# psa_car_controller: charging thresholds and a trip dashboard for PSA cars

> psa_car_controller is a Python program that talks to the connected_car v4 API of the PSA group, so a Peugeot, Citroen, Opel, Vauxhall or DS car can be queried and controlled from a script or a web dashboard. The vendor documentation is incomplete and the project fills in the gaps, including Docker images and a Home Assistant addon.

**flobz/psa_car_controller** — Control psa car with connected_car v4 API.

- Repository: https://github.com/flobz/psa_car_controller
- Stars: 599 · Forks: 335
- Language: Python
- License: GPL-3.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/flobz-psa-car-controller

## What the connected_car v4 API lets you control

The program wraps the vehicle API that the PSA group publishes for connected cars, and the practical feature list is longer than the name suggests. You can read the status of the car, which covers battery level for an electric vehicle and its position, start and stop the charge, and set a charge threshold that limits the battery to a chosen percentage. There is also a stop hour, so the car only charges outside peak hours, plus control of the air conditioning, and control of the lights and the horn where the vehicle supports it, and locking or releasing the doors. The read side covers consumption statistics, trips on a map or in a table, the list of charging sessions, the battery charging curve, the altitude curve of a trip, the carbon dioxide emitted by charging, and what the charging cost. Live vehicle data can also be pushed to a route planner. The program was tested on a Peugeot e-208 and is described as working with the other PSA vehicles, which the project topics list as Citroen, Opel, Vauxhall and DS.

## The vendor API documentation has gaps

The project takes a practical stance on the official documentation. The developer portal for the group documents the API, but the project states plainly that it is not totally up to date and contains some errors, which is the reason this program exists in the form it does. Two things in the repository cover that gap: a specification file for the API at the top level, and an API document under the documentation directory that the project tells users to read before calling the endpoints.

That arrangement has a consequence for anyone building on top of it. The behaviours you depend on are described by the project, not by the vendor, so when something looks wrong the first place to check is the project's own documentation rather than the developer portal. It also means the surface can change under you when the vendor changes the service, which is a good reason to keep the version of this program pinned rather than pulling the latest image on every restart, especially given the release cadence here, with v3.7.10 published on 2026-10-15 after v3.7.9 in August and v3.7.8 at the end of that month.

## Recording turns the program into a dashboard

There are two ways to use the software, and the second one is the interesting one. The first is the API, documented in the project, which is how you script a charge threshold or read the battery level from another program. The second is the dashboard, and it is enabled by adding the record argument to the command line, which makes the program store the position of the vehicle and build a history you can look at later.

Once recording is on, the dashboard shows your trips, your consumption and some statistics, including a comparison of consumption against the exterior temperature, a charging curve and an altitude profile for a trip. Two of those need third party credentials. You need an API key from the OpenWeatherMap service in your configuration file for the consumption against exterior temperature view, and an API key from the CO2 signal service for the carbon dioxide per kilometre figure, which the project notes is not needed in France. A third integration sends live car status to a better route planner. The cost of the dashboard is therefore a few API keys and a record flag, and the return is a history of what the car actually did rather than what the app claims it did.

## Charge price lives in config.ini

The cost side of the dashboard is driven by a configuration file rather than by code. After a successful launch, a config.ini file is created, and the price you pay for electricity goes into it in the format 0.15. If your tariff is cheaper at night, the same file holds a night price along with a night hour start and a night hour end, and the hours are written in the format 23h12. The price can also be edited by hand in the dashboard, which the project suggests is useful if you charge at a public charge point with a different rate.

The distinction between this file and the two other configuration inputs is worth keeping straight. The account credentials and the vehicle settings go into the JSON files passed on the command line, the price goes into the generated config.ini, and the third party API keys go into the configuration file as well. The Docker image keeps this in a single mounted directory, which is why the Compose file mounts the config folder rather than individual files.

## The Docker image and what it exposes

The container route is the one most people will use, and the Compose file is short:
```yaml
version: "2"

services:
  psacc:
    image: flobz/psa_car_controller:latest
    restart: unless-stopped
    ports:
      - "5000:5000"
    volumes:
      - ./config:/config
```
The image restarts unless stopped, exposes port 5000 and keeps the configuration in a mounted directory so the settings survive a container replacement. The second stage of the image shows how the process is launched, with the environment variables that select the behaviour:
```dockerfile
FROM debian:bookworm-slim
ARG PYTHON_DEP
WORKDIR /config
ENV PSACC_BASE_PATH=/ PSACC_PORT=5000 PSACC_OPTIONS="-c -r --web-conf" PSACC_CONFIG_DIR="/config" PYTHONPATH="/app"
```
The default options in that line are the charge configuration, the record flag and the web configuration, so a container starts with recording already on. The image also installs Playwright with the headless Chromium shell for the authentication step, and the Dockerfile handles the case where that is not available on the architecture by falling back to manual authentication, with a comment in the build file saying exactly that. The repository also ships a systemd unit file, for people running the program directly on a Raspberry Pi or a small server.

## The dependency list tells you what the program really is

The Python manifest is honest about the shape of the project. The runtime needs Python 3.11 or later, and the dependencies split into three groups. The dashboard is Dash with Plotly, a data acquisition layer, Bootstrap components and Werkzeug under Flask, which is a web application with charts rather than a command line tool. The vehicle side uses an OAuth client, requests, pytz, ConfigUpdater and cryptography, with a pinned pycryptodomex release that the manifest explains is pinned because that project introduces breaking changes in minor versions. And the Android and browser parts show up as androguard, which inspects Android packages, and Playwright, which drives a headless browser, together with geojson and reverse-geocode for the map features. MQTT is also a dependency, which is what makes the Domoticz and Home Assistant integrations possible, and the whole set is managed with Poetry.

## Where the project fits into a home automation stack

The integrations are the reason to pick this program over the manufacturer's own app. There is a Home Assistant addon published as its own repository, so the car can be exposed as entities in a dashboard rather than through a one-off script. There is documentation for Domoticz, an external Home Assistant integration written by a third party, a Grafana issue thread for people who want the data in their existing dashboards, and a note that a Jeedom procedure is missing and anyone is welcome to contribute one. The connection to a better route planner is documented as well, and the project credits the authentication work to another developer whose library it builds on.

The limits are just as clear. The scope is one vehicle group, the API behind it is documented by the project as imperfect, and the official documentation of the program is spread across a directory of documents, a FAQ file, a separate addon repository and a developer document. The last push was on 2026-10-15, the same day as the v3.7.10 release, so the work is active, and the licence is GPL-3.0, which matters if you plan to modify and redistribute it.

## Conclusion

psa_car_controller suits an owner of a PSA group car who wants off-peak charging thresholds, preconditioning and trip history without opening the manufacturer's app, and it is especially useful for home automation setups because the Home Assistant addon, the Domoticz notes and the ABRP integration all exist. It is the wrong tool if your car is not from the PSA group, and it is the wrong tool if you need a supported commercial interface, since the underlying API documentation is described as not totally up to date and containing errors. Before you rely on it, read the API notes in docs/psacc_api.md and the api_spec.md file, confirm the Docker image suits your architecture, because the headless authentication step falls back to manual handling where Playwright is unavailable, and set the electricity price in config.ini before the dashboard can show you what charging costs.

## FAQ

### How do I install psa_car_controller?

The project points at four routes: instructions for Linux or Windows, a Docker guide, installation as a Home Assistant addon published in its own repository, and an external tutorial for running it on a Raspberry Pi with docker-compose. The Compose file uses the image flobz/psa_car_controller:latest with port 5000 exposed and a config directory mounted at /config.

### Which PSA cars does psa_car_controller support?

The program was tested with a Peugeot e-208 and is described as working with other PSA vehicles including Citroen, Opel, Vauxhall and DS. The project topics also list the 2008, 208, Corsa-e and DS models.

### What can I control and read from my car with this program?

You can read the car status including battery level and position, start and stop the charge, set a charge threshold and a stop hour for off-peak charging, control the air conditioning, the lights and the horn where supported, and lock the doors and release them again. It also reports consumption, trips, charging curves, altitude and carbon dioxide.

### How do I get the trip dashboard and consumption statistics?

Add the record argument so the program stores the vehicle position, and the dashboard can then show trips, consumption and statistics. You also need an OpenWeatherMap API key in the config file for the consumption against exterior temperature view, and a CO2 signal API key for carbon dioxide per kilometre, which the project says is not needed in France.

### How does the program work out what charging costs?

After a successful launch a config.ini file is created, and you set the electricity price there in the format 0.15, with optional night price and night hour start and end in the format 23h12. The price can also be changed by hand in the dashboard, which helps when you use a public charge point.

## Sources

- [flobz/psa_car_controller on GitHub](https://github.com/flobz/psa_car_controller)
- [Issues](https://github.com/flobz/psa_car_controller/issues)
- [License: GPL-3.0](https://github.com/flobz/psa_car_controller/blob/master/LICENSE)
- [README](https://github.com/flobz/psa_car_controller/blob/master/README.md)
- [Releases](https://github.com/flobz/psa_car_controller/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/flobz-psa-car-controller
