How the TeslaMate Conversion Module Handles Unit Transformations

The TeslaMate.Convert module centralizes all unit normalization using pure functions and compile-time constants, ensuring consistent speed, distance, length, temperature, and time transformations across the UI and database.

The teslamate-org/teslamate repository relies on the conversion module to normalize raw data received from the Tesla API into locale-appropriate units. Located in lib/teslamate/convert.ex, this module implements total functions that return nil for nil inputs while preserving type safety through overloaded arithmetic for Decimal, float, and integer values.

Core Architecture of the Conversion Module

The conversion module defines transformation factors as module attributes at compile time. All functions are pure and side-effect free, making them safe to call from LiveViews, background jobs, and API handlers without triggering database queries or external I/O.

The module handles three numeric types distinctly:

  • Decimal structs for exact arithmetic
  • Integers when precision is set to 0
  • Floats for standard floating-point rounding

This design ensures that TeslaMate maintains precision for financial or scientific calculations while allowing flexible formatting for display purposes.

Speed and Distance Conversions

Miles per Hour to Kilometres per Hour

The mph_to_kmh/1 function converts vehicle speed data using the @km_factor constant. When the input is a Decimal, the function performs exact division using Decimal arithmetic; otherwise, it applies round/1 to the result.


# Convert API speed (mph) to km/h with Decimal precision

speed_mph = Decimal.new("55.2")
speed_kmh = TeslaMate.Convert.mph_to_kmh(speed_mph)

Distance Transformations

Distance conversions support bidirectional transformation with configurable precision. The miles_to_km/2 and km_to_miles/2 functions in lib/teslamate/convert.ex handle three cases:

  • Decimal values using @km_factor_d for exact conversion
  • Integer rounding when precision is 0
  • Float rounding for all other precision levels

# Convert odometer reading with 2-decimal precision

odometer_mi = 12345.678
odometer_km = TeslaMate.Convert.miles_to_km(odometer_mi, 2)

# => 19860.57

Length and Temperature Transformations

Metres to Feet and Inverse

For length conversions, m_to_ft/1 and ft_to_m/1 utilize the @ft_factor constant. The metre-to-feet function multiplies by the factor, while the inverse divides by it. Both functions support Decimal inputs through Decimal.mult/2 and equivalent division operations.

Celsius to Fahrenheit

The celsius_to_fahrenheit/2 function implements the standard formula (C × 9 / 5) + 32. Like distance conversions, it provides a Decimal overload for exact arithmetic and falls back to float or integer rounding based on the specified precision parameter.

Time Formatting with sec_to_str/1

Beyond unit transformations, the module handles temporal data through sec_to_str/1. This function decomposes a seconds value into weeks, days, hours, minutes, and seconds using a pre-computed @divisor list.

The implementation:

  • Calculates components for each time unit
  • Discards zero-valued components
  • Returns at most two parts (e.g., ["2 wk", "3 d"])

This formatting appears throughout the TeslaMate dashboard when displaying charging durations or trip lengths.


# Format charging duration for UI display

seconds = 9_864
TeslaMate.Convert.sec_to_str(seconds)

# => ["2 hr", "44 min"]

Integration Across the Codebase

The conversion module integrates deeply into TeslaMate's data pipeline:

Summary

  • The TeslaMate.Convert module in lib/teslamate/convert.ex provides pure, total functions for all unit transformations.
  • Compile-time constants (@km_factor, @ft_factor, @divisor) ensure consistent conversion factors across the application.
  • Functions handle Decimal, integer, and float inputs with appropriate arithmetic precision.
  • The module supports speed (mph/kmh), distance (miles/km), length (m/feet), temperature (C/F), and time (seconds to formatted strings).
  • Integration points include vehicle serializers, state managers, and Phoenix LiveViews for consistent data representation.

Frequently Asked Questions

How does TeslaMate handle precision in distance conversions?

The miles_to_km/2 and km_to_miles/2 functions accept a precision parameter. When set to 0, they return rounded integers. For other values, they return floats rounded to the specified decimal places. Decimal inputs receive exact arithmetic treatment without rounding errors.

What happens when conversion functions receive nil values?

All functions in the conversion module are total functions, meaning they safely return nil when the input is nil. This design prevents runtime exceptions in the vehicle data pipeline when the Tesla API temporarily returns incomplete telemetry.

Where is the conversion module used in the TeslaMate UI?

The module appears in lib/teslamate_web/live/car_live/summary.ex for formatting charging durations, and throughout lib/teslamate_web/live/vehicle_live/* templates for displaying converted speed, range, and temperature values to end users.

Why does TeslaMate use Decimal arithmetic for some conversions?

The Tesla API occasionally returns high-precision floating-point values for odometer and speed readings. By using Decimal structs in mph_to_kmh/1 and distance functions, TeslaMate avoids floating-point rounding errors that could accumulate in long-term mileage calculations or energy efficiency metrics.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →