Add UDS protocol support (ISO 14229) for ECU emulator
Implement UDS Service 0x22 (Read Data By Identifier) with support for: - Engine ECU (0x7E0): boost pressure, fuel rail pressure, lambda, torque, wastegate position, ignition timing, knock correction per cylinder - DSG Transmission (0x7E1): current gear, selector position, oil temp - Instrument Cluster (0x714): RPM, ambient light sensor Also adds ECU_EMULATOR_SPEC.md with full protocol documentation. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,52 +14,70 @@ except ImportError:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
# OBD2 PIDs для тестирования
|
||||
# OBD2 PIDs для тестирования (согласно ECU_EMULATOR_SPEC.md)
|
||||
TEST_PIDS = [
|
||||
# Supported PIDs
|
||||
(0x00, "Supported PIDs [01-20]"),
|
||||
(0x20, "Supported PIDs [21-40]"),
|
||||
(0x40, "Supported PIDs [41-60]"),
|
||||
# Engine
|
||||
(0x04, "Engine Load"),
|
||||
(0x05, "Coolant Temperature"),
|
||||
(0x0C, "Engine RPM"),
|
||||
(0x0D, "Vehicle Speed"),
|
||||
(0x0F, "Intake Air Temperature"),
|
||||
(0x10, "MAF Air Flow Rate"),
|
||||
(0x11, "Throttle Position"),
|
||||
# Fuel
|
||||
(0x2F, "Fuel Tank Level"),
|
||||
(0x5C, "Oil Temperature"),
|
||||
# Other
|
||||
(0x46, "Ambient Temperature"),
|
||||
]
|
||||
|
||||
|
||||
def decode_pid(pid: int, data: bytes) -> str:
|
||||
"""Декодировать значение PID."""
|
||||
"""Декодировать значение PID согласно ECU_EMULATOR_SPEC.md."""
|
||||
if len(data) < 1:
|
||||
return "No data"
|
||||
|
||||
if pid == 0x00:
|
||||
# Supported PIDs bitmap
|
||||
# Supported PIDs bitmap
|
||||
if pid in (0x00, 0x20, 0x40, 0x60):
|
||||
if len(data) >= 4:
|
||||
mask = int.from_bytes(data[:4], "big")
|
||||
supported = []
|
||||
base = pid + 1
|
||||
for i in range(32):
|
||||
if mask & (1 << (31 - i)):
|
||||
supported.append(f"{i+1:02X}")
|
||||
return f"PIDs: {', '.join(supported[:10])}..."
|
||||
supported.append(f"{base + i:02X}")
|
||||
if supported:
|
||||
return f"PIDs: {', '.join(supported)}"
|
||||
return "None"
|
||||
return f"Raw: {data.hex()}"
|
||||
|
||||
elif pid == 0x05 or pid == 0x0F or pid == 0x46:
|
||||
# Temperature: A - 40
|
||||
# Temperature PIDs: A - 40
|
||||
elif pid in (0x05, 0x0F, 0x46, 0x5C):
|
||||
return f"{data[0] - 40} °C"
|
||||
|
||||
# Engine Load / Throttle / Fuel Level: A * 100 / 255
|
||||
elif pid in (0x04, 0x11, 0x2F):
|
||||
return f"{data[0] * 100 / 255:.1f} %"
|
||||
|
||||
# RPM: (A*256 + B) / 4
|
||||
elif pid == 0x0C:
|
||||
# RPM: (A*256 + B) / 4
|
||||
if len(data) >= 2:
|
||||
rpm = (data[0] * 256 + data[1]) / 4
|
||||
return f"{rpm:.0f} rpm"
|
||||
|
||||
# Speed: A
|
||||
elif pid == 0x0D:
|
||||
# Speed: A
|
||||
return f"{data[0]} km/h"
|
||||
|
||||
elif pid == 0x11 or pid == 0x2F:
|
||||
# Percentage: A * 100 / 255
|
||||
return f"{data[0] * 100 / 255:.1f} %"
|
||||
# MAF: (A*256 + B) / 100
|
||||
elif pid == 0x10:
|
||||
if len(data) >= 2:
|
||||
maf = (data[0] * 256 + data[1]) / 100
|
||||
return f"{maf:.2f} g/s"
|
||||
|
||||
return f"Raw: {data.hex()}"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user