/00 — boot sequence

Hello.

cd ../open-source

aiyu-ayaan/RideLink

RideLink

🛵 Open-source TVS Connect alternative for TVS Ntorq 125 (Race XP, XT, SmartXonnect). Google Maps turn-by-turn arrows on the scooter display, caller ID, WhatsApp counts, ride analytics. No account, no cloud, no tracking.

  • active
  • 1 stars
  • Kotlin
  • Other
  • pushed today
RideLink preview

// readmeaiyu-ayaan/RideLink

RideLink logo

RideLink

Your scooter display, without the account.
A private, local-first Android companion app for TVS SmartXonnect scooter displays.

Release status Latest release Last commit Android 8.0+ Kotlin 2.4 Material 3 Expressive On-device only


RideLink connects your phone to your TVS SmartXonnect scooter display over Bluetooth Low Energy (BLE). It replaces the official TVS Connect app for riding features: it streams Google Maps turn-by-turn directions, forwards caller ID and accepts/rejects calls with handlebar buttons, syncs media info, and keeps time, battery, signal, and local weather up to date.

Zero accounts. Zero cloud servers. Zero tracking. All communications stay between your phone and your scooter.

Highlights

  • Turn-by-turn navigation: Reads Google Maps notifications live and maps navigation icons directly to scooter dashboard arrows and distance readouts.
  • Call control: Shows caller ID on incoming calls; answer or reject calls using scooter switches or quick auto-SMS templates.
  • Media sessions: Syncs track title, artist, playback state, and volume to compatible digital displays.
  • Live telemetry & status: Real-time speed, trip meters, odometer, fuel level, range, engine temperatures, service reminders, and MIL diagnostics.
  • Ride analytics & history: Automatic ride recording with split distance sourcing (Google Maps route progress vs. odometer vs. speed integration), elevation, speed bands, and SQLite history exportable to CSV.
  • Weather & environment: Optional local temperature, AQI, and location sync via Open-Meteo (no API key required).
  • Fuel and service: Fuel log with real full-to-full mileage and cost per km (₹), automatic refuel detection from the fuel gauge, low-fuel alert that finds a petrol pump in Maps, and service / insurance / PUC reminders shown on the display.
  • Riding safety: WhatsApp auto-reply while riding (one-to-one chats, once per ride), ride check-in SMS with a Google Maps link at start and end, and a precise last-parked spot.
  • Multi-scooter garage: Pair and manage multiple scooters with per-bike model profiles and auto-reconnect.
  • Material 3 Expressive UI: Built entirely in Jetpack Compose with dynamic color, adaptive layouts, dark/light themes, and floating pill navigation.
  • Auto model detection: Recognises the SmartXonnect LCD (Race XP), older Ntorq and 2025+ clusters from their own frames.
  • Race XP extras: Race stats, display brightness, SMS sender, birthday greeting, last parked location and missed-call auto-reply.
  • Developer tools: Demo navigation through every turn type, arrow and alert code sweeps, and a live frame console.
  • In-app updates: Built-in GitHub Releases updater supporting Stable, Beta, and Alpha release channels.

Supported scooters

RideLink detects the display from the frames it sends and picks the right protocol by itself (Settings → Scooter → Auto). You can also pick the model by hand.

ScooterYearsDisplayProtocol in RideLinkTurn-by-turnStatus
NTORQ 125 Race XP2020 – 2026SmartXonnect LCD, arrow pictogram + 2 text linesSmartXonnect (auto-detected)Arrow + distance + direction words✅ Tested on a 2026 Race XP
NTORQ 125 Standard / Race Edition / Super Squad / Marvel editions2018 – 2024SmartXonnect LCDSmartXonnect (auto-detected)Arrow + distance + direction words🟡 Same protocol as the Race XP, not yet tested
NTORQ 125 XT2023+Hybrid TFT + LCDOlder Ntorq (U577 premium)Arrow + distance🟡 Untested on a real scooter
NTORQ 125 (U716) / U577 base2022 – 2024LCDOlder NtorqArrow + distance🟡 Untested
NTORQ 125 2025+ (U812, N251 Standard, U458 Race, U377 Super Squad)2025+Digital cluster2025+ NtorqArrow + distance + text🟡 Built from the TVS app, untested
NTORQ 1502025+TFT / LCDNot supported yet–❌

What works on every supported display: Google Maps turn-by-turn, caller ID with accept/reject from the scooter switch, missed calls, phone battery, signal, clock sync, WhatsApp/Facebook/Instagram counts, rider name and custom text lines, overspeed alert, live ride data and ride analytics.

Extras on the SmartXonnect LCD (Race XP): race stats (best lap, top speed, 0–60), display brightness, SMS sender, birthday / purchase-day greeting, plus experimental notification-light clear, food delivery alerts and last-ride CO2.

Extras on TFT displays: weather + AQI, place name and music info.

Tested your scooter? Open an issue with the model and year and a Console log (Settings → Developer options → Save logs) so it can move to ✅.

Screenshots

Ride (Demo Mode)Ride (Dark Theme)AnalyticsSettingsDeveloper Console
Ride Screen with Live Demo RideRide Screen Dark ThemeAnalytics and Ride HistorySettings ScreenDeveloper Console
Active navigation turn, speed & live ride telemetryMaterial 3 dark theme with scooter chipsPeriod stats, distance chart & ride recordsModular settings sections and scooter garageLive BLE frame log & diagnostic test injection

How it works

flowchart LR
    subgraph Phone["Android Device (RideLink)"]
        direction TB
        Service["ClusterService<br/>Foreground Service"]
        Notif["RideNotificationListener<br/>Maps turns · Calls · Media"]
        Controller["ClusterController<br/>Session state · Telemetry"]
        Recorder["RideRecorder & Store<br/>SQLite v2 · Period stats"]
        Link["ClusterLink<br/>BLE GATT engine"]
        
        Notif --> Controller
        Controller --> Recorder
        Controller <--> Link
        Service --> Controller
    end

    subgraph Scooter["TVS SmartXonnect Display"]
        direction TB
        GATT["GATT Server"]
        Dash["Instrument Cluster<br/>LCD / TFT"]
        GATT <--> Dash
    end

    Link <-->|"BLE (Service 5351 · Write 5352 · Notify 5354)"| GATT

Data flow

  1. Connection: Scans for BLE advertisements matching TVS displays. Once paired, ClusterService maintains a persistent foreground GATT link with automatic reconnection.
  2. Handshake: Negotiates MTU 512, enables notifications on 5354, authenticates rider profile (5B 52), and syncs media state and social counts.
  3. Heartbeat & Telemetry: Emits status packets (5B 4A) every 2 seconds with time, battery percentage, signal strength, network status, and ambient temperature. Incoming notify frames (5A 10, 5A 11, 5A 19) update local speed, trip distance, fuel, range, and diagnostic telemetry.
  4. Navigation: Intercepts Google Maps active navigation steps, converts direction arrows and distance meters into cluster-native control codes (5B 4F text + 5A 4E instruction), and streams them with synchronized timing.
  5. Calls: Injects ringing caller frames (5B 43) every 500 ms; handles cluster switch presses to answer or reject calls through Android's TelecomManager.

Full protocol reverse-engineering notes and frame structures are documented in PROTOCOL.md.

Architecture

RideLink is organized into three clean Gradle modules:

graph LR
    app[":app<br/>MainActivity · ClusterService · RideNotificationListener · BootReceiver"]
    ui[":ui<br/>Compose screens · Theme · Material 3 Expressive · Strings"]
    core[":core<br/>Protocol · BLE GATT · ClusterController · Parsers · SQLite stores"]

    app --> ui
    app --> core
    ui --> core
  • :app: Application entry point, Android manifest, foreground services, broadcast receivers, and application lifecycle.
  • :core: Protocol encoders/decoders, BLE GATT link manager, notification parsers, telecom integration, weather repository, and SQLite databases (garage.db, rides.db).
  • :ui: 100% Jetpack Compose UI, Material 3 Expressive theming, navigation graphs, canvas analytics charts, and localized strings.

For deep dive into state ownership and lifecycle, see development/docs/ARCHITECTURE.md.

Installation

Releases

Download the latest signed release APK from the Releases page.

RideLink features an in-app updater (Settings → About → Updates). Once installed, updates can be checked, downloaded, and installed directly with support for Stable, Beta, and Alpha channels.

Permissions explained

RideLink requests only the permissions needed to replicate dashboard functionality:

PermissionPurpose
Nearby devices / BluetoothConnect to the scooter cluster over BLE.
Notification accessRead Google Maps navigation steps and incoming caller details.
Phone state & call log (Optional)Display caller names and signal bar status on the speedometer.
Answer phone calls (Optional)Accept incoming calls using the scooter's handlebar switch.
Location (Coarse) (Optional)Fetch local weather and air quality via Open-Meteo for TFT clusters.

Development & build

Prerequisites

  • Android Studio Ladybug / Meerkat or newer
  • JDK 17 or 21
  • Android SDK 35 (Android 15)

Build commands

# Clone the repository
git clone https://github.com/aiyu-ayaan/RideLink.git
cd RideLink

# Assemble debug APK
./gradlew assembleDebug

# Run unit tests
./gradlew test

# Run protocol verification tests
./gradlew :core:test --tests "com.aiyu.ridelink.core.protocol.*"

The debug APK will be placed at app/build/outputs/apk/debug/app-debug.apk.

Test tools (tools/)

The repository includes desktop Python test utilities (requires BlueZ on Linux, python3-dbus, and python3-gi):

  • tools/fake_cluster.py: Emulates a TVS SmartXonnect scooter display over BlueZ GATT, printing decoded frames received from the phone.
  • tools/central_test.py: Simulates the phone central and injects pinned test frames into a real or virtual display.

Privacy & ethics

  • No telematics sent to third parties: RideLink contains zero analytics SDKs, trackers, or telemetry endpoints.
  • Personal use project: RideLink is an independent project and is not affiliated with, endorsed by, or connected to TVS Motor Company. No proprietary TVS code or assets are distributed.

Related docs

License

RideLink is source-available, not open source. The code is public to read and audit; copying, modifying, redistributing or building your own version needs written permission. You may install and use the official release APKs for personal use. See LICENSE for the full terms.

// stack

  • Kotlin
  • Android
  • BLE
  • Bluetooth LOW Energy
  • Google Maps
  • Jetpack Compose
  • Material3
  • Motorcycle
  • android
  • ble
  • bluetooth-low-energy
  • google-maps
  • jetpack-compose
  • kotlin
  • material3
  • motorcycle
  • ntorq
  • ntorq-125
  • ntorq-race-xp
  • open-source

// specs

status
Working
type
Mobile
year
2026
language
Kotlin
license
Other
stars
1
branch
master

Repository data last synced