diff options
Diffstat (limited to 'kvmd')
-rw-r--r-- | kvmd/apps/kvmd/api/msd.py | 6 | ||||
-rw-r--r-- | kvmd/apps/kvmd/server.py | 17 | ||||
-rw-r--r-- | kvmd/plugins/msd/otg/__init__.py | 22 |
3 files changed, 38 insertions, 7 deletions
diff --git a/kvmd/apps/kvmd/api/msd.py b/kvmd/apps/kvmd/api/msd.py index 2fa2eb9b..98e85412 100644 --- a/kvmd/apps/kvmd/api/msd.py +++ b/kvmd/apps/kvmd/api/msd.py @@ -63,7 +63,11 @@ class MsdApi: @exposed_http("GET", "/msd") async def __state_handler(self, _: Request) -> Response: - return make_json_response(await self.__msd.get_state()) + state = await self.__msd.get_state() + if state["storage"] and state["storage"]["parts"]: + state["storage"]["size"] = state["storage"]["parts"][""]["size"] # Legacy API + state["storage"]["free"] = state["storage"]["parts"][""]["free"] # Legacy API + return make_json_response(state) @exposed_http("POST", "/msd/set_params") async def __set_params_handler(self, req: Request) -> Response: diff --git a/kvmd/apps/kvmd/server.py b/kvmd/apps/kvmd/server.py index 4f5a10d3..d9e07484 100644 --- a/kvmd/apps/kvmd/server.py +++ b/kvmd/apps/kvmd/server.py @@ -153,6 +153,7 @@ class _Subsystem: class KvmdServer(HttpServer): # pylint: disable=too-many-arguments,too-many-instance-attributes __EV_GPIO_STATE = "gpio_state" __EV_ATX_STATE = "atx_state" + __EV_MSD_STATE = "msd_state" __EV_STREAMER_STATE = "streamer_state" __EV_OCR_STATE = "ocr_state" __EV_INFO_STATE = "info_state" @@ -208,7 +209,7 @@ class KvmdServer(HttpServer): # pylint: disable=too-many-arguments,too-many-ins _Subsystem.make(user_gpio, "User-GPIO", self.__EV_GPIO_STATE), _Subsystem.make(hid, "HID", "hid_state").add_source("hid_keymaps_state", self.__hid_api.get_keymaps, None, None), _Subsystem.make(atx, "ATX", self.__EV_ATX_STATE), - _Subsystem.make(msd, "MSD", "msd_state"), + _Subsystem.make(msd, "MSD", self.__EV_MSD_STATE), _Subsystem.make(streamer, "Streamer", self.__EV_STREAMER_STATE), _Subsystem.make(ocr, "OCR", self.__EV_OCR_STATE), _Subsystem.make(info_manager, "Info manager", self.__EV_INFO_STATE), @@ -378,6 +379,8 @@ class KvmdServer(HttpServer): # pylint: disable=too-many-arguments,too-many-ins await self.__poll_gpio_state(poller) case self.__EV_INFO_STATE: await self.__poll_info_state(poller) + case self.__EV_MSD_STATE: + await self.__poll_msd_state(poller) case self.__EV_STREAMER_STATE: await self.__poll_streamer_state(poller) case self.__EV_OCR_STATE: @@ -404,6 +407,18 @@ class KvmdServer(HttpServer): # pylint: disable=too-many-arguments,too-many-ins for (key, value) in state.items(): await self._broadcast_ws_event(f"info_{key}_state", value, legacy=True) + async def __poll_msd_state(self, poller: AsyncGenerator[dict, None]) -> None: + prev: dict = {"storage": None} + async for state in poller: + await self._broadcast_ws_event(self.__EV_MSD_STATE, state, legacy=False) + prev_storage = prev["storage"] + prev.update(state) + if prev["storage"] is not None and prev_storage is not None: + prev_storage.update(prev["storage"]) + prev["storage"] = prev_storage + if "online" in prev: # Complete/Full + await self._broadcast_ws_event(self.__EV_MSD_STATE, prev, legacy=True) + async def __poll_streamer_state(self, poller: AsyncGenerator[dict, None]) -> None: prev: dict = {} async for state in poller: diff --git a/kvmd/plugins/msd/otg/__init__.py b/kvmd/plugins/msd/otg/__init__.py index fca18e7b..6d0dd776 100644 --- a/kvmd/plugins/msd/otg/__init__.py +++ b/kvmd/plugins/msd/otg/__init__.py @@ -171,6 +171,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes async with self.__state._lock: # pylint: disable=protected-access storage: (dict | None) = None if self.__state.storage: + assert self.__state.vd storage = dataclasses.asdict(self.__state.storage) for name in list(storage["images"]): del storage["images"][name]["name"] @@ -179,21 +180,19 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes for name in list(storage["parts"]): del storage["parts"][name]["name"] - storage["size"] = storage["parts"][""]["size"] # Legacy API - storage["free"] = storage["parts"][""]["free"] # Legacy API - storage["downloading"] = (self.__reader.get_state() if self.__reader else None) storage["uploading"] = (self.__writer.get_state() if self.__writer else None) vd: (dict | None) = None if self.__state.vd: + assert self.__state.storage vd = dataclasses.asdict(self.__state.vd) if vd["image"]: del vd["image"]["path"] return { "enabled": True, - "online": (bool(self.__state.vd) and self.__drive.is_enabled()), + "online": (bool(vd) and self.__drive.is_enabled()), "busy": self.__state.is_busy(), "storage": storage, "drive": vd, @@ -208,9 +207,22 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes if (await self.__notifier.wait()) > 0: prev = {} new = await self.get_state() - if new != prev: + if not prev or (prev.get("online") != new["online"]): prev = copy.deepcopy(new) yield new + else: + diff: dict = {} + for sub in ["busy", "drive"]: + if prev.get(sub) != new[sub]: + diff[sub] = new[sub] + for sub in ["images", "parts", "downloading", "uploading"]: + if (prev.get("storage") or {}).get(sub) != (new["storage"] or {}).get(sub): + if "storage" not in diff: + diff["storage"] = {} + diff["storage"][sub] = new["storage"][sub] + if diff: + prev = copy.deepcopy(new) + yield diff @aiotools.atomic_fg async def reset(self) -> None: |