fix(server): fallback парсинг raw если decoded не распознан
This commit is contained in:
+62
-3
@@ -43,6 +43,8 @@ def build_default_script() -> dict:
|
||||
|
||||
def _parse_batch(responses: list[dict]) -> dict:
|
||||
"""Парсит батч ответов в структуру для LLM."""
|
||||
import re
|
||||
|
||||
result = {
|
||||
"vin": None,
|
||||
"dtc_stored": [],
|
||||
@@ -58,24 +60,79 @@ def _parse_batch(responses: list[dict]) -> dict:
|
||||
|
||||
result["raw_log"].append(f"→ {cmd}\n← {raw}")
|
||||
|
||||
# VIN
|
||||
# ── VIN ──
|
||||
if decoded.startswith("VIN:"):
|
||||
vin = decoded.replace("VIN:", "").strip()
|
||||
if len(vin) == 17:
|
||||
result["vin"] = vin
|
||||
elif "49" in raw and ("02" in raw or "4902" in raw.replace(" ", "")):
|
||||
# fallback: парсим VIN из raw
|
||||
# формат: "014 0:49 02 01 57 56 57..." или "490201575657..."
|
||||
clean = raw.replace(":", "").replace(" ", "").upper()
|
||||
if "490201" in clean:
|
||||
hex_str = clean.split("490201")[-1][:34]
|
||||
vin = ""
|
||||
for i in range(0, len(hex_str) - 1, 2):
|
||||
try:
|
||||
vin += chr(int(hex_str[i:i+2], 16))
|
||||
except (ValueError, OverflowError):
|
||||
pass
|
||||
if len(vin) == 17:
|
||||
result["vin"] = vin
|
||||
decoded = f"VIN: {vin}" # для лога
|
||||
|
||||
# DTC
|
||||
# ── DTC ──
|
||||
if decoded.startswith("DTC stored:"):
|
||||
codes = decoded.replace("DTC stored:", "").strip()
|
||||
if codes != "none":
|
||||
result["dtc_stored"] = [c.strip() for c in codes.split()]
|
||||
elif raw.replace(" ", "").startswith("43"):
|
||||
# fallback: парсим DTC из raw 43XX...
|
||||
clean = raw.replace(" ", "").upper()
|
||||
if clean.startswith("43") and len(clean) >= 4:
|
||||
codes = []
|
||||
i = 2 # skip byte count
|
||||
while i + 3 < len(clean):
|
||||
try:
|
||||
a = int(clean[i:i+2], 16)
|
||||
b = int(clean[i+2:i+4], 16)
|
||||
p = {0: "P", 1: "C", 2: "B", 3: "U"}.get(a >> 6, "?")
|
||||
code = f"{p}{(a>>4)&3}{a&15}{b>>4:X}{b&15:X}"
|
||||
if code != "P0000":
|
||||
codes.append(code)
|
||||
except Exception:
|
||||
pass
|
||||
i += 4
|
||||
if codes:
|
||||
result["dtc_stored"] = codes
|
||||
decoded = f"DTC stored: {' '.join(codes)}"
|
||||
|
||||
if decoded.startswith("DTC pending:"):
|
||||
codes = decoded.replace("DTC pending:", "").strip()
|
||||
if codes != "none":
|
||||
result["dtc_pending"] = [c.strip() for c in codes.split()]
|
||||
elif raw.replace(" ", "").startswith("47"):
|
||||
# fallback: pending DTC
|
||||
clean = raw.replace(" ", "").upper()
|
||||
if clean.startswith("47") and len(clean) >= 4:
|
||||
codes = []
|
||||
i = 2
|
||||
while i + 3 < len(clean):
|
||||
try:
|
||||
a = int(clean[i:i+2], 16)
|
||||
b = int(clean[i+2:i+4], 16)
|
||||
p = {0: "P", 1: "C", 2: "B", 3: "U"}.get(a >> 6, "?")
|
||||
code = f"{p}{(a>>4)&3}{a&15}{b>>4:X}{b&15:X}"
|
||||
if code != "P0000":
|
||||
codes.append(code)
|
||||
except Exception:
|
||||
pass
|
||||
i += 4
|
||||
if codes:
|
||||
result["dtc_pending"] = codes
|
||||
decoded = f"DTC pending: {' '.join(codes)}"
|
||||
|
||||
# PID (формат: "Имя: значение")
|
||||
# ── PID ──
|
||||
if ":" in decoded and not decoded.startswith(("VIN", "DTC", "ELM", "Protocol")):
|
||||
parts = decoded.split(":", 1)
|
||||
if len(parts) == 2:
|
||||
@@ -84,6 +141,8 @@ def _parse_batch(responses: list[dict]) -> dict:
|
||||
"value": parts[1].strip(),
|
||||
})
|
||||
|
||||
logger.info(f"[{cmd}] decoded={decoded[:60]}")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user