summaryrefslogtreecommitdiff
path: root/kvmd
diff options
context:
space:
mode:
Diffstat (limited to 'kvmd')
-rw-r--r--kvmd/apps/kvmd/api/msd.py6
-rw-r--r--kvmd/apps/kvmd/server.py17
-rw-r--r--kvmd/plugins/msd/otg/__init__.py22
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: