fix: канонический init Python (ATE0→..., drain после send, clone detect)
This commit is contained in:
+26
-5
@@ -56,6 +56,7 @@ class AndrOBD:
|
|||||||
|
|
||||||
INIT_TMO = 10000 # мс — таймаут для команд инициализации
|
INIT_TMO = 10000 # мс — таймаут для команд инициализации
|
||||||
DEF_TMO = 200 # мс — начальный таймаут
|
DEF_TMO = 200 # мс — начальный таймаут
|
||||||
|
ATST_CLONE = 0x96 # 150×4=600ms — фиксированный для клонов
|
||||||
|
|
||||||
def __init__(self, port: str, baudrate: int = 38400):
|
def __init__(self, port: str, baudrate: int = 38400):
|
||||||
self._transport = SerialTransport(port, baudrate)
|
self._transport = SerialTransport(port, baudrate)
|
||||||
@@ -73,20 +74,39 @@ class AndrOBD:
|
|||||||
self._transport.close()
|
self._transport.close()
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
"""Базовая инициализация ELM327 (уровень 0 — все клоны).
|
"""Канонический init: ATE0→ATL0→ATS0→ATI→[ветвление]→ATSP0.
|
||||||
|
|
||||||
ТОЛЬКО команды которые есть у ВСЕХ клонов:
|
Эхо ПЕРВЫМ. ATI ДО протокола. Клон: ATST фикс, без ATAT1.
|
||||||
ATE0 ATL0 ATS0 ATH1 ATSP0
|
|
||||||
"""
|
"""
|
||||||
logger.info("AndrOBD: init (L0)")
|
logger.info("AndrOBD: init (L0)")
|
||||||
self._state = State.INITIALIZING
|
self._state = State.INITIALIZING
|
||||||
|
|
||||||
|
# Шаг 1: clone-safe, без протокола
|
||||||
self._exec("ATE0", self.DEF_TMO * 5)
|
self._exec("ATE0", self.DEF_TMO * 5)
|
||||||
|
self._transport.try_read(500) # drain после AT-команды
|
||||||
self._exec("ATL0", self.DEF_TMO * 5)
|
self._exec("ATL0", self.DEF_TMO * 5)
|
||||||
|
self._transport.try_read(500)
|
||||||
self._exec("ATS0", self.DEF_TMO * 5)
|
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._exec("ATSP0", self.INIT_TMO)
|
||||||
|
self._transport.try_read(500)
|
||||||
|
|
||||||
self._state = State.READY
|
self._state = State.READY
|
||||||
logger.info("AndrOBD: ready (L0)")
|
logger.info(f"AndrOBD: ready (L0, clone={is_clone})")
|
||||||
|
|
||||||
def init_l1(self):
|
def init_l1(self):
|
||||||
"""Инициализация уровня 1: база + адаптивный тайминг."""
|
"""Инициализация уровня 1: база + адаптивный тайминг."""
|
||||||
@@ -111,6 +131,7 @@ class AndrOBD:
|
|||||||
self._recover()
|
self._recover()
|
||||||
self._state = State.BUSY
|
self._state = State.BUSY
|
||||||
result = self._exec(cmd, self._timing.ms)
|
result = self._exec(cmd, self._timing.ms)
|
||||||
|
self._transport.try_read(500) # drain после read — клон v1.5
|
||||||
if self._state == State.BUSY:
|
if self._state == State.BUSY:
|
||||||
self._state = State.READY
|
self._state = State.READY
|
||||||
return result
|
return result
|
||||||
|
|||||||
Reference in New Issue
Block a user