a46e5d786d63b4010665c5ea8d0c161ca4b165ef
TurboSu
赛车遥测仪表盘 — 基于 Web 的 B/S 架构外置仪表盘,支持多种赛车游戏遥测数据实时显示。
功能特性
- 多游戏支持 — 插件化架构,内置 Forza Horizon 4/5、Forza Motorsport、Assetto Corsa/ACC、F1、iRacing
- 社区扩展 — 游戏插件可独立打包导入导出 (
.tsp),方便社区贡献小众游戏支持 - 实时仪表盘 — 速度表、转速表、档位指示器、圈速计时器
- 独立仪表盘 — 每个仪表盘是独立文件夹 (
manifest.json+index.html),启动自动扫描 - 场景模式 — 多仪表盘布局组合,支持多比例画布切换
- 局域网共享 — 仪表盘/场景生成独立链接,手机/平板/笔记本均可全屏访问
- 跨端自适应 — 响应式布局:桌面侧边栏 / 平板折叠 / 手机底部导航
- 比例约束渲染 — 仪表盘可指定比例 (
auto/16:9/4:3/1:1) 和渲染模式 (contain/cover/fill/center) - HyperOS 风格 — Miuix 设计语言,毛玻璃模糊效果,日间/夜间模式
- 社区分发 — 仪表盘
.tsd、场景.tss、插件.tsp— zip 格式,便于分享
快速开始
环境要求
- Python 3.10+
- pip
运行
git clone ssh://git@git.yeij.top:2222/AskaEth/TurboSu.git
cd TurboSu
# 一键启动 (自动创建 venv 并安装依赖)
./run.sh
# 或手动启动
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
python app.py
浏览器访问 http://localhost:9527
使用指南
1. 选择游戏
侧边栏 → 游戏列表展开 → 选择你要玩的游戏。列表来自 games/builtin/ (内置) 和 games/user/ (社区)。
2. 配置遥测输出
在各游戏中开启 UDP 数据输出功能:
| 游戏 | 设置位置 | 端口 |
|---|---|---|
| Forza Horizon 4/5 | 设置 → HUD与游戏 → 数据输出 | 20777 |
| Forza Motorsport | 设置 → 游戏玩法 → UDP数据输出 | 20777 |
| Assetto Corsa | 内容管理器 → 自定义UDP | 9996 |
| ACC | 设置 → 电子设备 → UDP | 20777 |
| F1 24 | 设置 → 遥测设置 → UDP | 20777 |
| iRacing | 选项 → 杂项 → 数据记录 | 20777 |
3. 浏览仪表盘
侧边栏 → 仪表盘 → 浏览/分类筛选 → 点击卡片在新标签打开全屏仪表盘。
链接自动复制,局域网设备可直接访问。右键卡片可导出 .tsd 文件。
4. 创建场景
侧边栏 → 场景 → 新建场景 → 编辑添加多个仪表盘 → 选择画布比例 → 渲染。
场景卡片支持导出 .tss,页面顶栏可导入。
5. 数据调试
侧边栏 → 数据测试 → 实时查看解析字段和原始 JSON 数据流。
开发指南
自定义仪表盘格式
每个仪表盘是一个独立文件夹,放在 dashboards/ 或 data/dashboards/:
dashboards/my_dashboard/
├── manifest.json # 元信息
└── index.html # 完整独立页面 (含 WS 连接 + 数据绑定)
manifest.json
{
"id": "my_dashboard",
"name": "我的仪表盘",
"category": "custom",
"description": "简短描述",
"author": "你的名字",
"version": "1.0.0",
"config": {
"icon": "🏎️",
"aspect_ratio": "16:9",
"render_mode": "contain"
}
}
index.html
完全独立的 HTML 页面。需包含:
- WebSocket 连接到
ws://<host>/ws接收遥测数据 data-bind属性绑定数据字段(如data-bind="speed_kmh")- 比例约束渲染逻辑(参考内置仪表盘)
打包分发:将整个文件夹压缩为 zip,改后缀为 .tsd。
自定义游戏插件
插件文件夹放在 games/user/:
games/user/my_game/
├── manifest.json # 元信息
└── parser.py # 解析逻辑 (get_parser() + parse())
manifest.json
{
"id": "my_game",
"name": "我的游戏",
"parser_type": "forza",
"description": "自定义游戏遥测",
"author": "你的名字",
"version": "1.0.0",
"default_port": 20777
}
parser.py
import time
from server.telemetry.data import TelemetryData
def get_parser():
return MyGameParser()
class MyGameParser:
def game_id(self) -> str:
return "my_game"
def parse(self, data: bytes, addr: tuple) -> TelemetryData:
td = TelemetryData(game_id="my_game", timestamp=time.time())
td.raw = {"raw_hex": data.hex(), "length": len(data)}
# 解析你的游戏数据...
# td.speed_kmh = ...
# td.rpm = ...
# td.gear = ...
return td
打包分发:将文件夹压缩为 zip,改后缀为 .tsp,在设置页面导入。
TelemetryData 可用字段
| 字段 | 类型 | 说明 |
|---|---|---|
speed_kmh |
float | 速度 (km/h) |
speed_mph |
float | 速度 (mph) |
rpm |
float | 发动机转速 |
max_rpm |
float | 最大转速 |
gear |
int | 档位 (0=N, -1=R) |
throttle |
float | 油门 (0~1) |
brake |
float | 刹车 (0~1) |
clutch |
float | 离合 (0~1) |
handbrake |
float | 手刹 (0~1) |
steering |
float | 转向 (-1~1) |
lap_time |
float | 当前圈速 (秒) |
best_lap |
float | 最佳圈速 (秒) |
last_lap |
float | 上圈时间 (秒) |
lap_number |
int | 圈数 |
fuel |
float | 燃油 |
boost |
float | 涡轮增压 |
horsepower |
float | 马力 |
torque |
float | 扭矩 |
position_x/y/z |
float | 坐标 |
engine_temp |
float | 发动机温度 |
oil_temp |
float | 油温 |
raw |
dict | 原始数据 |
项目结构
TurboSu/
├── app.py # FastAPI 主入口 (lifespan)
├── run.sh # 一键启动脚本
├── requirements.txt
├── config/settings.py # 全局配置 (JSON 持久化)
├── server/
│ ├── api.py # REST API (状态/配置/CRUD/导入导出)
│ ├── websocket.py # WebSocket 广播 (30fps 限流)
│ ├── game_manager.py # 游戏插件发现/加载/导入导出(.tsp)
│ └── telemetry/
│ ├── data.py # TelemetryData 27字段数据类
│ ├── listener.py # UDP 异步监听器
│ └── parsers/ # 内置解析器 (base/forza/ac/acc/f1/iracing)
├── games/
│ ├── builtin/ # 7 款内置游戏插件
│ │ ├── forza_horizon_5/ # manifest.json + parser.py
│ │ ├── forza_horizon_4/
│ │ ├── forza_motorsport/
│ │ ├── assetto_corsa/
│ │ ├── assetto_corsa_competizione/
│ │ ├── f1_24/
│ │ └── iracing/
│ └── user/ # 社区插件 (运行时安装)
├── dashboards/ # 内置仪表盘 (4 款)
│ ├── speedometer/ # manifest.json + index.html
│ ├── tachometer/
│ ├── gear_indicator/
│ └── lap_timer/
├── models/
│ ├── dashboard.py # 仪表盘模型 + 自动扫描 + zip导入导出
│ └── scene.py # 场景模型 + 画布/布局 + zip导入导出
├── templates/
│ ├── index.html # 主 SPA 页面
│ └── scene.html # 场景渲染页 (iframe组合)
├── static/
│ ├── css/
│ │ ├── miuix.css # HyperOS/Miuix 样式框架 (CSS变量+毛玻璃+主题)
│ │ └── main.css # 布局 + 跨端响应式 (3断点)
│ └── js/
│ ├── app.js / router.js # 应用入口 + Hash路由
│ ├── api.js / ws.js # API + WebSocket 客户端
│ ├── components/ # sidebar.js / topbar.js
│ ├── pages/ # home / dashboard / scene / debug / settings
│ └── utils/ # theme.js / toast.js
├── data/ # 运行时数据 (user dashboards, scenes, config)
├── logs/ # 日志 (轮转文件, 10MB x5)
├── README.md
└── CONTRIBUTING.md
导入导出格式
| 格式 | 后缀 | 本质 | 说明 |
|---|---|---|---|
| 仪表盘 | .tsd |
zip | 含 manifest.json + index.html |
| 场景 | .tss |
zip | 含 scene.json |
| 游戏插件 | .tsp |
zip | 含 manifest.json + parser.py |
作者
Yei.J. (AskaEth)
许可证
Apache License 2.0
Description
Languages
JavaScript
40.4%
Python
30.8%
HTML
19.9%
CSS
8.8%