diff --git a/kvmd/apps/kvmd/api/switch.py b/kvmd/apps/kvmd/api/switch.py index d89f1b84..105e26f7 100644 --- a/kvmd/apps/kvmd/api/switch.py +++ b/kvmd/apps/kvmd/api/switch.py @@ -52,6 +52,16 @@ class SwitchApi: async def __state_handler(self, _: Request) -> Response: return make_json_response(await self.__switch.get_state()) + @exposed_http("POST", "/switch/set_active_prev") + async def __set_active_prev_handler(self, _: Request) -> Response: + await self.__switch.set_active_prev() + return make_json_response() + + @exposed_http("POST", "/switch/set_active_next") + async def __set_active_next_handler(self, _: Request) -> Response: + await self.__switch.set_active_next() + return make_json_response() + @exposed_http("POST", "/switch/set_active") async def __set_active_port_handler(self, req: Request) -> Response: port = valid_int_f0(req.query.get("port")) diff --git a/kvmd/apps/kvmd/switch/__init__.py b/kvmd/apps/kvmd/switch/__init__.py index 6f2337a4..33f96e4c 100644 --- a/kvmd/apps/kvmd/switch/__init__.py +++ b/kvmd/apps/kvmd/switch/__init__.py @@ -141,6 +141,12 @@ class Switch: # pylint: disable=too-many-public-methods # ===== + async def set_active_prev(self) -> None: + self.__chain.set_active_prev() + + async def set_active_next(self) -> None: + self.__chain.set_active_next() + async def set_active_port(self, port: int) -> None: self.__chain.set_active_port(port) diff --git a/kvmd/apps/kvmd/switch/chain.py b/kvmd/apps/kvmd/switch/chain.py index 4bd9b4eb..386fb7bf 100644 --- a/kvmd/apps/kvmd/switch/chain.py +++ b/kvmd/apps/kvmd/switch/chain.py @@ -55,6 +55,14 @@ class _CmdSetActual(_BaseCmd): actual: bool +class _CmdSetActivePrev(_BaseCmd): + pass + + +class _CmdSetActiveNext(_BaseCmd): + pass + + @dataclasses.dataclass(frozen=True) class _CmdSetActivePort(_BaseCmd): port: int @@ -212,6 +220,12 @@ class Chain: # pylint: disable=too-many-instance-attributes # ===== + def set_active_prev(self) -> None: + self.__queue_cmd(_CmdSetActivePrev()) + + def set_active_next(self) -> None: + self.__queue_cmd(_CmdSetActiveNext()) + def set_active_port(self, port: int) -> None: self.__queue_cmd(_CmdSetActivePort(port)) @@ -330,10 +344,29 @@ class Chain: # pylint: disable=too-many-instance-attributes case _CmdSetActual(): self.__actual = cmd.actual + case _CmdSetActivePrev(): + if len(self.__units) > 0: + port = self.__active_port + port -= 1 + if port >= 0: + self.__active_port = port + self.__queue_event(PortActivatedEvent(self.__active_port)) + + case _CmdSetActiveNext(): + port = self.__active_port + if port < 0: + port = 0 + else: + port += 1 + if port < len(self.__units) * 4: + self.__active_port = port + self.__queue_event(PortActivatedEvent(self.__active_port)) + case _CmdSetActivePort(): # Может быть вызвано изнутри при синхронизации - self.__active_port = cmd.port - self.__queue_event(PortActivatedEvent(self.__active_port)) + if cmd.port < len(self.__units) * 4: + self.__active_port = cmd.port + self.__queue_event(PortActivatedEvent(self.__active_port)) case _CmdSetPortBeacon(): (unit, ch) = self.get_real_unit_channel(cmd.port) diff --git a/kvmd/clients/kvmd.py b/kvmd/clients/kvmd.py index 1fd89e1b..c6a286f0 100644 --- a/kvmd/clients/kvmd.py +++ b/kvmd/clients/kvmd.py @@ -136,6 +136,26 @@ class _AtxApiPart(_BaseApiPart): raise +class _SwitchApiPart(_BaseApiPart): + async def set_active_prev(self) -> None: + session = self._ensure_http_session() + async with session.post("/switch/set_active_prev") as resp: + htclient.raise_not_200(resp) + + async def set_active_next(self) -> None: + session = self._ensure_http_session() + async with session.post("/switch/set_active_next") as resp: + htclient.raise_not_200(resp) + + async def set_active(self, port: int) -> None: + session = self._ensure_http_session() + async with session.post( + url="/switch/set_active", + params={"port": port}, + ) as resp: + htclient.raise_not_200(resp) + + # ===== class KvmdClientWs: def __init__(self, ws: aiohttp.ClientWebSocketResponse) -> None: @@ -213,6 +233,7 @@ class KvmdClientSession(BaseHttpClientSession): self.streamer = _StreamerApiPart(self._ensure_http_session) self.hid = _HidApiPart(self._ensure_http_session) self.atx = _AtxApiPart(self._ensure_http_session) + self.switch = _SwitchApiPart(self._ensure_http_session) @contextlib.asynccontextmanager async def ws(self) -> AsyncGenerator[KvmdClientWs, None]: