asopi tech
asopi techIndie Developer

Asopitech With · Vehicle companion app

Tesla app with Alopex DB & Alopex Skulk

The Tesla app is a vehicle companion app for checking and controlling a Tesla's charging and climate remotely. What if we rebuilt it with Alopex DB and Alopex Skulk?

Updated: Oct 12, 2026

What the service does

The Tesla app lets owners check charging from anywhere, heat or cool the cabin, and see where the car is. Scheduled charging is set from the app too. The data is charging and driving time series, cabin temperature, location and charging records.

Where the data lives

  • Skulk time series: battery level, charging power, cabin temperature and speed are appended to Skulk, tagged by vehicle. Trends over time come from time-bucketed aggregation.
  • Alopex DB tables: vehicles, users, charging records and charging schedules live in tables.

Reading the car’s sensors and writing the values is the car’s software.

Deployment

Skulk is embedded in the car’s software and keeps recording when the connection drops. In the cloud, an Alopex DB cluster receives the records from many cars and returns charging records and trends to the app.

Why Alopex DB and Alopex Skulk fit

Vehicle data is born in the car and gathered in the cloud. Skulk holds the time series in the car, Alopex DB holds vehicles and charging records, and an Alopex DB cluster takes over as the fleet grows.

See it in code

Vehicles and charge records live in Alopex DB (drive and charge time series in Skulk). Just the core of listing charge history and the total.

import alopex

# 車と充電の記録は Alopex DB(走行・充電の時系列は Skulk)
db = alopex.Database.open("tesla.alopex")

db.execute_sql("CREATE TABLE IF NOT EXISTS vehicles (id INTEGER PRIMARY KEY, name TEXT)")
db.execute_sql("""
    CREATE TABLE IF NOT EXISTS charges (
        vehicle_id INTEGER,
        started DATE,
        kwh INTEGER
    )
""")

db.execute_sql("INSERT INTO vehicles (id, name) VALUES (?, ?)", [1, "Model Y"])
for started, kwh in [("2026-10-18", 32), ("2026-10-20", 28), ("2026-10-21", 15)]:
    db.execute_sql("INSERT INTO charges (vehicle_id, started, kwh) VALUES (?, ?, ?)", [1, started, kwh])

# 充電の記録を新しい順に並べ、合計の電力量を出す
print("-- 充電履歴")
for row in db.execute_sql("SELECT started, kwh FROM charges WHERE vehicle_id = ? ORDER BY started DESC", [1]):
    print("  ", row["started"], f'{row["kwh"]}kWh')
total = db.execute_sql("SELECT SUM(kwh) AS total FROM charges WHERE vehicle_id = ?", [1])[0]["total"]
print("合計:", total, "kWh")

The charge records sort and aggregate with SQL. The battery-level, speed and cabin-temperature time series is ingested by Skulk, tagged by vehicle, and received by the cloud cluster.

For data from things that move, we recommend Alopex Skulk embedded in the device with Alopex DB receiving the records in the cloud.