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
joulo_api_auth: "Bearer joulo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
configuration.yaml
# configuration.yaml • Joulo sensors
rest:
  - resource: https://krbhttscqdzrujxoitjh.supabase.co/functions/v1/api/chargers
    scan_interval: 300
    headers:
      Authorization: !secret joulo_api_auth
    sensor:
      - name: "Joulo Charger Status"
        value_template: >-
          {{ value_json.chargers[0].status | default('unknown') }}
      - name: "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
      # RFID/TAG-ID van de actieve sessie • handig voor EVCC om
      # de auto achter de sessie te identificeren.
      - name: "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"
        value_template: "{{ value_json.chargers[0].is_charging | default(false) }}"
        device_class: power

  - resource: https://krbhttscqdzrujxoitjh.supabase.co/functions/v1/api/energy
    scan_interval: 3600
    headers:
      Authorization: !secret joulo_api_auth
    sensor:
      - name: "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"
        value_template: "{{ value_json.total_ere_credits | float(0) }}"
        state_class: total_increasing

  - resource: https://krbhttscqdzrujxoitjh.supabase.co/functions/v1/api/sessions?limit=10
    scan_interval: 600
    headers:
      Authorization: !secret joulo_api_auth
    sensor:
      - name: "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"
        value_template: "{{ value_json.sessions[0].ere_credits | float(0) }}"

// 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_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://krbhttscqdzrujxoitjh.supabase.co/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.