From f283113ab1ca546ce1166c3ccf4c757f2042895b Mon Sep 17 00:00:00 2001 From: Repinoid Date: Sun, 28 Jun 2026 11:23:12 +0400 Subject: [PATCH] =?UTF-8?q?fix:=20=D0=BA=D0=B0=D0=BD=D0=BE=D0=BD=D0=B8?= =?UTF-8?q?=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B9=20init=20Python=20(ATE0?= =?UTF-8?q?=E2=86=92...,=20drain=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20send,?= =?UTF-8?q?=20clone=20detect)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- obd/protocol.py | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/obd/protocol.py b/obd/protocol.py index 5243fb8..d95a3ed 100644 --- a/obd/protocol.py +++ b/obd/protocol.py @@ -56,6 +56,7 @@ class AndrOBD: INIT_TMO = 10000 # мс — таймаут для команд инициализации DEF_TMO = 200 # мс — начальный таймаут + ATST_CLONE = 0x96 # 150×4=600ms — фиксированный для клонов def __init__(self, port: str, baudrate: int = 38400): self._transport = SerialTransport(port, baudrate) @@ -73,20 +74,39 @@ class AndrOBD: self._transport.close() def init(self): - """Базовая инициализация ELM327 (уровень 0 — все клоны). + """Канонический init: ATE0→ATL0→ATS0→ATI→[ветвление]→ATSP0. - ТОЛЬКО команды которые есть у ВСЕХ клонов: - ATE0 ATL0 ATS0 ATH1 ATSP0 + Эхо ПЕРВЫМ. ATI ДО протокола. Клон: ATST фикс, без ATAT1. """ logger.info("AndrOBD: init (L0)") self._state = State.INITIALIZING + + # Шаг 1: clone-safe, без протокола self._exec("ATE0", self.DEF_TMO * 5) + self._transport.try_read(500) # drain после AT-команды self._exec("ATL0", self.DEF_TMO * 5) + self._transport.try_read(500) self._exec("ATS0", self.DEF_TMO * 5) - self._exec("ATH1", self.DEF_TMO * 5) + self._transport.try_read(500) + + # Шаг 2: ATI → detectClone ДО ветвления + ati = self._exec("ATI", self.DEF_TMO * 5) + self._transport.try_read(500) + is_clone = "v1.5" in ati.lower() + if is_clone: + logger.info("AndrOBD: clone v1.5 — ATST fixed, no ATAT1") + self._exec(f"ATST{self.ATST_CLONE:02X}", self.DEF_TMO * 5) + self._transport.try_read(500) + else: + self._exec("ATAT1", self.DEF_TMO * 5) + self._transport.try_read(500) + + # Шаг 3: протокол self._exec("ATSP0", self.INIT_TMO) + self._transport.try_read(500) + self._state = State.READY - logger.info("AndrOBD: ready (L0)") + logger.info(f"AndrOBD: ready (L0, clone={is_clone})") def init_l1(self): """Инициализация уровня 1: база + адаптивный тайминг.""" @@ -111,6 +131,7 @@ class AndrOBD: self._recover() self._state = State.BUSY result = self._exec(cmd, self._timing.ms) + self._transport.try_read(500) # drain после read — клон v1.5 if self._state == State.BUSY: self._state = State.READY return result