TeslaMate MQTT Integration: Architecture, Configuration, and Topic Structure
TeslaMate integrates with MQTT using the Tortoise311 Elixir client library to publish real-time vehicle telemetry through a supervision tree that maps internal vehicle state to hierarchical topics under teslamate/<namespace>/cars/<car_id>/<key>.
The teslamate-org/teslamate repository implements a robust MQTT integration that enables real-time streaming of Tesla vehicle data to IoT platforms and home automation systems. This integration leverages Erlang/OTP supervision patterns to ensure reliable message delivery while maintaining a lightweight footprint by delegating protocol handling to the Tortoise311 library.
How TeslaMate MQTT Integration Works
Configuration and Initialization
The MQTT broker connection is configured in config/runtime.exs using environment variables or explicit config values. When a non-nil :mqtt configuration is present, the application automatically launches the MQTT supervision tree.
Key configuration parameters include:
- Host and Port: Broker connection endpoints
- Credentials: Username/password authentication
- Client ID: Identifier for the MQTT connection
- QoS: Quality of Service level (defaults to 1)
- Namespace: Topic prefix (defaults to
"teslamate")
Application Startup Sequence
In lib/teslamate/application.ex, the supervision tree conditionally includes the MQTT component only when configuration exists:
if(mqtt_config != nil, do: {TeslaMate.Mqtt, mqtt_config}),
This pattern ensures that TeslaMate.Mqtt starts as a supervised child only when explicitly configured, preventing connection errors in MQTT-less deployments.
Supervision Tree Architecture
The TeslaMate.Mqtt module (defined in lib/teslamate/mqtt.ex) orchestrates two supervised children:
TeslaMate.Mqtt.Publisher: AGenServerthat wrapsTortoise311.publish/4and handles outgoing messages with configurable QoS and retentionTeslaMate.Mqtt.PubSub: ASupervisorthat spawns aVehicleSubscriberprocess for each registered vehicle retrieved viaVehicles.list/0
This hierarchy ensures that if the publisher or any vehicle subscriber crashes, only that specific process restarts without affecting the entire MQTT integration.
Publishing Vehicle Telemetry
VehicleSubscriber Process
Each vehicle in the fleet gets its own subscriber process via lib/teslamate/mqtt/pubsub/vehicle_subscriber.ex. These processes:
- Subscribe to vehicle summary streams using
Vehicles.subscribe_to_summary/1 - Receive
%TeslaMate.Vehicles.Vehicle.Summary{}structs containing telemetry data - Extract fields including battery level, speed, location, geofence, and active route
- Publish updates concurrently using
Task.async_stream/3with failure logging viaLogger.warning/1
Topic Structure and Naming Convention
TeslaMate MQTT integration uses a hierarchical topic pattern:
teslamate/<namespace>/cars/<car_id>/<key>
<namespace>: Configurable prefix (defaults to"teslamate")<car_id>: Numeric vehicle identifier<key>: Telemetry field name such asbattery_level,latitude,longitude,charging_state, orheading
The publish/3 helper function in the publisher module constructs these topics automatically, converting Elixir values to strings before transmission.
Retained Messages and Cleanup
The system differentiates between retained and non-retained messages:
- Retained: Most telemetry fields (battery level, location) are retained so new subscribers immediately receive the last known state
- Non-retained: Fields like
healthythat appear in the@do_not_retainlist are published without the retained flag
On startup, each subscriber calls clear_retained/3 to wipe stale retained messages for keys that should no longer persist, preventing outdated data from surviving across application restarts.
Implementation Details
The Publisher Module
lib/teslamate/mqtt/publisher.ex provides the core publishing interface:
def publish(topic, value, opts \\ []) do
# Converts value to string, builds full topic
# Calls Tortoise311.publish/4 with QoS and retain flags
end
The module supports QoS 1 delivery semantics and handles connection state transparently through the underlying Tortoise311 client.
Connection Handling
lib/teslamate/mqtt/handler.ex implements the Tortoise311.Handler behaviour, providing callbacks for:
connection_up/3: Logs successful broker connectionsconnection_down/3: Handles disconnectionsterminate/3: Cleans up on client termination
These callbacks ensure visibility into MQTT connection health through standard Elixir logging.
Configuring TeslaMate MQTT Integration
To enable MQTT publishing, add the following to config/runtime.exs:
config :teslamate, :mqtt,
host: System.get_env("MQTT_HOST") || "localhost",
port: System.get_env("MQTT_PORT") && String.to_integer(System.get_env("MQTT_PORT")) || 1883,
username: System.get_env("MQTT_USERNAME") || "teslamate",
password: System.get_env("MQTT_PASSWORD") || "mqttpassword",
client_id: System.getFollowersByUsername("USERNAME")_id: "teslamate",
qos: 1,
retain: true,
namespace: "teslamate"
To publish custom metrics from your own code:
topic = "teslamate/custom/cars/1/custom_metric"
value = 99.9
TeslaMate.Mqtt.Publisher.publish(topic, value, retain: true, qos: 1)
Summary
- Tortoise311 Foundation: TeslaMate MQTT integration relies on the Tortoise311 Elixir library for protocol handling, providing reliable QoS 1 messaging
- Supervised Architecture: The system uses
TeslaMate.Mqttas a supervisor coordinatingPublisherandPubSubprocesses, with per-vehicleVehicleSubscriberprocesses ensuring fault isolation - Hierarchical Topics: Data publishes to
teslamate/<namespace>/cars/<car_id>/<key>, supporting configurable namespaces and comprehensive telemetry including battery, location, and charging state - Retained Message Management: Critical fields use retained messages for immediate state availability, while
clear_retained/3prevents stale data persistence - Configuration-Driven: Activation requires only
:mqttconfig inconfig/runtime.exs, with theTeslaMate.Applicationconditionally starting the supervision tree
Frequently Asked Questions
What MQTT broker does TeslaMate use?
TeslaMate uses the Tortoise311 MQTT client library (an actively maintained fork of Tortoise) to connect to any standards-compliant MQTT broker. The integration supports brokers like Mosquitto, RabbitMQ, HiveMQ, and cloud-based IoT platforms, requiring only standard host, port, and credential configuration in config/runtime.exs.
How do I configure TeslaMate MQTT integration?
Set environment variables or explicit config values in config/runtime.exs under the :mqtt key for the :teslamate application. Required fields include host, port, username, password, and optionally qos, retain, and namespace. The application detects this configuration in lib/teslamate/application.ex and starts the MQTT supervision tree only when present.
What is the topic structure for TeslaMate MQTT messages?
TeslaMate publishes to topics following the pattern teslamate/<namespace>/cars/<car_id>/<key>. The default namespace is "teslamate", <car_id> is the numeric vehicle identifier, and <key> represents specific telemetry fields like battery_level, charging_state, latitude, or speed. This structure allows fine-grained subscription to individual vehicles or specific data points.
Does TeslaMate support MQTT QoS levels and retained messages?
Yes. TeslaMate MQTT integration supports QoS 1 (at least once delivery) by default, configurable via the :qos setting. Retained messages are enabled by default for most telemetry keys, ensuring new subscribers receive the last known vehicle state immediately. The TeslaMate.Mqtt.Publisher module handles retention logic, excluding specific keys defined in @do_not_retain (such as healthy) from retention to prevent misleading status indicators.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →