fix(server): fallback парсинг raw если decoded не распознан

This commit is contained in:
Repinoid
2026-05-26 13:22:48 +03:00
parent 00044b91e1
commit 0fb919fa7c
+62 -3
View File
@@ -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