# Understanding the TeslaMate Vehicle State Machine: The 5 Core States Explained

> Explore the 5 core states of the TeslaMate vehicle state machine: Charge, Climate, Drive, VehicleConfig, and VehicleState. Learn how Tesla API data transforms into usable Elixir structs.

- Repository: [TeslaMate/teslamate](https://github.com/teslamate-org/teslamate)
- Tags: internals
- Published: 2026-06-18

---

**The TeslaMate vehicle state machine consists of five distinct sub-states—Charge, Climate, Drive, VehicleConfig, and VehicleState—that transform raw Tesla API JSON into typed Elixir structs through pure-functional mapping functions.**

The `teslamate-org/teslamate` repository implements a sophisticated vehicle state machine to model real-time Tesla telemetry. At its core, the `TeslaApi.Vehicle.State` module orchestrates five specialized sub-states, each responsible for parsing specific categories of vehicle data from the Tesla API into strongly-typed Elixir structures. This pure-functional approach enables reliable unit testing and seamless integration with the application’s database, MQTT publisher, and LiveView dashboards.

## What Is the TeslaMate Vehicle State Machine?

The TeslaMate vehicle state machine is a pure-functional state transformer implemented primarily in [`lib/tesla_api/vehicle/state.ex`](https://github.com/teslamate-org/teslamate/blob/main/lib/tesla_api/vehicle/state.ex). Unlike traditional GenServer-based state machines, this implementation uses lightweight "mapper" functions (`result/1`) to convert raw JSON payloads into Elixir structs without side effects. The module aggregates disparate telemetry streams—battery metrics, cabin climate, navigation data, and vehicle configuration—into a unified, type-safe representation that powers the dashboard, database layer, and MQTT integrations.

## The Five Sub-States of the TeslaMate State Machine

The state machine decomposes vehicle telemetry into five coherent domains. Each sub-state is defined by its own struct and mapping logic in [`lib/tesla_api/vehicle/state.ex`](https://github.com/teslamate-org/teslamate/blob/main/lib/tesla_api/vehicle/state.ex).

### Charge State

The **Charge** state captures battery-related telemetry including state of charge, charger power, charging limits, and time-to-full calculations. The `TeslaApi.Vehicle.State.Charge` struct exposes these fields through the `Charge.result/1` mapper function, which ingests the raw `charge_state` JSON node from the Tesla API response.

### Climate State

The **Climate** state manages cabin temperature controls, fan status, seat heater levels, defrost settings, and pre-conditioning schedules. The `TeslaApi.Vehicle.State.Climate` struct normalizes this environmental data via `Climate.result/1`, processing the `climate_state` API payload.

### Drive State

The **Drive** state handles real-time navigation and motion data including GPS coordinates, vehicle speed, compass heading, and shift state (Park, Reverse, Neutral, Drive). The `TeslaApi.Vehicle.State.Drive` struct and `Drive.result/1` function transform the `drive_state` JSON into usable Elixir types for tracking trips and location.

### VehicleConfig State

The **VehicleConfig** state stores static configuration data that rarely changes, including vehicle model, trim options, hardware variants, and factory-installed features. The `TeslaApi.Vehicle.State.VehicleConfig` struct persists these immutable attributes through `VehicleConfig.result/1`.

### VehicleState

The **VehicleState** represents high-level vehicle status including door locks, window positions, trunk and frunk status, software update progress, TPMS tire pressure readings, and Sentry Mode activation. This state includes a nested `SoftwareUpdate` struct specifically for tracking OTA update progress, mapped via `VehicleState.result/1`.

## How the State Machine Transforms API Data

The state machine operates as a pure transformation pipeline. When `TeslaApi.Vehicle.get/2` retrieves fresh telemetry from Tesla’s cloud endpoint, each sub-state’s `result/1` function extracts and types its relevant subset of the JSON payload.

```elixir

# 1️⃣ Pull the raw vehicle data from the Tesla API

{:ok, raw_vehicle} = TeslaApi.Vehicle.get(vin, token)

# 2️⃣ Convert the nested maps into typed structs

charge_state   = TeslaApi.Vehicle.State.Charge.result(raw_vehicle["charge_state"])
climate_state = TeslaApi.Vehicle.State.Climate.result(raw_vehicle["climate_state"])
drive_state   = TeslaApi.Vehicle.State.Drive.result(raw_vehicle["drive_state"])
config_state  = TeslaApi.Vehicle.State.VehicleConfig.result(raw_vehicle["vehicle_config"])
state_state   = TeslaApi.Vehicle.State.VehicleState.result(raw_vehicle["vehicle_state"])

# 3️⃣ Assemble the full vehicle snapshot (simplified)

vehicle_snapshot = %{
  charge:   charge_state,
  climate:  climate_state,
  drive:    drive_state,
  config:   config_state,
  state:    state_state
}

# 4️⃣ Store / broadcast the snapshot

TeslaMate.Vehicles.update(vin, vehicle_snapshot)

```

You can then access specific metrics directly from the typed structs:

```elixir

# 👀 Example: Inspect the charger power from the state machine

%TeslaApi.Vehicle.State.Charge{charger_power: power} = charge_state
IO.puts("Current charger power: #{power} kW")

```

## Integration with TeslaMate Consumers

Once transformed, the unified state feeds multiple consumers across the application according to the `teslamate-org/teslamate` source code. The `TeslaMate.Vehicles.Vehicle` module (in [`lib/teslamate/vehicles/vehicle.ex`](https://github.com/teslamate-org/teslamate/blob/main/lib/teslamate/vehicles/vehicle.ex)) aggregates these structs for database persistence. Simultaneously, `TeslaMate.Mqtt.Pubsub.VehicleSubscriber` (in [`lib/teslamate/mqtt/pubsub/vehicle_subscriber.ex`](https://github.com/teslamate-org/teslamate/blob/main/lib/teslamate/mqtt/pubsub/vehicle_subscriber.ex)) broadcasts state updates over MQTT for external integrations. The LiveView components in [`lib/teslamate_web/live/car_live/summary.ex`](https://github.com/teslamate-org/teslamate/blob/main/lib/teslamate_web/live/car_live/summary.ex) render real-time dashboards from this normalized state without directly parsing raw API responses.

## Summary

- The TeslaMate vehicle state machine comprises five sub-states: **Charge**, **Climate**, **Drive**, **VehicleConfig**, and **VehicleState**.
- Each sub-state uses a dedicated struct and `result/1` mapper function in [`lib/tesla_api/vehicle/state.ex`](https://github.com/teslamate-org/teslamate/blob/main/lib/tesla_api/vehicle/state.ex) to parse raw Tesla API JSON.
- The implementation is pure-functional, not a GenServer, enabling side-effect-free transformation and easy unit testing.
- Mapped structs flow to the database layer (`TeslaMate.Vehicles.Vehicle`), MQTT broker (`VehicleSubscriber`), and web interface ([`car_live/summary.ex`](https://github.com/teslamate-org/teslamate/blob/main/car_live/summary.ex)).

## Frequently Asked Questions

### What are the five states in the TeslaMate vehicle state machine?

The TeslaMate vehicle state machine defines five sub-states: **Charge** (battery metrics), **Climate** (cabin controls), **Drive** (navigation and motion), **VehicleConfig** (static configuration), and **VehicleState** (doors, locks, and software updates). Each corresponds to a specific struct in `TeslaApi.Vehicle.State` that maps raw Tesla API JSON into typed Elixir data.

### How does TeslaMate convert Tesla API JSON into Elixir structs?

TeslaMate uses pure-functional mapper functions named `result/1` defined in each sub-state module. For example, `TeslaApi.Vehicle.State.Charge.result/1` takes the raw `charge_state` JSON map and returns a populated `%TeslaApi.Vehicle.State.Charge{}` struct with typed fields for charger power, battery level, and charging limits.

### Is the TeslaMate vehicle state machine implemented as a GenServer?

No. Unlike traditional Elixir state machines that run as GenServer processes, the TeslaMate vehicle state machine is a pure-functional transformer. The `TeslaApi.Vehicle.State` module acts as a library of functions that transform data without maintaining process state or side effects, making it lightweight and easy to test.

### Which TeslaMate modules consume the output of the vehicle state machine?

The mapped structs flow to three primary consumers: `TeslaMate.Vehicles.Vehicle` for database persistence, `TeslaMate.Mqtt.Pubsub.VehicleSubscriber` for MQTT broadcasting, and `TeslaMateWeb.Live.CarLive.Summary` for the real-time web dashboard. These consumers receive normalized data without needing to parse raw Tesla API responses.