Skip to main content

Library to interface with Gran Turismo's motion rig telemetry service.

Project description

Gran Turismo Telemetry

Python library for interfacing with Polyphony Digital's telemetry service for motion rigs in GT6/GTS/GT7 (maybe older?)

Features

  • Playstation IP Address discovery
  • Asynchronous callbacks
  • Game event observer
  • Telemetry as an object or a dictionary
  • NEW: Real-time GUI Dashboard - Visual gauges for steering, throttle, brake, RPM, and gear

Installation

Install with pip: pip install gt-telem

GUI Dashboard

A real-time telemetry dashboard is now included! The GUI displays:

  • RPM Gauge: Circular gauge showing engine RPM (0-8000)
  • Steering Gauge: Shows steering wheel rotation in radians (requires heartbeat type "B")
  • Throttle Bar: Horizontal bar showing throttle percentage (green)
  • Brake Bar: Horizontal bar showing brake percentage (red)
  • Gear Display: Digital gear indicator (N, R, 1-8)
  • Additional Info: Speed, lap times, fuel level, race position, motion data

Note: The GUI uses heartbeat type "B" to access motion data including steering wheel rotation.

Running the GUI

Main GUI (Requires PlayStation/GT7):

Windows:

# Run the main GUI
run_gui.bat

Linux/macOS:

# Make executable and run
chmod +x run_gui.sh
./run_gui.sh

Test GUI (No PlayStation Required):

For testing the GUI components with simulated data:

Windows:

# Run the test GUI
test_gui.bat

Linux/macOS:

# Make executable and run
chmod +x test_gui.sh
./test_gui.sh

Manual Method:

# Activate virtual environment first
# Windows:
.venv\Scripts\activate.bat
# Linux/macOS:
source .venv/bin/activate

# Then run either GUI
python gt_telemetry_gui.py     # Main GUI
python test_gui.py             # Test GUI

Requirements:

  • Gran Turismo 7 running on PlayStation
  • Telemetry enabled in GT7 settings
  • PlayStation and PC on the same network
  • Python 3.7+ with tkinter (included with most Python installations)

GUI Features:

  • Real-time Updates: 60 FPS refresh rate for smooth gauge movement
  • Connection Management: Easy connect/disconnect with status indicators
  • Error Handling: Clear error messages for connection issues
  • Modern Interface: Dark theme with colorful gauges
  • Responsive Design: Scales well on different screen sizes

Usage

Getting telemetry is fairly straightforward. Here's a simple example that runs the client on a separate thread:

from gt_telem import TurismoClient
from time import sleep

tc = TurismoClient()

tc.start()
for i in range(10):
    sleep(1)
    print(tc.telemetry.position)
tc.stop()

If you're working inside of an asynchronous framework, use run_async()

from gt_telem import TurismoClient

class MyAsyncClass:
    def __init__(self, tc: TurismoClient):
        self.tc = tc
        self.cancel_tkn: asyncio.Event = None

    async def start_telem(self):
        await self.tc.run_async(self.cancel_tkn)

Otherwise run like this if you only care for callbacks:

import json

from gt_telem import TurismoClient
from gt_telem.models import Telemetry

async def print_telem(t: Telemetry):
    print(json.dumps(t.as_dict, indent=4))

tc = TurismoClient()
tc.register_callback(print_telem)
tc.run() #blocking call

The full list of telemetry is available here.

Events

The following events are currently supported:

  • gt_telem.events.GameEvents
    • on_running - The game has started/is running
    • on_in_game_menu - Outside of a race or track screen
    • on_at_track - Player has entered a track screen
    • on_in_race - Fired when the simulation starts, before player control
    • on_paused - When the player pauses the race
    • on_race_end - Fires when a player leaves the simulation
  • gt_telem.events.RaceEvents
    • on_race_start - Fired at the beginning of Lap 1
    • on_race_finish - Fired when the last lap is completed (checkered flag)
    • on_lap_change - Fires when the lap counter changes (including 0->1)
    • on_best_lap_time - A new best lap is set
    • on_last_lap_time - A new last lap time is available
  • gt_telem.events.DriverEvents
    • on_gear_change - A gear has changed
    • on_flash_lights - High Beams have been activated
    • on_handbrake - Player has utilized handbrake
    • on_suggested_gear - Fires when the game suggests a gear change
    • on_tcs - Traction Control System activated
    • on_asm - Active Stability Management activated
    • on_rev_limit - Engine revs exceed threshold
    • on_brake - Player depresses brake
    • on_throttle - Player depresses throttle
    • on_shift_light_low - Engine revs entered lower bound for shift light
    • on_shift_light_high - Engine revs exceed upper bound for shift light

Example using Events

Here's a more complex example of a telemetry recorder that hooks into race start, pause, and race end:

from gt_telem import TurismoClient
from gt_telem.events import GameEvents
from gt_telem.errors.playstation_errors import *

class MySimpleTelemetryRecorder():
    def __init__(self, tc: TurismoClient):
        self.tc = tc
        self.storage = []

    def start(self):
        self.tc.register_callback(MySimpleTelemetryRecorder.receive_telem, [self])

    def stop(self):
        self.tc.deregister_callback(MySimpleTelemetryRecorder.receive_telem)
        # save self.storage somewhere

    @staticmethod
    async def receive_telem(t, context):
        context.storage.append(t)
        print(f"{t.engine_rpm}RPM - {t.boost_pressure}kPa")
        print(f"Best: {t.best_lap_time}\tLast: {t.last_lap_time}")


if __name__ == "__main__":
    try:
        tc = TurismoClient()
    except PlayStatonOnStandbyError as e:
        print("Turn the playstation on")
        print(e)
        exit()
    except PlayStationNotFoundError as e:
        print("Maybe I'm on the wrong network")
        print(e)
        exit()
    ge = GameEvents(tc)
    mstr = MySimpleTelemetryRecorder(tc)
    ge.on_in_race.append(mstr.start)
    ge.on_race_end.append(mstr.stop)
    ge.on_paused.append(mstr.stop)
    print("Listening for telemetry. CTRL+C to stop")
    tc.run()

TurismoClient.run() is a blocking call, but does shut down gracefully when a keyboard interrupt is issued. It also accepts a cancellation token.

Advanced Example

See this jupyter notebook that displays a live race view and how to properly pass a token to shut down gracefully.

Heartbeat Types

Gran Turismo 7 supports different heartbeat message types that provide additional telemetry data. You can specify the heartbeat type when creating a TurismoClient:

from gt_telem import TurismoClient

# Standard heartbeat (default) - 296 bytes
tc_standard = TurismoClient(heartbeat_type="A")

# Motion data heartbeat - 316 bytes with additional motion fields
tc_motion = TurismoClient(heartbeat_type="B")

# Extended data heartbeat - includes filtered inputs and energy recovery
tc_extended = TurismoClient(heartbeat_type="~")

Heartbeat Type "A" (Standard)

This is the default format that provides all the standard telemetry data. Compatible with most existing GT7 telemetry applications.

Heartbeat Type "B" (Motion Data)

Adds 5 additional motion-related fields:

  • wheel_rotation_radians - Wheel rotation in radians
  • filler_float_fb - Possibly lateral slip angle or other motion data
  • sway - Vehicle sway motion
  • heave - Vehicle heave motion
  • surge - Vehicle surge motion

Access motion data using the motion_data property:

telemetry = tc.telemetry
if telemetry and telemetry.motion_data:
    motion = telemetry.motion_data
    print(f"Sway: {motion['sway']:.3f}")
    print(f"Heave: {motion['heave']:.3f}")
    print(f"Surge: {motion['surge']:.3f}")

Heartbeat Type "~" (Extended Data)

Provides additional fields including:

  • throttle_filtered - Filtered throttle input
  • brake_filtered - Filtered brake input
  • energy_recovery - Energy recovery value
  • Additional unknown fields for future expansion

Access extended data using the extended_data property:

telemetry = tc.telemetry
if telemetry and telemetry.extended_data:
    extended = telemetry.extended_data
    print(f"Energy Recovery: {extended['energy_recovery']:.3f}")
    print(f"Filtered Throttle: {extended['throttle_filtered']}")

Important Notes

  • Only one heartbeat type can be active per session. The first heartbeat sent to the game "wins" and cannot be changed until the game stops sending telemetry.
  • Different heartbeat types use different encryption keys (IV masks: A=0xDEADBEAF, B=0xDEADBEEF, ~=0x55FABB4F), which can cause compatibility issues between applications using different formats.
  • Not all applications support the extended heartbeat formats. Use type "A" for maximum compatibility.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gt_telem-1.0.0.tar.gz (60.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gt_telem-1.0.0-py3-none-any.whl (47.6 kB view details)

Uploaded Python 3

File details

Details for the file gt_telem-1.0.0.tar.gz.

File metadata

  • Download URL: gt_telem-1.0.0.tar.gz
  • Upload date:
  • Size: 60.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.5

File hashes

Hashes for gt_telem-1.0.0.tar.gz
Algorithm Hash digest
SHA256 cc43804f45a8baa98c00436c76ee7d783feb22bcb020983e9ecc8e39d8ed7b0c
MD5 dae9110a0a708e4c37938a7007a9ac9c
BLAKE2b-256 fd58e0382ff0142e850f6161cc06f8f966e2d5f078eb5cddd1a8a6b302c3a939

See more details on using hashes here.

File details

Details for the file gt_telem-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: gt_telem-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 47.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.5

File hashes

Hashes for gt_telem-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3078eecd86b81525e464b9e6bc2e9d03264f76d1d0650027a4af1a99627fe734
MD5 4a7da6a09078bb7ee81b2f57dc1759d0
BLAKE2b-256 ea5f16357d9163de7039b71280628f90ba1a41ec10844806f691c6af2c0c21b4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page