Files
templates/python/set_devices/protocol_router.py

72 lines
2.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Выбор wire-протокола для одного последовательного канала SETGUI.
Во время подключения оба потоковых parser-а получают одинаковые байты. Первый
полностью проверенный кадр фиксирует режим канала до следующего ``reset``.
Версия находится сразу после общего SOF A5 5A, поэтому протоколы не могут
ошибочно принять кадр друг друга.
"""
from __future__ import annotations
from enum import Enum
from set_devices import protocol as gui_v1
from setprotocol import core as setp_v2
class ProtocolMode(Enum):
"""Wire-протокол, выбранный для текущего физического соединения."""
AUTO = "auto"
SETPROTOCOL_V2 = "setprotocol_v2"
GUI_V1 = "gui_v1"
@property
def display_name(self) -> str:
return {
ProtocolMode.AUTO: "Определение протокола…",
ProtocolMode.SETPROTOCOL_V2: "SETProtocol v2",
ProtocolMode.GUI_V1: "GUI protocol v1 (совместимость)",
}[self]
class ProtocolRouter:
"""Потоковый маршрутизатор SETProtocol v2 и устаревшего GUI v1."""
def __init__(self) -> None:
self._v2 = setp_v2.FrameParser()
self._v1 = gui_v1.FrameParser()
self.mode = ProtocolMode.AUTO
def reset(self, mode: ProtocolMode = ProtocolMode.AUTO) -> None:
self._v2.reset()
self._v1.reset()
self.mode = mode
def select(self, mode: ProtocolMode) -> None:
"""Фиксирует режим и отбрасывает остатки предыдущего разбора."""
if mode is ProtocolMode.AUTO:
self.reset()
return
self.reset(mode)
def feed(self, data: bytes) -> list[gui_v1.Frame | setp_v2.Frame]:
if self.mode is ProtocolMode.SETPROTOCOL_V2:
return list(self._v2.feed(data))
if self.mode is ProtocolMode.GUI_V1:
return list(self._v1.feed(data))
# В AUTO parser-ы независимы. Неверная версия учитывается только их
# внутренней диагностикой и не влияет на второй parser.
v2_frames = self._v2.feed(data)
v1_frames = self._v1.feed(data)
if v2_frames:
self.mode = ProtocolMode.SETPROTOCOL_V2
self._v1.reset()
return list(v2_frames)
if v1_frames:
self.mode = ProtocolMode.GUI_V1
self._v2.reset()
return list(v1_frames)
return []