68 lines
2.4 KiB
Python
68 lines
2.4 KiB
Python
"""Состояния и классификация ответов ELM327 (AndrOBD STAT/RSP_ID).
|
|
|
|
State — состояния стейт-машины (UNDEFINED → INITIALIZING → READY → BUSY → ...)
|
|
Rsp — классификация сырых ответов ELM327
|
|
"""
|
|
|
|
from enum import Enum, auto
|
|
|
|
|
|
class State(Enum):
|
|
"""Состояния стейт-машины (AndrOBD STAT).
|
|
|
|
UNDEFINED → INITIALIZING → READY — нормальный путь.
|
|
BUSY — во время выполнения команды.
|
|
ERROR/DISCONNECTED — ошибка, требуется восстановление.
|
|
"""
|
|
UNDEFINED = auto()
|
|
INITIALIZING = auto()
|
|
READY = auto()
|
|
BUSY = auto()
|
|
ERROR = auto()
|
|
DISCONNECTED = auto()
|
|
|
|
|
|
class Rsp:
|
|
"""Классификация ответов ELM327 (AndrOBD RSP_ID).
|
|
|
|
Каждый сырой ответ классифицируется:
|
|
- PROMPT (`>`) — готов к следующей команде
|
|
- OK — команда выполнена
|
|
- SEARCHING — идёт поиск протокола
|
|
- BUS_ERROR/BUS_BUSY/CAN_ERROR/STOPPED — ошибка шины → DISCONNECTED
|
|
- ERROR/DATA_ERROR/BUFFER_FULL — ошибка → warm start
|
|
- UNKNOWN — данные (ответ на PID/DTC)
|
|
"""
|
|
PROMPT = ">"
|
|
OK = "OK"
|
|
SEARCHING = "SEARCHING"
|
|
NODATA = "NODATA"
|
|
ERROR = "ERROR"
|
|
UNABLE = "UNABLE"
|
|
BUS_BUSY = "BUS BUSY"
|
|
BUS_ERROR = "BUS ERROR"
|
|
CAN_ERROR = "CAN ERROR"
|
|
BUS_INIT = "BUS INIT"
|
|
STOPPED = "STOPPED"
|
|
DATA_ERROR = "DATA ERROR"
|
|
BUFFER_FULL= "BUFFER FULL"
|
|
RX_ERROR = "RX ERROR"
|
|
UNKNOWN = ""
|
|
|
|
@classmethod
|
|
def identify(cls, raw: str) -> str:
|
|
"""Определяет тип ответа ELM327 по сырой строке."""
|
|
u = raw.upper().strip()
|
|
# NO DATA бывает как "NODATA" так и "NO DATA"
|
|
if u.replace(" ", "") == "NODATA":
|
|
return cls.NODATA
|
|
for tag in (cls.SEARCHING, cls.ERROR, cls.UNABLE,
|
|
cls.BUS_BUSY, cls.BUS_ERROR, cls.CAN_ERROR,
|
|
cls.BUS_INIT, cls.STOPPED, cls.DATA_ERROR,
|
|
cls.BUFFER_FULL, cls.RX_ERROR, cls.OK):
|
|
if u.startswith(tag):
|
|
return tag
|
|
if raw.strip() == ">":
|
|
return cls.PROMPT
|
|
return cls.UNKNOWN
|