Home Assistant × Joulo

Charging sessions, ERE and status in Home Assistant

Joulo provides a REST API with the same data as your dashboard. A single YAML block in your configuration.yaml gives you sensors for charging status, kWh per session, total ERE credits and the active TAG ID.

REST
Bearer token
JSON
No add-on needed

what you get

Four data streams, one token

The Joulo REST API exposes a handful of endpoints. On top of those you can build as many Home Assistant sensors as you need • status, energy, sessions, EVCC linking and a restart button.

Realtime status

GET /chargers • status of each charger, whether it is actively charging and the kWh accumulated in the current session.

Sessions

GET /sessions • list of recent charging sessions with kWh, start and end time, and the ERE credits per session.

Energy & ERE

GET /energy • total charged kWh and accrued ERE credits. Ideal for single-number indicators on your dashboard.

EVCC TAG ID

current_session.id_tag • the RFID/TAG ID behind the active session. Paste it into EVCC so it knows which vehicle is charging.

setup

Up and running in four steps

The integration uses Home Assistant's built-in rest: integration. No custom component, no HACS • just YAML.

01 • Generate API token

Log in to your Joulo dashboard and open the API tab. Activate the API and copy the token. The token only works on your own Joulo data • Joulo has no access to your Home Assistant.

02 • secrets.yaml

Put the full header value • Bearer plus your token • into secrets.yaml under the key joulo_api_auth. Configuration.yaml then references it as !secret joulo_api_auth, unquoted: YAML does not expand a !secret inside a string.

03 • configuration.yaml

Add the rest: block below. The three endpoints (chargers, energy, sessions) together expose every sensor you need.

04 • Restart Home Assistant

Do a full restart (not just YAML reload). After a minute the Joulo entities show up in Developer Tools → States.

configuration

Copy-paste YAML

Paste this into your configuration.yaml. Change [0] to an index or slug if you run multiple chargers.

secrets.yaml
# secrets.yaml
# Plak je token precies zoals het dashboard het toont. Het begint niet met joulo_.
joulo_api_auth: "Bearer JOUW_API_TOKEN"
configuration.yaml
# configuration.yaml • Joulo sensors
# Elke sensor heeft een unique_id. Dan maakt Home Assistant na een YAML-reload
# geen nieuwe entiteit aan, en kun je de sensor in de interface hernoemen.
rest:
  - resource: https://api.joulo.nl/functions/v1/api/chargers
    scan_interval: 300
    headers:
      Authorization: !secret joulo_api_auth
    sensor:
      - name: "Joulo Charger Status"
        unique_id: joulo_charger_status
        value_template: >-
          {{ value_json.chargers[0].status | default('unknown') }}
      - name: "Joulo Session kWh"
        unique_id: joulo_session_kwh
        value_template: >-
          {% set s = value_json.chargers[0].current_session | default(none) %}
          {{ (s.kwh_so_far if s else 0) | float(0) }}
        unit_of_measurement: "kWh"
        device_class: energy
        state_class: total_increasing
      # Geschatte netto-opbrengst van de lopende sessie in euro. 0 als je niet laadt.
      - name: "Joulo Opbrengst Huidige Sessie"
        unique_id: joulo_opbrengst_huidige_sessie
        value_template: >-
          {% set s = value_json.chargers[0].current_session | default(none) %}
          {{ (s.estimated_euro if s and s.estimated_euro is not none else 0) | float(0) }}
        unit_of_measurement: "EUR"
        device_class: monetary
      # RFID/TAG-ID van de actieve sessie • handig voor EVCC om
      # de auto achter de sessie te identificeren.
      - name: "Joulo Active TAG ID"
        unique_id: joulo_active_tag_id
        value_template: >-
          {% set s = value_json.chargers[0].current_session | default(none) %}
          {{ s.id_tag if s and s.id_tag else '' }}
    binary_sensor:
      - name: "Joulo Is Charging"
        unique_id: joulo_is_charging
        value_template: "{{ value_json.chargers[0].is_charging | default(false) }}"
        device_class: power

  - resource: https://api.joulo.nl/functions/v1/api/energy
    scan_interval: 3600
    headers:
      Authorization: !secret joulo_api_auth
    sensor:
      - name: "Joulo Total kWh"
        unique_id: joulo_total_kwh
        value_template: "{{ value_json.total_kwh | float(0) }}"
        unit_of_measurement: "kWh"
        device_class: energy
        state_class: total_increasing
      - name: "Joulo Total ERE"
        unique_id: joulo_total_ere
        value_template: "{{ value_json.total_ere_credits | float(0) }}"
        state_class: total_increasing

  - resource: https://api.joulo.nl/functions/v1/api/sessions?limit=10
    scan_interval: 600
    headers:
      Authorization: !secret joulo_api_auth
    sensor:
      - name: "Joulo Last Session kWh"
        unique_id: joulo_last_session_kwh
        value_template: "{{ value_json.sessions[0].kwh | float(0) }}"
        unit_of_measurement: "kWh"
        device_class: energy
      - name: "Joulo Last Session ERE"
        unique_id: joulo_last_session_ere
        value_template: "{{ value_json.sessions[0].ere_credits | float(0) }}"

  - resource: https://api.joulo.nl/functions/v1/api/ere-position
    scan_interval: 3600
    headers:
      Authorization: !secret joulo_api_auth
    sensor:
      # Verkocht en nog niet op je rekening: klaar voor uitbetaling plus gereserveerd.
      - name: "Joulo Nog Uit Te Betalen"
        unique_id: joulo_nog_uit_te_betalen
        value_template: >-
          {{ ((value_json.payable.net_eur | float(0))
            + (value_json.reserved.net_eur | float(0))) | round(2) }}
        unit_of_measurement: "EUR"
        device_class: monetary

dashboard

Lovelace card in five lines

A basic entities card shows the key Joulo sensors. Swap for a gauge, history-graph or mini-graph card for a richer view.

ui-lovelace.yaml
# Lovelace dashboard kaart
type: entities
title: Joulo laadstation
entities:
  - entity: sensor.joulo_charger_status
    name: Status
  - entity: binary_sensor.joulo_is_charging
    name: Laadt nu
  - entity: sensor.joulo_session_kwh
    name: Huidige sessie
  - entity: sensor.joulo_opbrengst_huidige_sessie
    name: Opbrengst huidige sessie
  - entity: sensor.joulo_nog_uit_te_betalen
    name: Nog uit te betalen
  - entity: sensor.joulo_total_kwh
    name: Totaal geladen
  - entity: sensor.joulo_total_ere
    name: ERE-credits

automations

Two automation recipes

What you do with the data is up to you. Two common patterns you can use directly:

Push notification when session ends

# automations.yaml • notify wanneer sessie eindigt
- id: joulo_session_done
  alias: "Joulo • sessie afgerond"
  trigger:
    - platform: state
      entity_id: binary_sensor.joulo_is_charging
      from: "on"
      to: "off"
  action:
    - service: notify.mobile_app_jouw_telefoon
      data:
        title: "Laadsessie klaar"
        message: >-
          {{ states('sensor.joulo_session_kwh') }} kWh geladen.
          Totaal vandaag: {{ states('sensor.joulo_total_kwh') }} kWh.

EVCC vehicle ID via TAG ID

# evcc.yaml • gebruik de Joulo TAG-ID voor auto-identificatie
vehicles:
  - name: tesla
    type: template
    template: tesla
    identifiers:
      # Plak hier de waarde van sensor.joulo_active_tag_id na een
      # eerste laadsessie. EVCC herkent dan welke auto er laadt.
      - "DEADBEEF12345678"

control

Restart your charger from Home Assistant

Charger stuck? POST /chargers/reboot sends an OCPP Reset through the Joulo backend • for chargers connected via OCPP or the Joulo Proxy. An active session is stopped, the command is only delivered while the charger is online, and each charger has a cooldown of roughly 5 minutes.

Define the rest_command

configuration.yaml
# configuration.yaml • herstart je laadstation op afstand
# charger_id = het "id" uit GET /chargers. type "Soft" rondt een actieve
# sessie netjes af; "Hard" herstart direct.
rest_command:
  joulo_reboot_charger:
    url: https://api.joulo.nl/functions/v1/api/chargers/reboot
    method: POST
    headers:
      Authorization: !secret joulo_api_auth
    content_type: "application/json"
    payload: '{"charger_id": "CHARGER_ID", "type": "Soft"}'

Dashboard button

# Lovelace • knop die de herstart aanroept
type: button
name: Herstart laadstation
icon: mdi:restart
tap_action:
  action: call-service
  service: rest_command.joulo_reboot_charger
  confirmation:
    text: Laadstation herstarten? Een actieve sessie stopt.

troubleshooting

If entities stay empty

401 Unauthorized

Token not copied correctly, or quotes wrap the token in secrets.yaml. Remove them, restart Home Assistant and check the log.

unavailable / unknown

value_template can't find the value • usually because no session is active yet. Use | default(0) or | default('') as in the example.

Multiple chargers

The response is an array. Replace chargers[0] with chargers[1], or filter by slug with chargers | selectattr('slug', 'eq', 'my-charger') | first.

Rate limiting

Keep scan_interval at 300 s or higher for /chargers and 600 s or higher for /sessions and /energy. Polling faster doesn't give you more data • Joulo syncs from the upstream provider every 15 min.

Ready to get started?

Create a free account and connect your charger. Find your API token directly in the dashboard.