Problem Statement
I am struggling to find a time slot for a public chargepoint
I’m trying to hit reload on a charging-App manually multiple times
But the public chargepoint is a busy one and offers only two loadoints, which are more or less constantly occupied
Because there’s only a limited time slot, when one loadpoint is available as it’s very cheap by far
Which makes me feel frustated and hit the reload button every other minute!
Solution
Find a public available (best case free) API, which offers the status of a specific loadpoint and/or loadpoints of a chargepoint. Then add items for those states, so I can build rules around it.
Step1: Get TomTom account
As of now (Nov '24), there’s a Freemium plan of the TomTom API, which allows for 2,500 free on-tile request daily. Which is all you need. After successful registration copy your API Key.
Step2: Find out, the TomTom ID of your specific chargepoint
After successfully registered, you’ll need to login to your account on developer.tomtom.com and use the “Nearby search” with coordinates near the chargepoint on this page:
You’ll get an JSON as response, which you can walk through (again v2 of that endpoint in Nov '24): object►results►0►id
(assuming your desired chargepoint is the first result in that JSON). That ID looks something like this: 12345678-123-1234-1234-12345678912 (alphanumerical). Copy that ID
Step2: Add http-thing for TomTom
With -again v2 Nov '24- you can add five new channels for each of the possible status: available, occupied, outOfService, reserved, unknown:
UID: http:url:HTTPYourChargePoint
label: HTTP Your Chargepoint
thingTypeUID: http:url
configuration:
authMode: BASIC
ignoreSSLErrors: false
baseURL: https://api.tomtom.com/search/2/chargingAvailability.json
delay: 0
stateMethod: GET
refresh: 60
commandMethod: GET
contentType: text/plain
timeout: 3000
bufferSize: 2048
channels:
- id: last-failure
channelTypeUID: http:request-date-time
label: Last Failure
configuration: {}
- id: last-success
channelTypeUID: http:request-date-time
label: Last Success
configuration: {}
- id: responseJSON
channelTypeUID: http:string
label: JSON four your chargepoint
description: JSON for status of your chargepoint
configuration:
stateExtension: ?chargingAvailability={INSERT_ID_OF_CHARGEPOINT}&key={INSERT_YOUR_API-KEY}
- id: availableLoadpoints
channelTypeUID: http:number
label: available loadpoints
description: amount of available loadpoints
configuration:
stateExtension: ?chargingAvailability={INSERT_ID_OF_CHARGEPOINT}&key={INSERT_YOUR_API-KEY}
stateTransformation: JSONPATH:$.connectors[0].availability.current.available
- id: occupiedLoadpoints
channelTypeUID: http:number
label: occupied loadpoints
description: amount of occupied loadpoints
configuration:
stateExtension: ?chargingAvailability={INSERT_ID_OF_CHARGEPOINT}&key={INSERT_YOUR_API-KEY}
stateTransformation: JSONPATH:$.connectors[0].availability.current.occupied
- id: offlineLoadpoints
channelTypeUID: http:number
label: offline loadpoints
description: amount of offline loadpoints
configuration:
stateExtension: ?chargingAvailability={INSERT_ID_OF_CHARGEPOINT}&key={INSERT_YOUR_API-KEY}
stateTransformation: JSONPATH:$.connectors[0].availability.current.outOfService
- id: reservedLoadpoints
channelTypeUID: http:number
label: reserved loadpoints
description: amount of reserved loadpoints
configuration:
stateExtension: ?chargingAvailability={INSERT_ID_OF_CHARGEPOINT}&key={INSERT_YOUR_API-KEY}
stateTransformation: JSONPATH:$.connectors[0].availability.current.reserved
- id: unknownLoadpoints
channelTypeUID: http:number
label: unknown loadpoints
description: amount of unknown loadpoints
configuration:
stateExtension: ?chargingAvailability={INSERT_ID_OF_CHARGEPOINT}&key={INSERT_YOUR_API-KEY}
stateTransformation: JSONPATH:$.connectors[0].availability.current.unknown
Step3: Add the items
Add the items and link them to the channels as you like. for me, best is to “Add Equipment from Thing”
Now you should have at least five items:
- LoadpointsAvailable
- LoadpointsOccupied
- LoadpointsOffline
- LoadpointsReserved
- LoadpointsUnknown
As I only need to “observe” in a certain amount of time, I addes a “LoadpointsObservation” item. It’s a simple switch-item in the same Group/Model as the above ones. Description later on. In the Metadata I used “Expire” to set the item to “OFF” after 12h (which should be enough as observation time)
value: 12h0m0s,OFF
config: {}
What happens now, is that http-binding calls the API in the configured intervall (60secs in Step2 refresh
)
Step4: a rule for it.
It’s a simple rule and fires, if the “Available”-item changes. It then will compare the previous state with the current one and add a log-entry and send a notification.
configuration: {}
triggers:
- id: "2"
configuration:
itemName: LoadpointsAvailable
type: core.ItemStateChangeTrigger
conditions:
- inputs: {}
id: "1"
configuration:
itemName: LoadpointsObservation
state: ON
operator: =
type: core.ItemStateCondition
actions:
- inputs: {}
id: "3"
configuration:
type: application/javascript
script: >
// checks, when a loadpoint of your chargepoint is available or is occupied again
var prevAvailable =
items.getItem("LoadpointsAvailable").persistence.previousState(true,
"jdbc").numericState;
var curAvailable = items.getItem("LoadpointsAvailable").numericState;
var text = curVerfuegbar + " loadpoints available on YOUR CHARGEPOINT! was "
+ prevVerfuegbar;
var icon = "";
var tag = "";
if (prevVerfuegbar == 0 && curVerfuegbar > 0) {
// at least one is available now
text += " Drive now!";
icon = "flowpipe";
tag = "info";
} else if (prevVerfuegbar > 0 && curVerfuegbar == 0) {
// previously available turned to occupied
text += " Stay or return home!"
icon = "error";
tag = "urgent";
}
if (icon != "") {
console.info("INFO Loadpoint: " + text);
actions.NotificationAction.sendNotification("YOUR@EMAIL.COM", text, icon, tag);
}
type: script.ScriptAction
Step5: whatever you want
of course that’s not the only thing you could do with that information. I’m thinking on adding some flavour to it with calculating the “occupied since” or “available since” timeframe. So you could also use that information (based on persistence and “lastChanged”-argument) to further drive my inner nerd. You could display that on a page or widget, you could add some logic to it like “average standing time is xx hours” and use it to “predict” free timeslots…