[TUTORIAL] How to get notified about which charging station are free while driving

Since I own an electric car with a relatively small battery, I need to charge it regularly. Unfortunately, I can’t do this at home, so I’m dependent on the availability of public charging stations in the area. This is generally fine, but one thing that bothers me is that you only find out whether a charging station is occupied when you actually get there. If it is occupied, you either have to hope the next station is available, or pull out your phone to check which charging stations are free. Both options feel like a missed opportunity. Ideally, you’d want to be informed in advance. This is what I tried to solve with the tutorial described here.

With the help of ChatGPT, I created a HomeyScript that informs me about which charging stations are available. This notification is then sent to my phone, allowing me to play it out loud through Android Auto while I’m driving. This way, I know exactly which charging stations are free and where to drive to charge my car.

What do we need?

Step 1: Setting up the charging stations

With the TomTom app installed, we can add the charging stations that interest us because they are nearby or, for example, because they are cheaper. If you’re unsure how to set up the TomTom app, MartijnPoppen has an excellent guide on how to request the API key and add new charging stations.

Keep in mind that, at the time of writing, TomTom allows 2500 free API requests per day. So, we adjust the update interval based on the number of charging stations we’ve added. This can be found in the settings of the added charging station. The ten charging stations I have added are set to either 300 seconds or 600 seconds to stay within the limit of 2.500 requests per day.

Step 2: Weather conditions (optional)

I don’t mind walking a bit further to charge my care somewhat cheaper. But if it’s pouring rain, I’ll pass on that option. The notification takes weather conditions into account when it’s sent. If it’s raining, the cheaper but farther charging station is not included in the list of available stations. I use OpenWeather for this, where I’ve set my home address as the location when I added the 1. weather, current (location) as a new device within Homey. For more information on how to set this up, RonnyW has written an excellent guide as well. If you don’t mind braving the elements, you can skip this step :wink: .

Step 3: The HomeyScript

Now comes the fun part. With the charging stations and weather conditions set, we can query which stations are available. We only want to see charging stations where at least one charging point is available. It’s also not useful to hear about ten different stations being available, so we set a limit of three available stations in the notification. As mentioned in step 2, weather conditions are also taken into account.

// Common variables
let devices = await Homey.devices.getDevices();
let availableChargingPoints = [];
const capabilitiesToCheck = [ 
//  'measure_amount_available.5.Outlet', 
  'measure_amount_available.17.Outlet', 
  'measure_amount_available.11.Outlet'
];  
let firstLineChargingPoints = "De volgende laadpunten zijn beschikbaar: \n";
let devicesMap = new Map();

// Define all laadpalen with their desired order
const laadpalenOrder = {
  "A": 1,
  "B": 2,
  "C": 3,
  "D": 4,
  "E": 5,
  "F": 6,
  "G": 7,
  "H": 100,
  "I": 101,
  "J": 102,
  // Add more laadpalen as needed
};

// Get the weather device by ID
const weatherDevice = devices['c2c1ca48-1098-418e-a557-77134aec18d9'];
let rainAboveThreshold = false;

// Check if the weather device exists and has the measure_rain capability
if (weatherDevice && weatherDevice.capabilitiesObj.measure_rain) {
  const measureRain = weatherDevice.capabilitiesObj.measure_rain.value;
  if (measureRain > 2) {
    rainAboveThreshold = true; // If the rain measure is above the threshold, set the flag
  }
}

for (const device of Object.values(devices)) {
  // Ensure capabilitiesObj exists for the device and the device has the specific driver ID
  if (!device.capabilitiesObj || device.driverId !== 'homey:app:com.tomtom:charging_availability') continue;

  for (const capabilityToCheck of capabilitiesToCheck) {
    const capability = device.capabilitiesObj[capabilityToCheck];
    if (capability && capability.value > 0) {
      
      // Remove "laadpaal" from device name and trim
      const deviceNameWithoutPrefix = device.name.replace("Laadpaal", "").trim();

      // Aggregate capability values for each device
      if (devicesMap.has(deviceNameWithoutPrefix)) {
        devicesMap.set(deviceNameWithoutPrefix, devicesMap.get(deviceNameWithoutPrefix) + capability.value);
      } else {
        devicesMap.set(deviceNameWithoutPrefix, capability.value);
      }
    }
  }
}

// Process devicesMap to create entries, including order information
for (const [deviceName, totalValue] of devicesMap.entries()) {
  // If rain is above threshold, skip adding Laadpaal A to the available charging points
  if (rainAboveThreshold && deviceName === "A") {
    continue;
  }

  // Get the order from the predefined list, or default to a high number for unordered laadpalen
  const order = laadpalenOrder[deviceName] || 999;
  const entry = { order, text: `- ${deviceName}: ${totalValue};` };
  availableChargingPoints.push(entry);
}

// Sort entries by their order
availableChargingPoints.sort((a, b) => a.order - b.order);

// Extract the sorted text entries for the output and take only the first three
const sortedEntries = availableChargingPoints.slice(0, 3).map(entry => entry.text);

function generateOutputMessage(sortedEntries) {
  return sortedEntries.length > 0
    ? firstLineChargingPoints + sortedEntries.join("\n")
    : "Er zijn geen laadpunten beschikbaar.";
}

const outputMessage = generateOutputMessage(sortedEntries);
await tag("Available Charging Points", outputMessage);
console.log(outputMessage);

Explanation of the HomeScript

In the capabilitiesToCheck variable, I’ve included the different outlet types to check for. By entering the names of the charging stations in the Devices section under Developer Tools, we can see how the capabilities are named. We look up the names of the charging stations and check under capabilities for the ID, which usually starts with measure_amount_available.[number].Outlet.

const capabilitiesToCheck = [
'measure_amount_available.17.Outlet',
'measure_amount_available.11.Outlet'
];

laadpalenOrder determines the order in which the notification lists the charging stations. The charging station with number 1 will be displayed first if it is free.

// Define all laadpalen with their desired order
const laadpalenOrder = {
  "A": 1,
  "B": 2,
  "C": 3,
  "D": 4,
  "E": 5,
  "F": 6,
  "G": 7,
  "H": 100,
  "I": 101,
  "J": 102,
  // Add more laadpalen as needed
};

The variable weatherDevice is the ID of the added OpenWeather location. This can also be found under Devices in Developer Tools.

const weatherDevice = devices['ID'];

Down here, we remove the word “Laadpaal” (charging station) from the deviceNameWithoutPrefix variable. In Homey, I’ve named all charging stations with the same naming convention: Laadpaal [street name]. That works fine in Homey but isn’t very helpful when we want a quick overview of available charging stations. So, I strip out the word “Laadpaal.”

// Remove "laadpaal" from device name and trim
const deviceNameWithoutPrefix = device.name.replace("Laadpaal", "").trim();

The last part worth explaining. This ensures that Laadpaal A is not shown if it’s raining.

// Process devicesMap to create entries, including order information
for (const [deviceName, totalValue] of devicesMap.entries()) {
// If rain is above threshold, skip adding Laadpaal A to the available charging points
if (rainAboveThreshold && deviceName === "A") {
continue;
}

Step 4: Setting up AA Notification Forwarder

Now that the script is ready, we want to make sure it’s visible in the car. Unfortunately, the Homey app doesn’t natively support Android Auto. So, to make this work, we need to use an app that makes notifications from other apps visible in Android Auto. For this, we can use AA Notification Forwarder, which is not available in the Play Store. This is because the app doesn’t comply with Google’s policies regarding Android Auto. Google prefers not to forward notifications from non-chat services. Fortunately, it’s not very difficult to sideload apps on Android. After downloading and installing the app, it’s important to follow the steps as outlined on the Github page. If not, we won’t receive the notifications.

Once the settings are configured, we start the app. Under Apps to Forward, we search for Homey and enable it. We also enable the checkbox for Ignore Group Summary notifications.

Step 5: Setting up Tasker and AutoLocation

Now it’s time to let Homey know that we’re within a certain range of home, so it can send the notification to the phone. We use Tasker, and optionally AutoLocation, for this. Both apps require a one-time purchase. It is possible to do this with Tasker alone, but experience shows that AutoLocation is more accurate in location tracking.

Connected to the car

First, we create a task in Tasker that uses a variable to check if the phone is connected to the car via Bluetooth. We don’t want to receive the free charging stations notification if we’re not in the car. In Tasker, we go to the VARS tab and create the variable %ConnectCar. The initial uppercase letter is important here; otherwise, it becomes a local variable that we can’t use elsewhere. We set the variable value to 0. Next, we go to the TASKS tab. There, we create a new task by clicking the plus button in the bottom right. Click Create and name the task, like Car start. In the task, click the plus button again and search for Variable Set. In Name, click the label icon in the top right. Find variable %ConnectCar and set the To value to 1.

Next, go back with the arrow in the top left, and you’ll see the task is created. Click the back arrow again to create a second task. I named this Car Stop, and it is identical to Car Start, except that the value of %ConnectCar is set to 0. Afterward, we go to the PROFILES tab and create a profile using the plus button in the bottom right. Choose Create and click State. Then search for BT Connected. Under Name, use the magnifying glass to find the previously saved Bluetooth connections. Select the one for the car (you must have connected to the car at least once for this to work). Use the back arrow to select the task to activate when connected to the car’s Bluetooth. Choose Car Start. Long press Car Start until the option to Add Exit Task appears. Select Car Stop, and the variable will now change depending on whether we are connected to the car’s Bluetooth.

Setting up AutoLocation

If we want to use the AutoLocation app, we need to set up the Geofence before proceeding. Open the app and click Start Monitor under Geofences. Then, go to Manage Geofences and click the plus sign at the top. On the map screen, click the up arrow in the bottom right corner. Here, you can set the radius of the geofence. In my case, it’s 10.000 meters, but this can be any distance. Then, find your home location on the map and click it. A circle will appear around the location based on the set distance. Then click Accept Geofence and give the Geofence a name.

Informing Homey

Now that Tasker knows if we’re in the car and AutoLocation is set up, it’s time to inform Homey that we are nearby. To do this, we create another task. The task begins with an If statement that checks if the phone is connected to the car via Bluetooth. If %ConnectCar equals 1, the flow should proceed. Click the plus button and search for if in the action category. Then, using the label icon, find %ConnectCar and select it. Change the ~ to equals, and the value should be 1. Go back to select If, End If.

Between the If and End If, place a new action called HTTP request. The method is GET, and the URL is https://webhook.homey.app/[HomeyID]/ChargingPoints?tag=[name], where HomeyID is the ID of Homey (found under Settings, General), and name is a custom name.

With the task ready, create a profile. Click the plus button in the profile tab, then Create. If using AutoLocation, click State and search for AutoLocation Geofences. Select the name of the Geofence you created earlier. Set the Status to Inside. Then, click back several times until you can select the task. Find the name of the task you created to notify Homey.

If you’re not using AutoLocation, select Location instead of State when creating the profile. Create a new location by long-pressing your home location on the map. Adjust the radius to, for example, 10 kilometers. Click Back and give the location a name. Then, select the task you created to notify Homey.

Step 6: Flow in Homey

With everything set up, it’s just a matter of creating the Flow in Homey. I used the following flow:

In the flow, the name of the webhook event matches the one from the HTTP request. HomeScript is, of course, the script from this tutorial, and tag is the custom name that we created with the GET request.

Hopefully, this explanation helps others easily find an available charging station or provides inspiration for triggering flows when you are near home.

6 Likes