173 lines
7.7 KiB
Python
173 lines
7.7 KiB
Python
"""Сборка диагностических скриптов.
|
||
|
||
Три уровня в зависимости от возможностей ELM327:
|
||
L0 (все клоны) — 5 PIDs + stored DTC
|
||
L1 (+ATAT1) — 8 PIDs + VIN + stored/pending DTC
|
||
L2 (+CAF1/CFC1) — 14 PIDs + VIN + калибровки + все ошибки
|
||
|
||
Принцип:
|
||
- Чем выше уровень — тем больше PIDs и глубже диагностика
|
||
- Скрипты захардкожены (PIDs по SAE J1979), LLM не составляет
|
||
- Нет в профиле — не слать (несуществующие команды вешают клонов)
|
||
"""
|
||
|
||
|
||
def build_script_l0() -> dict:
|
||
"""Скрипт для уровня 0 — клоны v1.5 и подобные.
|
||
|
||
Только однокадровые ответы. Без VIN (много-фреймовый, без CFC1 рвётся).
|
||
"""
|
||
return {
|
||
"version": 1,
|
||
"title": "Диагностика (базовая)",
|
||
"steps": [
|
||
{"id": "elm_atrv", "cmd": "ATRV", "desc": "Напряжение"},
|
||
{"id": "pid_05", "cmd": "0105", "desc": "Температура ОЖ"},
|
||
{"id": "pid_0C", "cmd": "010C", "desc": "Обороты"},
|
||
{"id": "pid_0D", "cmd": "010D", "desc": "Скорость"},
|
||
{"id": "pid_11", "cmd": "0111", "desc": "Дроссель"},
|
||
{"id": "pid_04", "cmd": "0104", "desc": "Нагрузка"},
|
||
{"id": "dtc_03", "cmd": "03", "desc": "Коды ошибок"},
|
||
],
|
||
}
|
||
|
||
|
||
def build_script_l1() -> dict:
|
||
"""Скрипт для уровня 1 — хорошие клоны с ATAT1.
|
||
|
||
Быстрее L0 за счёт адаптивного тайминга. VIN — медленно но возможно.
|
||
"""
|
||
return {
|
||
"version": 1,
|
||
"title": "Диагностика (стандартная)",
|
||
"steps": [
|
||
{"id": "elm_atrv", "cmd": "ATRV", "desc": "Напряжение"},
|
||
{"id": "pid_05", "cmd": "0105", "desc": "Температура ОЖ"},
|
||
{"id": "pid_0C", "cmd": "010C", "desc": "Обороты"},
|
||
{"id": "pid_0D", "cmd": "010D", "desc": "Скорость"},
|
||
{"id": "pid_11", "cmd": "0111", "desc": "Дроссель"},
|
||
{"id": "pid_04", "cmd": "0104", "desc": "Нагрузка"},
|
||
{"id": "pid_06", "cmd": "0106", "desc": "STFT"},
|
||
{"id": "pid_07", "cmd": "0107", "desc": "LTFT"},
|
||
{"id": "vin_09", "cmd": "0902", "desc": "VIN"},
|
||
{"id": "dtc_03", "cmd": "03", "desc": "Сохр. ошибки"},
|
||
{"id": "dtc_07", "cmd": "07", "desc": "Pending ошибки"},
|
||
],
|
||
}
|
||
|
||
|
||
def build_script_l2() -> dict:
|
||
"""Скрипт для уровня 2 — настоящий ELM327 с CAF1+CFC1.
|
||
|
||
Полный фарш: много PIDs, VIN быстро, калибровки, все типы ошибок.
|
||
"""
|
||
return {
|
||
"version": 1,
|
||
"title": "Диагностика (полная)",
|
||
"steps": [
|
||
{"id": "elm_atrv", "cmd": "ATRV", "desc": "Напряжение"},
|
||
{"id": "pid_05", "cmd": "0105", "desc": "Температура ОЖ"},
|
||
{"id": "pid_0C", "cmd": "010C", "desc": "Обороты"},
|
||
{"id": "pid_0D", "cmd": "010D", "desc": "Скорость"},
|
||
{"id": "pid_11", "cmd": "0111", "desc": "Дроссель"},
|
||
{"id": "pid_04", "cmd": "0104", "desc": "Нагрузка"},
|
||
{"id": "pid_06", "cmd": "0106", "desc": "STFT"},
|
||
{"id": "pid_07", "cmd": "0107", "desc": "LTFT"},
|
||
{"id": "pid_0B", "cmd": "010B", "desc": "MAP"},
|
||
{"id": "pid_0F", "cmd": "010F", "desc": "Темп. воздуха"},
|
||
{"id": "pid_10", "cmd": "0110", "desc": "MAF"},
|
||
{"id": "pid_1C", "cmd": "011C", "desc": "Стандарт OBD"},
|
||
{"id": "vin_09", "cmd": "0902", "desc": "VIN"},
|
||
{"id": "cal_09", "cmd": "0904", "desc": "Калибровка"},
|
||
{"id": "ecu_09", "cmd": "090A", "desc": "Имя ЭБУ"},
|
||
{"id": "dtc_03", "cmd": "03", "desc": "Сохр. ошибки"},
|
||
{"id": "dtc_07", "cmd": "07", "desc": "Pending ошибки"},
|
||
{"id": "dtc_0A", "cmd": "0A", "desc": "Перманентные"},
|
||
],
|
||
}
|
||
|
||
|
||
# ── Совместимость со старым API ─────────────────────────
|
||
|
||
def build_default_script() -> dict:
|
||
"""Минимальный скрипт (уровень 0)."""
|
||
return build_script_l0()
|
||
|
||
|
||
def build_full_script() -> dict:
|
||
"""Полный скрипт (уровень 2)."""
|
||
return build_script_l2()
|
||
|
||
|
||
def build_script_for_level(level: int) -> dict:
|
||
"""Возвращает скрипт под уровень устройства."""
|
||
if level >= 2:
|
||
return build_script_l2()
|
||
elif level == 1:
|
||
return build_script_l1()
|
||
else:
|
||
return build_script_l0()
|
||
|
||
|
||
def build_dynamic_script() -> dict:
|
||
"""Скрипт для динамического теста — 12 PID, опрос каждые 250мс."""
|
||
return {
|
||
"version": 1,
|
||
"title": "Динамический тест",
|
||
"mode": "dynamic",
|
||
"interval_ms": 250,
|
||
"steps": [
|
||
{"id": "pid_04", "cmd": "0104", "desc": "Нагрузка"},
|
||
{"id": "pid_05", "cmd": "0105", "desc": "ОЖ"},
|
||
{"id": "pid_06", "cmd": "0106", "desc": "STFT"},
|
||
{"id": "pid_07", "cmd": "0107", "desc": "LTFT"},
|
||
{"id": "pid_0B", "cmd": "010B", "desc": "MAP"},
|
||
{"id": "pid_0C", "cmd": "010C", "desc": "RPM"},
|
||
{"id": "pid_0D", "cmd": "010D", "desc": "Скорость"},
|
||
{"id": "pid_0E", "cmd": "010E", "desc": "Зажигание"},
|
||
{"id": "pid_0F", "cmd": "010F", "desc": "IAT"},
|
||
{"id": "pid_10", "cmd": "0110", "desc": "MAF"},
|
||
{"id": "pid_11", "cmd": "0111", "desc": "Дроссель"},
|
||
{"id": "pid_1F", "cmd": "011F", "desc": "Время работы"},
|
||
],
|
||
}
|
||
|
||
|
||
def build_test_script(wait_ms: int = 400, pids: list[str] | None = None, repeat: int = 10) -> dict:
|
||
"""Тестовый скрипт для отладки таймингов ELM327.
|
||
|
||
Сервер управляет таймингами — можно менять wait_ms/pids/repeat без передеплоя APK.
|
||
|
||
Args:
|
||
wait_ms: пауза ПЕРЕД каждой OBD-командой (ms)
|
||
pids: список PID для опроса (по умолчанию 010C,0110,0106)
|
||
repeat: сколько раз повторить цикл
|
||
"""
|
||
if pids is None:
|
||
pids = ["010C", "0110", "0106"]
|
||
|
||
pid_names = {"010C": "RPM", "0110": "MAF", "0106": "STFT", "0105": "ОЖ",
|
||
"0104": "Нагрузка", "0107": "LTFT", "0111": "Дроссель",
|
||
"010D": "Скорость", "010B": "MAP", "010F": "IAT"}
|
||
|
||
steps = []
|
||
# Статика — один проход по всем PID для калибровки
|
||
for pid in pids:
|
||
name = pid_names.get(pid, pid)
|
||
steps.append({"id": f"static_{pid}", "cmd": pid, "desc": f"{name} (статик)", "wait": 0})
|
||
|
||
# Динамика — repeat циклов
|
||
for cycle in range(repeat):
|
||
for pid in pids:
|
||
name = pid_names.get(pid, pid)
|
||
steps.append({"id": f"dyn{cycle}_{pid}", "cmd": pid, "desc": f"{name}", "wait": wait_ms})
|
||
|
||
return {
|
||
"version": 1,
|
||
"mode": "test",
|
||
"title": f"Тест: {len(pids)} PID × {repeat}, пауза {wait_ms}ms",
|
||
"wait_ms": wait_ms,
|
||
"repeat": repeat,
|
||
"steps": steps,
|
||
}
|