From 082a4787f99239695a4759caa74e8df59b825fdc Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Wed, 11 Jun 2025 12:32:26 -0400 Subject: [PATCH 1/5] Implement new API methods --- nanokvm/client.py | 41 ++++++++++++++++++++++++++++++++++++----- nanokvm/models.py | 23 +++++++++++++++++++++-- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/nanokvm/client.py b/nanokvm/client.py index 7bf29c9..cb45d05 100644 --- a/nanokvm/client.py +++ b/nanokvm/client.py @@ -31,10 +31,11 @@ GetMdnsStateRsp, GetMemoryLimitRsp, GetMountedImageRsp, + GetMouseJigglerModeRsp, GetOLEDRsp, GetPreviewRsp, GetSSHStateRsp, - GetSwapStateRsp, + GetSwapSizeRsp, GetTailscaleStatusRsp, GetVersionRsp, GetVirtualDeviceRsp, @@ -46,12 +47,15 @@ LoginReq, LoginRsp, MountImageReq, + MouseJigglerMode, PasteReq, SetGpioReq, SetHidModeReq, SetMemoryLimitReq, + SetMouseJigglerModeReq, SetOledReq, SetPreviewReq, + SetSwapSizeReq, StatusImageRsp, UpdateVirtualDeviceReq, UpdateVirtualDeviceRsp, @@ -305,12 +309,19 @@ async def get_ssh_state(self) -> GetSSHStateRsp: response_model=GetSSHStateRsp, ) - async def get_swap_state(self) -> GetSwapStateRsp: - """Get Swap enabled state.""" - return await self._api_request_json( + async def get_swap_size(self) -> int: + """Get Swap size.""" + rsp = await self._api_request_json( hdrs.METH_GET, "/vm/swap", - response_model=GetSwapStateRsp, + response_model=GetSwapSizeRsp, + ) + return rsp.size + + async def set_swap_size(self, size_mb: int) -> None: + """Set the Swap size.""" + await self._api_request_json( + hdrs.METH_POST, "/vm/swap", data=SetSwapSizeReq(size=size_mb) ) async def get_mdns_state(self) -> GetMdnsStateRsp: @@ -608,3 +619,23 @@ async def tailscale_stop(self) -> None: async def tailscale_restart(self) -> None: """Perform a Tailscale action: restart.""" await self._api_request_json(hdrs.METH_POST, "/extensions/tailscale/restart") + + async def mouse_jiggler_state(self) -> GetMouseJigglerModeRsp: + """Get the mouse jiggler state.""" + return await self._api_request_json( + hdrs.METH_GET, + "/vm/mouse-jiggler", + response_model=GetMouseJigglerModeRsp, + ) + + async def mouse_jiggler_enable(self, mode: MouseJigglerMode) -> None: + """Enable the mouse jiggler.""" + await self._api_request_json( + hdrs.METH_POST, + "/vm/mouse-jiggler/enable", + data=SetMouseJigglerModeReq(mode=mode), + ) + + async def mouse_jiggler_disable(self) -> None: + """Disable the mouse jiggler.""" + await self._api_request_json(hdrs.METH_POST, "/vm/mouse-jiggler/disable") diff --git a/nanokvm/models.py b/nanokvm/models.py index af2ebcc..986359c 100644 --- a/nanokvm/models.py +++ b/nanokvm/models.py @@ -94,6 +94,13 @@ class HWVersion(StrEnum): UNKNOWN = "Unknown" +class MouseJigglerMode(StrEnum): + """Mouse Jiggler Modes.""" + + ABSOLUTE = "absolute" + RELATIVE = "relative" + + # Generic Response Wrapper class ApiResponse(BaseModel, Generic[T]): """Generic API response structure.""" @@ -199,8 +206,12 @@ class GetSSHStateRsp(BaseModel): enabled: bool -class GetSwapStateRsp(BaseModel): - enabled: bool | None = None +class GetSwapSizeRsp(BaseModel): + size: int + + +class SetSwapSizeReq(BaseModel): + size: int class GetMdnsStateRsp(BaseModel): @@ -296,3 +307,11 @@ class StatusImageRsp(BaseModel): class DownloadImageReq(BaseModel): file: str # URL of the image to download # cdrom field is ignored for downloads + + +class SetMouseJigglerModeReq(BaseModel): + mode: MouseJigglerMode + + +class GetMouseJigglerModeRsp(BaseModel): + mode: MouseJigglerMode From 4350ea18f0909bcbd1d4e11b3d473112862b86ec Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Wed, 11 Jun 2025 12:36:24 -0400 Subject: [PATCH 2/5] A few more --- nanokvm/client.py | 11 ++++++++++- nanokvm/models.py | 4 ++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/nanokvm/client.py b/nanokvm/client.py index cb45d05..cfb0af2 100644 --- a/nanokvm/client.py +++ b/nanokvm/client.py @@ -26,6 +26,7 @@ GetCdRomRsp, GetGpioRsp, GetHardwareRsp, + GetHdmiStateRsp, GetHidModeRsp, GetInfoRsp, GetMdnsStateRsp, @@ -572,8 +573,16 @@ async def reboot_system(self) -> None: """Reboot the KVM device.""" await self._api_request_json(hdrs.METH_POST, "/vm/system/reboot") + async def get_hdmi_state(self) -> GetHdmiStateRsp: + """Get the HDMI state.""" + return await self._api_request_json( + hdrs.METH_GET, + "/vm/hdmi", + response_model=GetHdmiStateRsp, + ) + async def reset_hdmi(self) -> None: - """Reset the HDMI connection (relevant for PCIe version).""" + """Reset the HDMI connection.""" await self._api_request_json(hdrs.METH_POST, "/vm/hdmi/reset") async def reset_hid(self) -> None: diff --git a/nanokvm/models.py b/nanokvm/models.py index 986359c..678f772 100644 --- a/nanokvm/models.py +++ b/nanokvm/models.py @@ -315,3 +315,7 @@ class SetMouseJigglerModeReq(BaseModel): class GetMouseJigglerModeRsp(BaseModel): mode: MouseJigglerMode + + +class GetHdmiStateRsp(BaseModel): + enabled: bool From 317726b9b868e47a3f4ada2987df4d453e75b1a8 Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Wed, 11 Jun 2025 12:40:02 -0400 Subject: [PATCH 3/5] Fix mouse jiggler models --- nanokvm/client.py | 22 ++++++++++------------ nanokvm/models.py | 6 ++++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/nanokvm/client.py b/nanokvm/client.py index cfb0af2..7bbb109 100644 --- a/nanokvm/client.py +++ b/nanokvm/client.py @@ -32,7 +32,7 @@ GetMdnsStateRsp, GetMemoryLimitRsp, GetMountedImageRsp, - GetMouseJigglerModeRsp, + GetMouseJigglerRsp, GetOLEDRsp, GetPreviewRsp, GetSSHStateRsp, @@ -53,7 +53,7 @@ SetGpioReq, SetHidModeReq, SetMemoryLimitReq, - SetMouseJigglerModeReq, + SetMouseJigglerReq, SetOledReq, SetPreviewReq, SetSwapSizeReq, @@ -629,22 +629,20 @@ async def tailscale_restart(self) -> None: """Perform a Tailscale action: restart.""" await self._api_request_json(hdrs.METH_POST, "/extensions/tailscale/restart") - async def mouse_jiggler_state(self) -> GetMouseJigglerModeRsp: + async def mouse_jiggler_state(self) -> GetMouseJigglerRsp: """Get the mouse jiggler state.""" return await self._api_request_json( hdrs.METH_GET, "/vm/mouse-jiggler", - response_model=GetMouseJigglerModeRsp, + response_model=GetMouseJigglerRsp, ) - async def mouse_jiggler_enable(self, mode: MouseJigglerMode) -> None: - """Enable the mouse jiggler.""" + async def set_mouse_jiggler_state( + self, enabled: bool, mode: MouseJigglerMode + ) -> None: + """Set the mouse jiggler state.""" await self._api_request_json( hdrs.METH_POST, - "/vm/mouse-jiggler/enable", - data=SetMouseJigglerModeReq(mode=mode), + "/vm/mouse-jiggler", + data=SetMouseJigglerReq(enabled=enabled, mode=mode), ) - - async def mouse_jiggler_disable(self) -> None: - """Disable the mouse jiggler.""" - await self._api_request_json(hdrs.METH_POST, "/vm/mouse-jiggler/disable") diff --git a/nanokvm/models.py b/nanokvm/models.py index 678f772..4881929 100644 --- a/nanokvm/models.py +++ b/nanokvm/models.py @@ -309,11 +309,13 @@ class DownloadImageReq(BaseModel): # cdrom field is ignored for downloads -class SetMouseJigglerModeReq(BaseModel): +class SetMouseJigglerReq(BaseModel): + enabled: bool mode: MouseJigglerMode -class GetMouseJigglerModeRsp(BaseModel): +class GetMouseJigglerRsp(BaseModel): + enabled: bool mode: MouseJigglerMode From 78c7ca7839a230745add776ecf77b293fc3be25f Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Wed, 11 Jun 2025 12:40:10 -0400 Subject: [PATCH 4/5] Add methods to enable and disable HDMI --- nanokvm/client.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nanokvm/client.py b/nanokvm/client.py index 7bbb109..2f12153 100644 --- a/nanokvm/client.py +++ b/nanokvm/client.py @@ -585,6 +585,14 @@ async def reset_hdmi(self) -> None: """Reset the HDMI connection.""" await self._api_request_json(hdrs.METH_POST, "/vm/hdmi/reset") + async def enable_hdmi(self) -> None: + """Enable the HDMI connection.""" + await self._api_request_json(hdrs.METH_POST, "/vm/hdmi/enable") + + async def disable_hdmi(self) -> None: + """Disable the HDMI connection.""" + await self._api_request_json(hdrs.METH_POST, "/vm/hdmi/disable") + async def reset_hid(self) -> None: """Reset the HID subsystem.""" await self._api_request_json(hdrs.METH_POST, "/hid/reset") From fe1423e6b877559934095225da94e37db006aeff Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Wed, 11 Jun 2025 12:49:42 -0400 Subject: [PATCH 5/5] Rename `mouse_jiggler_state` to `get_mouse_jiggler_state` --- nanokvm/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nanokvm/client.py b/nanokvm/client.py index 2f12153..af56d3e 100644 --- a/nanokvm/client.py +++ b/nanokvm/client.py @@ -637,7 +637,7 @@ async def tailscale_restart(self) -> None: """Perform a Tailscale action: restart.""" await self._api_request_json(hdrs.METH_POST, "/extensions/tailscale/restart") - async def mouse_jiggler_state(self) -> GetMouseJigglerRsp: + async def get_mouse_jiggler_state(self) -> GetMouseJigglerRsp: """Get the mouse jiggler state.""" return await self._api_request_json( hdrs.METH_GET,