From f027654ad1e2d221318d28b4e318d0caf3f7a06d Mon Sep 17 00:00:00 2001 From: No0ne Date: Thu, 28 Mar 2024 18:35:08 +0100 Subject: [PATCH 01/30] bump to ps2x2pico-1.0 pre-release (#164) --- hid/pico/Makefile | 2 +- hid/pico/src/ph_ps2.c | 20 ++++++++++---------- hid/pico/src/ph_ps2.h | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/hid/pico/Makefile b/hid/pico/Makefile index b335228b..0130895e 100644 --- a/hid/pico/Makefile +++ b/hid/pico/Makefile @@ -31,7 +31,7 @@ endef .tinyusb: $(call libdep,tinyusb,hathach/tinyusb,d713571cd44f05d2fc72efc09c670787b74106e0) .ps2x2pico: - $(call libdep,ps2x2pico,No0ne/ps2x2pico,b90814df40ebbc0f42c2886b4bd17b20a177a4da) + $(call libdep,ps2x2pico,No0ne/ps2x2pico,b28bef9743632a56db48f14175aacf7bb23dbd07) deps: .pico-sdk .tinyusb .ps2x2pico diff --git a/hid/pico/src/ph_ps2.c b/hid/pico/src/ph_ps2.c index 5eb07174..ef192249 100644 --- a/hid/pico/src/ph_ps2.c +++ b/hid/pico/src/ph_ps2.c @@ -105,34 +105,34 @@ void ph_ps2_mouse_send_button(u8 button, bool state) { ph_ps2_mouse_buttons = ph_ps2_mouse_buttons & ~(1 << button); } - ms_send_packet(ph_ps2_mouse_buttons, 0, 0, 0, 0); + ms_send_movement(ph_ps2_mouse_buttons, 0, 0, 0); } } void ph_ps2_mouse_send_rel(s8 x, s8 y) { if (PH_O_IS_MOUSE_PS2) { - ms_send_packet(ph_ps2_mouse_buttons, x, y, 0, 0); + ms_send_movement(ph_ps2_mouse_buttons, x, y, 0); } } void ph_ps2_mouse_send_wheel(s8 h, s8 v) { if (PH_O_IS_MOUSE_PS2) { - ms_send_packet(ph_ps2_mouse_buttons, 0, 0, h, v); + ms_send_movement(ph_ps2_mouse_buttons, 0, 0, v); } } void ph_ps2_send_clear(void) { if (PH_O_IS_KBD_PS2) { - for(u8 key = 0xe0; key <= 0xe7; key++) { - kb_send_key(key, false, 0); - } + //for(u8 key = 0xe0; key <= 0xe7; key++) { + // kb_send_key(key, false, 0); + //} - for(u8 key = 4; key <= 116; key++) { - kb_send_key(key, false, 0); - } + //for(u8 key = 4; key <= 116; key++) { + // kb_send_key(key, false, 0); + //} } if (PH_O_IS_MOUSE_PS2) { - ms_send_packet(0, 0, 0, 0, 0); + ms_send_movement(0, 0, 0, 0); } } diff --git a/hid/pico/src/ph_ps2.h b/hid/pico/src/ph_ps2.h index 62fee109..af8012bc 100644 --- a/hid/pico/src/ph_ps2.h +++ b/hid/pico/src/ph_ps2.h @@ -41,7 +41,7 @@ void ph_ps2_kbd_send_key(u8 key, bool state); void ms_init(u8 gpio); bool ms_task(); -void ms_send_packet(u8 buttons, s8 x, s8 y, s8 h, s8 v); +void ms_send_movement(u8 buttons, s8 x, s8 y, s8 z); void ph_ps2_mouse_send_button(u8 button, bool state); void ph_ps2_mouse_send_rel(s8 x, s8 y); void ph_ps2_mouse_send_wheel(s8 h, s8 v); From 13f23a19c306b2704b4e7d6ed5c107eee7587eee Mon Sep 17 00:00:00 2001 From: No0ne Date: Mon, 20 May 2024 15:36:54 +0200 Subject: [PATCH 02/30] bump to ps2x2pico-1.1 (#167) --- hid/pico/Makefile | 2 +- hid/pico/src/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/hid/pico/Makefile b/hid/pico/Makefile index 0130895e..7b51b319 100644 --- a/hid/pico/Makefile +++ b/hid/pico/Makefile @@ -31,7 +31,7 @@ endef .tinyusb: $(call libdep,tinyusb,hathach/tinyusb,d713571cd44f05d2fc72efc09c670787b74106e0) .ps2x2pico: - $(call libdep,ps2x2pico,No0ne/ps2x2pico,b28bef9743632a56db48f14175aacf7bb23dbd07) + $(call libdep,ps2x2pico,No0ne/ps2x2pico,823260af57dcc55cf7cb96241346f51c065126de) deps: .pico-sdk .tinyusb .ps2x2pico diff --git a/hid/pico/src/CMakeLists.txt b/hid/pico/src/CMakeLists.txt index 904e7b7f..a8d86dc0 100644 --- a/hid/pico/src/CMakeLists.txt +++ b/hid/pico/src/CMakeLists.txt @@ -18,6 +18,7 @@ target_sources(${target_name} PRIVATE ${PS2_PATH}/ps2phy.c ${PS2_PATH}/ps2kb.c ${PS2_PATH}/ps2ms.c + ${PS2_PATH}/scancodesets.c ) target_link_options(${target_name} PRIVATE -Xlinker --print-memory-usage) target_compile_options(${target_name} PRIVATE -Wall -Wextra) From 5bdc9989222ce0344d773a64f8913f0149c14af4 Mon Sep 17 00:00:00 2001 From: No0ne Date: Fri, 19 Jul 2024 14:05:57 +0200 Subject: [PATCH 03/30] ps2: keyboard+mouse passthru support (#171) --- hid/pico/Makefile | 2 +- hid/pico/src/CMakeLists.txt | 6 ++++-- hid/pico/src/ph_ps2.c | 6 ++++-- hid/pico/src/ph_ps2.h | 4 ++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/hid/pico/Makefile b/hid/pico/Makefile index 7b51b319..42002cb0 100644 --- a/hid/pico/Makefile +++ b/hid/pico/Makefile @@ -31,7 +31,7 @@ endef .tinyusb: $(call libdep,tinyusb,hathach/tinyusb,d713571cd44f05d2fc72efc09c670787b74106e0) .ps2x2pico: - $(call libdep,ps2x2pico,No0ne/ps2x2pico,823260af57dcc55cf7cb96241346f51c065126de) + $(call libdep,ps2x2pico,No0ne/ps2x2pico,27c9bcede3370f0d4fdefea9c86a0eeb6170cf77) deps: .pico-sdk .tinyusb .ps2x2pico diff --git a/hid/pico/src/CMakeLists.txt b/hid/pico/src/CMakeLists.txt index a8d86dc0..7eeffa18 100644 --- a/hid/pico/src/CMakeLists.txt +++ b/hid/pico/src/CMakeLists.txt @@ -15,7 +15,8 @@ target_sources(${target_name} PRIVATE ph_com_uart.c ph_debug.c - ${PS2_PATH}/ps2phy.c + ${PS2_PATH}/ps2out.c + ${PS2_PATH}/ps2in.c ${PS2_PATH}/ps2kb.c ${PS2_PATH}/ps2ms.c ${PS2_PATH}/scancodesets.c @@ -24,7 +25,8 @@ target_link_options(${target_name} PRIVATE -Xlinker --print-memory-usage) target_compile_options(${target_name} PRIVATE -Wall -Wextra) target_include_directories(${target_name} PRIVATE ${CMAKE_CURRENT_LIST_DIR} ${PS2_PATH}) -pico_generate_pio_header(${target_name} ${PS2_PATH}/ps2phy.pio) +pico_generate_pio_header(${target_name} ${PS2_PATH}/ps2out.pio) +pico_generate_pio_header(${target_name} ${PS2_PATH}/ps2in.pio) target_link_libraries(${target_name} PRIVATE pico_stdlib diff --git a/hid/pico/src/ph_ps2.c b/hid/pico/src/ph_ps2.c index ef192249..c4499f13 100644 --- a/hid/pico/src/ph_ps2.c +++ b/hid/pico/src/ph_ps2.c @@ -32,6 +32,8 @@ #define _KBD_DATA_PIN 11 // CLK == 12 #define _MOUSE_DATA_PIN 14 // CLK == 15 +#define _KBD_IN_DATA_PIN 26 // passthru, CLK == 27 +#define _MOUSE_IN_DATA_PIN 16 // passthru, CLK == 17 u8 ph_g_ps2_kbd_leds = 0; bool ph_g_ps2_kbd_online = 0; @@ -57,13 +59,13 @@ void ph_ps2_init(void) { } if (PH_O_IS_KBD_PS2) { - kb_init(_KBD_DATA_PIN); + kb_init(_KBD_DATA_PIN, _KBD_IN_DATA_PIN); } else { INIT_STUB(_KBD_DATA_PIN); } if (PH_O_IS_MOUSE_PS2) { - ms_init(_MOUSE_DATA_PIN); + ms_init(_MOUSE_DATA_PIN, _MOUSE_IN_DATA_PIN); } else { INIT_STUB(_MOUSE_DATA_PIN); } diff --git a/hid/pico/src/ph_ps2.h b/hid/pico/src/ph_ps2.h index af8012bc..69f55866 100644 --- a/hid/pico/src/ph_ps2.h +++ b/hid/pico/src/ph_ps2.h @@ -34,12 +34,12 @@ void ph_ps2_init(void); void ph_ps2_task(void); void tuh_kb_set_leds(u8 leds); -void kb_init(u8 gpio); +void kb_init(u8 gpio_out, u8 gpio_in); bool kb_task(); void kb_send_key(u8 key, bool state, u8 modifiers); void ph_ps2_kbd_send_key(u8 key, bool state); -void ms_init(u8 gpio); +void ms_init(u8 gpio_out, u8 gpio_in); bool ms_task(); void ms_send_movement(u8 buttons, s8 x, s8 y, s8 z); void ph_ps2_mouse_send_button(u8 button, bool state); From d082f05e7ad20980d12c930cca807565f8547546 Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Sun, 31 Mar 2024 14:02:33 +0300 Subject: [PATCH 04/30] improved kvmd-udev-restart-pass --- PKGBUILD | 3 +++ scripts/kvmd-udev-restart-pass | 5 ++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/PKGBUILD b/PKGBUILD index efa54d74..c30d365b 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -114,6 +114,9 @@ depends=( # fsck for /boot dosfstools + # pgrep for kvmd-udev-restart-pass + procps-ng + # Misc hostapd ) diff --git a/scripts/kvmd-udev-restart-pass b/scripts/kvmd-udev-restart-pass index addf4bc2..760267eb 100755 --- a/scripts/kvmd-udev-restart-pass +++ b/scripts/kvmd-udev-restart-pass @@ -45,9 +45,8 @@ if [ "$port" = "HDMI-A-1" ]; then if systemctl is-enabled -q kvmd-pass; then systemctl restart kvmd-pass || true fi - pid=$(pidof ustreamer || echo 0) - if [ "$pid" -ne 0 ]; then + for pid in $(pgrep -f '^kvmd/streamer: ' || true); do kill "$pid" || true - fi + done fi fi From 968a07335f651798684935d2a11754edabcbc1c5 Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Tue, 2 Apr 2024 13:29:53 +0300 Subject: [PATCH 05/30] removed deprecated streamer option --last-as-blank --- configs/kvmd/main/v0-hdmi-rpi2.yaml | 1 - configs/kvmd/main/v0-hdmi-rpi3.yaml | 1 - configs/kvmd/main/v0-hdmi-zero2w.yaml | 1 - configs/kvmd/main/v0-hdmiusb-rpi2.yaml | 1 - configs/kvmd/main/v0-hdmiusb-rpi3.yaml | 1 - configs/kvmd/main/v0-hdmiusb-zero2w.yaml | 1 - configs/kvmd/main/v1-hdmi-rpi2.yaml | 1 - configs/kvmd/main/v1-hdmi-rpi3.yaml | 1 - configs/kvmd/main/v1-hdmi-zero2w.yaml | 1 - configs/kvmd/main/v1-hdmiusb-rpi2.yaml | 1 - configs/kvmd/main/v1-hdmiusb-rpi3.yaml | 1 - configs/kvmd/main/v1-hdmiusb-zero2w.yaml | 1 - configs/kvmd/main/v2-hdmi-rpi3.yaml | 1 - configs/kvmd/main/v2-hdmi-rpi4.yaml | 1 - configs/kvmd/main/v2-hdmi-zero2w.yaml | 1 - configs/kvmd/main/v2-hdmiusb-generic.yaml | 1 - configs/kvmd/main/v2-hdmiusb-rpi4.yaml | 1 - configs/kvmd/main/v3-hdmi-rpi4.yaml | 1 - configs/kvmd/main/v4mini-hdmi-rpi4.yaml | 1 - configs/kvmd/main/v4plus-hdmi-rpi4.yaml | 1 - 20 files changed, 20 deletions(-) diff --git a/configs/kvmd/main/v0-hdmi-rpi2.yaml b/configs/kvmd/main/v0-hdmi-rpi2.yaml index b29fed6e..af763cd8 100644 --- a/configs/kvmd/main/v0-hdmi-rpi2.yaml +++ b/configs/kvmd/main/v0-hdmi-rpi2.yaml @@ -30,7 +30,6 @@ kvmd: - "--quality={quality}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v0-hdmi-rpi3.yaml b/configs/kvmd/main/v0-hdmi-rpi3.yaml index a67d871f..a44169e9 100644 --- a/configs/kvmd/main/v0-hdmi-rpi3.yaml +++ b/configs/kvmd/main/v0-hdmi-rpi3.yaml @@ -30,7 +30,6 @@ kvmd: - "--quality={quality}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v0-hdmi-zero2w.yaml b/configs/kvmd/main/v0-hdmi-zero2w.yaml index 05dec2de..96e89761 100644 --- a/configs/kvmd/main/v0-hdmi-zero2w.yaml +++ b/configs/kvmd/main/v0-hdmi-zero2w.yaml @@ -32,7 +32,6 @@ kvmd: - "--quality={quality}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v0-hdmiusb-rpi2.yaml b/configs/kvmd/main/v0-hdmiusb-rpi2.yaml index 62ede331..b265935d 100644 --- a/configs/kvmd/main/v0-hdmiusb-rpi2.yaml +++ b/configs/kvmd/main/v0-hdmiusb-rpi2.yaml @@ -42,7 +42,6 @@ kvmd: - "--resolution={resolution}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v0-hdmiusb-rpi3.yaml b/configs/kvmd/main/v0-hdmiusb-rpi3.yaml index caf1b2df..54a55bb5 100644 --- a/configs/kvmd/main/v0-hdmiusb-rpi3.yaml +++ b/configs/kvmd/main/v0-hdmiusb-rpi3.yaml @@ -42,7 +42,6 @@ kvmd: - "--resolution={resolution}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v0-hdmiusb-zero2w.yaml b/configs/kvmd/main/v0-hdmiusb-zero2w.yaml index caf1b2df..54a55bb5 100644 --- a/configs/kvmd/main/v0-hdmiusb-zero2w.yaml +++ b/configs/kvmd/main/v0-hdmiusb-zero2w.yaml @@ -42,7 +42,6 @@ kvmd: - "--resolution={resolution}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v1-hdmi-rpi2.yaml b/configs/kvmd/main/v1-hdmi-rpi2.yaml index d770616b..af85f99b 100644 --- a/configs/kvmd/main/v1-hdmi-rpi2.yaml +++ b/configs/kvmd/main/v1-hdmi-rpi2.yaml @@ -39,7 +39,6 @@ kvmd: - "--quality={quality}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v1-hdmi-rpi3.yaml b/configs/kvmd/main/v1-hdmi-rpi3.yaml index 53d509d2..e8e442f3 100644 --- a/configs/kvmd/main/v1-hdmi-rpi3.yaml +++ b/configs/kvmd/main/v1-hdmi-rpi3.yaml @@ -41,7 +41,6 @@ kvmd: - "--quality={quality}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v1-hdmi-zero2w.yaml b/configs/kvmd/main/v1-hdmi-zero2w.yaml index 53d509d2..e8e442f3 100644 --- a/configs/kvmd/main/v1-hdmi-zero2w.yaml +++ b/configs/kvmd/main/v1-hdmi-zero2w.yaml @@ -41,7 +41,6 @@ kvmd: - "--quality={quality}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v1-hdmiusb-rpi2.yaml b/configs/kvmd/main/v1-hdmiusb-rpi2.yaml index e8506a26..09c6b4a8 100644 --- a/configs/kvmd/main/v1-hdmiusb-rpi2.yaml +++ b/configs/kvmd/main/v1-hdmiusb-rpi2.yaml @@ -51,7 +51,6 @@ kvmd: - "--resolution={resolution}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v1-hdmiusb-rpi3.yaml b/configs/kvmd/main/v1-hdmiusb-rpi3.yaml index 1f2418b6..d3d9d7fd 100644 --- a/configs/kvmd/main/v1-hdmiusb-rpi3.yaml +++ b/configs/kvmd/main/v1-hdmiusb-rpi3.yaml @@ -51,7 +51,6 @@ kvmd: - "--resolution={resolution}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v1-hdmiusb-zero2w.yaml b/configs/kvmd/main/v1-hdmiusb-zero2w.yaml index 1f2418b6..d3d9d7fd 100644 --- a/configs/kvmd/main/v1-hdmiusb-zero2w.yaml +++ b/configs/kvmd/main/v1-hdmiusb-zero2w.yaml @@ -51,7 +51,6 @@ kvmd: - "--resolution={resolution}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v2-hdmi-rpi3.yaml b/configs/kvmd/main/v2-hdmi-rpi3.yaml index e74b4662..3bfc000f 100644 --- a/configs/kvmd/main/v2-hdmi-rpi3.yaml +++ b/configs/kvmd/main/v2-hdmi-rpi3.yaml @@ -32,7 +32,6 @@ kvmd: - "--quality={quality}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v2-hdmi-rpi4.yaml b/configs/kvmd/main/v2-hdmi-rpi4.yaml index 0b4687b3..ea3c8c10 100644 --- a/configs/kvmd/main/v2-hdmi-rpi4.yaml +++ b/configs/kvmd/main/v2-hdmi-rpi4.yaml @@ -33,7 +33,6 @@ kvmd: - "--quality={quality}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v2-hdmi-zero2w.yaml b/configs/kvmd/main/v2-hdmi-zero2w.yaml index e74b4662..3bfc000f 100644 --- a/configs/kvmd/main/v2-hdmi-zero2w.yaml +++ b/configs/kvmd/main/v2-hdmi-zero2w.yaml @@ -32,7 +32,6 @@ kvmd: - "--quality={quality}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v2-hdmiusb-generic.yaml b/configs/kvmd/main/v2-hdmiusb-generic.yaml index 46e8045a..400d6038 100644 --- a/configs/kvmd/main/v2-hdmiusb-generic.yaml +++ b/configs/kvmd/main/v2-hdmiusb-generic.yaml @@ -42,7 +42,6 @@ kvmd: - "--resolution={resolution}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v2-hdmiusb-rpi4.yaml b/configs/kvmd/main/v2-hdmiusb-rpi4.yaml index 0caad141..cd1e9a72 100644 --- a/configs/kvmd/main/v2-hdmiusb-rpi4.yaml +++ b/configs/kvmd/main/v2-hdmiusb-rpi4.yaml @@ -42,7 +42,6 @@ kvmd: - "--resolution={resolution}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v3-hdmi-rpi4.yaml b/configs/kvmd/main/v3-hdmi-rpi4.yaml index 34c8b982..50b140b0 100644 --- a/configs/kvmd/main/v3-hdmi-rpi4.yaml +++ b/configs/kvmd/main/v3-hdmi-rpi4.yaml @@ -37,7 +37,6 @@ kvmd: - "--quality={quality}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v4mini-hdmi-rpi4.yaml b/configs/kvmd/main/v4mini-hdmi-rpi4.yaml index 576075a8..410544d7 100644 --- a/configs/kvmd/main/v4mini-hdmi-rpi4.yaml +++ b/configs/kvmd/main/v4mini-hdmi-rpi4.yaml @@ -45,7 +45,6 @@ kvmd: - "--quality={quality}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" diff --git a/configs/kvmd/main/v4plus-hdmi-rpi4.yaml b/configs/kvmd/main/v4plus-hdmi-rpi4.yaml index dffdaf63..eb52b124 100644 --- a/configs/kvmd/main/v4plus-hdmi-rpi4.yaml +++ b/configs/kvmd/main/v4plus-hdmi-rpi4.yaml @@ -46,7 +46,6 @@ kvmd: - "--quality={quality}" - "--desired-fps={desired_fps}" - "--drop-same-frames=30" - - "--last-as-blank=0" - "--unix={unix}" - "--unix-rm" - "--unix-mode=0660" From 7e0301637b40ee1859177ba0b9c5180d75d20d08 Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Sat, 6 Apr 2024 21:52:34 +0300 Subject: [PATCH 06/30] edidconf presets --- PKGBUILD | 2 +- configs/kvmd/edid/_1080p-by-default.hex | 16 ++++++ configs/kvmd/edid/_no-1920x1200.hex | 16 ++++++ configs/kvmd/edid/{v0-hdmi.hex => v0.hex} | 0 configs/kvmd/edid/{v1-hdmi.hex => v1.hex} | 0 configs/kvmd/edid/{v2-hdmi.hex => v2.hex} | 0 configs/kvmd/edid/{v3-hdmi.hex => v3.hex} | 0 .../kvmd/edid/{v4mini-hdmi.hex => v4mini.hex} | 0 .../kvmd/edid/{v4plus-hdmi.hex => v4plus.hex} | 0 kvmd/apps/edidconf/__init__.py | 54 +++++++++++++------ 10 files changed, 71 insertions(+), 17 deletions(-) create mode 100644 configs/kvmd/edid/_1080p-by-default.hex create mode 100644 configs/kvmd/edid/_no-1920x1200.hex rename configs/kvmd/edid/{v0-hdmi.hex => v0.hex} (100%) rename configs/kvmd/edid/{v1-hdmi.hex => v1.hex} (100%) rename configs/kvmd/edid/{v2-hdmi.hex => v2.hex} (100%) rename configs/kvmd/edid/{v3-hdmi.hex => v3.hex} (100%) rename configs/kvmd/edid/{v4mini-hdmi.hex => v4mini.hex} (100%) rename configs/kvmd/edid/{v4plus-hdmi.hex => v4plus.hex} (100%) diff --git a/PKGBUILD b/PKGBUILD index c30d365b..d7360e53 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -248,7 +248,7 @@ for _variant in "${_variants[@]}"; do if [[ $_platform =~ ^.*-hdmi$ ]]; then backup=(\"\${backup[@]}\" etc/kvmd/tc358743-edid.hex) - install -DTm444 configs/kvmd/edid/$_platform.hex \"\$pkgdir/etc/kvmd/tc358743-edid.hex\" + install -DTm444 configs/kvmd/edid/$_base.hex \"\$pkgdir/etc/kvmd/tc358743-edid.hex\" fi mkdir -p \"\$pkgdir/usr/share/kvmd\" diff --git a/configs/kvmd/edid/_1080p-by-default.hex b/configs/kvmd/edid/_1080p-by-default.hex new file mode 100644 index 00000000..f4238bec --- /dev/null +++ b/configs/kvmd/edid/_1080p-by-default.hex @@ -0,0 +1,16 @@ +00FFFFFFFFFFFF0031D8717701010101 +231A010380351E780E0565A756529C27 +0F50543FED00B300A9C0950090408180 +814081C0714FEE2C80A070381A403020 +3500404421000002000000FF00434146 +45424142452020202020000000FD0032 +4B0F5211000A202020202020000000FC +0050694B564D2056330A20202020012B +020317314A049F13223E213D203C0167 +030C001000802DEE2C80A070381A4030 +203500404421000002011D007251D01E +206E2835000F282100001E0000000000 +00000000000000000000000000000000 +00000000000000000000000000000000 +00000000000000000000000000000000 +000000000000000000000000000000CD diff --git a/configs/kvmd/edid/_no-1920x1200.hex b/configs/kvmd/edid/_no-1920x1200.hex new file mode 100644 index 00000000..c89278e5 --- /dev/null +++ b/configs/kvmd/edid/_no-1920x1200.hex @@ -0,0 +1,16 @@ +00FFFFFFFFFFFF0031D8737701010101 +231A010380351E780E0565A756529C27 +0F50543FED00B300A9C0950090408180 +814081C0714F023A801871382D40582C +45000F282100001E000000FF00434146 +45424142452020202020000000FD0032 +4B0F5211000A202020202020000000FC +0050694B564D20563420506C7573012D +020320714B90041F13223E213D203C01 +67030C001000802D23097F0783010000 +023A801871382D40582C45000F282100 +001E011D007251D01E206E2855000F28 +2100001E023A80D072382D40102C4580 +0F282100001E00000000000000000000 +00000000000000000000000000000000 +00000000000000000000000000000042 diff --git a/configs/kvmd/edid/v0-hdmi.hex b/configs/kvmd/edid/v0.hex similarity index 100% rename from configs/kvmd/edid/v0-hdmi.hex rename to configs/kvmd/edid/v0.hex diff --git a/configs/kvmd/edid/v1-hdmi.hex b/configs/kvmd/edid/v1.hex similarity index 100% rename from configs/kvmd/edid/v1-hdmi.hex rename to configs/kvmd/edid/v1.hex diff --git a/configs/kvmd/edid/v2-hdmi.hex b/configs/kvmd/edid/v2.hex similarity index 100% rename from configs/kvmd/edid/v2-hdmi.hex rename to configs/kvmd/edid/v2.hex diff --git a/configs/kvmd/edid/v3-hdmi.hex b/configs/kvmd/edid/v3.hex similarity index 100% rename from configs/kvmd/edid/v3-hdmi.hex rename to configs/kvmd/edid/v3.hex diff --git a/configs/kvmd/edid/v4mini-hdmi.hex b/configs/kvmd/edid/v4mini.hex similarity index 100% rename from configs/kvmd/edid/v4mini-hdmi.hex rename to configs/kvmd/edid/v4mini.hex diff --git a/configs/kvmd/edid/v4plus-hdmi.hex b/configs/kvmd/edid/v4plus.hex similarity index 100% rename from configs/kvmd/edid/v4plus-hdmi.hex rename to configs/kvmd/edid/v4plus.hex diff --git a/kvmd/apps/edidconf/__init__.py b/kvmd/apps/edidconf/__init__.py index 141cc1a3..66136cb3 100644 --- a/kvmd/apps/edidconf/__init__.py +++ b/kvmd/apps/edidconf/__init__.py @@ -283,6 +283,21 @@ def _make_format_hex(size: int) -> Callable[[int], str]: return (lambda value: ("0x{:0%dX} ({})" % (size * 2)).format(value, value)) +def _print_edid(edid: _Edid) -> None: + for (key, get, fmt) in [ + ("Manufacturer ID:", edid.get_mfc_id, str), + ("Product ID: ", edid.get_product_id, _make_format_hex(2)), + ("Serial number: ", edid.get_serial, _make_format_hex(4)), + ("Monitor name: ", edid.get_monitor_name, str), + ("Monitor serial: ", edid.get_monitor_serial, str), + ("Audio: ", edid.get_audio, _format_bool), + ]: + try: + print(key, fmt(get()), file=sys.stderr) # type: ignore + except NoBlockError: + pass + + # ===== def main(argv: (list[str] | None)=None) -> None: # pylint: disable=too-many-branches,too-many-statements # (parent_parser, argv, _) = init( @@ -296,6 +311,11 @@ def main(argv: (list[str] | None)=None) -> None: # pylint: disable=too-many-bra description="A simple and primitive KVMD EDID editor", # parents=[parent_parser], ) + + lane2 = ["v0", "v1", "v2", "v3"] + lane4 = ["v4mini", "v4plus"] + presets = lane2 + lane4 + [f"{name}.1080p-by-default" for name in lane2] + [f"{name}.no-1920x1200" for name in lane4] + parser.add_argument("-f", "--edid", dest="edid_path", default="/etc/kvmd/tc358743-edid.hex", help="The hex/bin EDID file path", metavar="") parser.add_argument("--export-hex", @@ -304,8 +324,8 @@ def main(argv: (list[str] | None)=None) -> None: # pylint: disable=too-many-bra help="Export [--edid] file to the new file as a bin data", metavar="") parser.add_argument("--import", dest="imp", help="Import the specified bin/hex EDID to the [--edid] file as a hex text", metavar="") - parser.add_argument("--restore-default", choices=["v0", "v1", "v2", "v3", "v4mini", "v4plus"], - help="Restore default edid for the given PiKVM build") + parser.add_argument("--import-preset", choices=presets, + help="Restore default EDID or choose the preset", metavar=f"{{ {' | '.join(presets)} }}",) parser.add_argument("--set-audio", type=valid_bool, help="Enable or disable audio", metavar="") parser.add_argument("--set-mfc-id", @@ -324,10 +344,18 @@ def main(argv: (list[str] | None)=None) -> None: # pylint: disable=too-many-bra help="Apply [--edid] on the [--device]") parser.add_argument("--device", dest="device_path", default="/dev/kvmd-video", help="The video device", metavar="") + parser.add_argument("--presets", dest="presets_path", default="/usr/share/kvmd/configs.default/kvmd/edid", + help="Presets directory", metavar="") options = parser.parse_args(argv[1:]) - if options.restore_default: - options.imp = f"/usr/share/kvmd/configs.default/kvmd/edid/{options.restore_default}-hdmi.hex" + base: (_Edid | None) = None + if options.import_preset: + imp = options.import_preset + if "." in imp: + (base_name, imp) = imp.split(".", 1) # v3.1080p-by-default + base = _Edid(os.path.join(options.presets_path, f"{base_name}.hex")) + imp = f"_{imp}" + options.imp = os.path.join(options.presets_path, f"{imp}.hex") orig_edid_path = options.edid_path if options.imp: @@ -340,6 +368,11 @@ def main(argv: (list[str] | None)=None) -> None: # pylint: disable=too-many-bra for cmd in dir(_Edid): if cmd.startswith("set_"): value = getattr(options, cmd) + if value is None and base is not None: + try: + value = getattr(base, cmd.replace("set_", "get_"))() + except NoBlockError: + pass if value is not None: getattr(edid, cmd)(value) changed = True @@ -351,18 +384,7 @@ def main(argv: (list[str] | None)=None) -> None: # pylint: disable=too-many-bra elif changed: edid.write_hex(options.edid_path) - for (key, get, fmt) in [ - ("Manufacturer ID:", edid.get_mfc_id, str), - ("Product ID: ", edid.get_product_id, _make_format_hex(2)), - ("Serial number: ", edid.get_serial, _make_format_hex(4)), - ("Monitor name: ", edid.get_monitor_name, str), - ("Monitor serial: ", edid.get_monitor_serial, str), - ("Audio: ", edid.get_audio, _format_bool), - ]: - try: - print(key, fmt(get()), file=sys.stderr) # type: ignore - except NoBlockError: - pass + _print_edid(edid) try: if options.clear: From ddd4d292cdbaadb9e107bb48e6860abeb2232394 Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Sat, 6 Apr 2024 22:00:22 +0300 Subject: [PATCH 07/30] new sponsors --- web/kvm/index.html | 2 ++ web/kvm/window-about.pug | 2 ++ 2 files changed, 4 insertions(+) diff --git a/web/kvm/index.html b/web/kvm/index.html index 9fb79a28..ef4a8a21 100644 --- a/web/kvm/index.html +++ b/web/kvm/index.html @@ -2035,6 +2035,7 @@
  • AdamBomb
  • adipisicing
  • Adrian Basham
  • +
  • Adrian Popescu
  • Ahmed Syed
  • Alberto Bassi
  • alejandro
  • @@ -2200,6 +2201,7 @@
  • Egan Ford
  • Elani Ferri
  • Elliot Woo
  • +
  • Entt
  • Eric Phenix
  • Ethan Shold
  • Eugene Sukhodolin
  • diff --git a/web/kvm/window-about.pug b/web/kvm/window-about.pug index 6787681c..197298da 100644 --- a/web/kvm/window-about.pug +++ b/web/kvm/window-about.pug @@ -53,6 +53,7 @@ div(id="about-window" class="window") li AdamBomb li adipisicing li Adrian Basham + li Adrian Popescu li Ahmed Syed li Alberto Bassi li alejandro @@ -218,6 +219,7 @@ div(id="about-window" class="window") li Egan Ford li Elani Ferri li Elliot Woo + li Entt li Eric Phenix li Ethan Shold li Eugene Sukhodolin From 56728d5007fa0a8ea0f45cdf9cb646db2a55599c Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Sat, 6 Apr 2024 22:02:12 +0300 Subject: [PATCH 08/30] =?UTF-8?q?Bump=20version:=203.329=20=E2=86=92=203.3?= =?UTF-8?q?30?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- PKGBUILD | 2 +- kvmd/__init__.py | 2 +- setup.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index dfe10f43..e9e93bed 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,7 +1,7 @@ [bumpversion] commit = True tag = True -current_version = 3.329 +current_version = 3.330 parse = (?P\d+)\.(?P\d+)(\.(?P\d+)(\-(?P[a-z]+))?)? serialize = {major}.{minor} diff --git a/PKGBUILD b/PKGBUILD index d7360e53..840c15ff 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -39,7 +39,7 @@ for _variant in "${_variants[@]}"; do pkgname+=(kvmd-platform-$_platform-$_board) done pkgbase=kvmd -pkgver=3.329 +pkgver=3.330 pkgrel=1 pkgdesc="The main PiKVM daemon" url="https://github.com/pikvm/kvmd" diff --git a/kvmd/__init__.py b/kvmd/__init__.py index 3ded6ba1..531a301a 100644 --- a/kvmd/__init__.py +++ b/kvmd/__init__.py @@ -20,4 +20,4 @@ # ========================================================================== # -__version__ = "3.329" +__version__ = "3.330" diff --git a/setup.py b/setup.py index a787dc6e..c2ebf784 100755 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ def main() -> None: setup( name="kvmd", - version="3.329", + version="3.330", url="https://github.com/pikvm/kvmd", license="GPLv3", author="Maxim Devaev", From 142c4a3552d443bca1a491d1b17d53e2b126ea91 Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Sat, 6 Apr 2024 23:51:41 +0300 Subject: [PATCH 09/30] v4plus: config.txt for passthrough --- configs/os/boot-config/v4plus-hdmi-rpi4.txt | 4 ++++ kvmd.install | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/configs/os/boot-config/v4plus-hdmi-rpi4.txt b/configs/os/boot-config/v4plus-hdmi-rpi4.txt index 3728ab39..05821ea4 100644 --- a/configs/os/boot-config/v4plus-hdmi-rpi4.txt +++ b/configs/os/boot-config/v4plus-hdmi-rpi4.txt @@ -23,3 +23,7 @@ dtparam=i2c_arm=on # Clock dtoverlay=i2c-rtc,pcf8563,wakeup-source + +# Passthrough +dtoverlay=vc4-kms-v3d +disable_overscan=1 diff --git a/kvmd.install b/kvmd.install index a97b799d..e57d03c7 100644 --- a/kvmd.install +++ b/kvmd.install @@ -83,6 +83,15 @@ post_upgrade() { keyboxd@etc-pacman.d-gnupg.socket fi + if [[ "$(varcmp "$2" 3.331)" -lt 0 ]]; then + grep -q "^dtoverlay=vc4-kms-v3d" /boot/config.txt || cat << EOF >> /boot/config.txt + +# Passthrough +dtoverlay=vc4-kms-v3d +disable_overscan=1 +EOF + fi + # Some update deletes /etc/motd, WTF # shellcheck disable=SC2015,SC2166 [ ! -f /etc/motd -a -f /etc/motd.pacsave ] && mv /etc/motd.pacsave /etc/motd || true From 1acf27c21f70d025cc904893f0968369dd93c454 Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Sun, 7 Apr 2024 01:45:09 +0300 Subject: [PATCH 10/30] v4plus: 8 buffers --- configs/kvmd/main/v4plus-hdmi-rpi4.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/kvmd/main/v4plus-hdmi-rpi4.yaml b/configs/kvmd/main/v4plus-hdmi-rpi4.yaml index eb52b124..c1e6faff 100644 --- a/configs/kvmd/main/v4plus-hdmi-rpi4.yaml +++ b/configs/kvmd/main/v4plus-hdmi-rpi4.yaml @@ -40,7 +40,7 @@ kvmd: - "--dv-timings" - "--format=uyvy" - "--format-swap-rgb" - - "--buffers=6" + - "--buffers=8" - "--encoder=m2m-image" - "--workers=3" - "--quality={quality}" From 9847154e1bf7ad235dc4597697e6e135f6a096e6 Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Sun, 7 Apr 2024 14:58:55 +0300 Subject: [PATCH 11/30] ustreamer 6.11 required --- PKGBUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PKGBUILD b/PKGBUILD index 840c15ff..1655414e 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -91,7 +91,7 @@ depends=( certbot platform-io-access raspberrypi-utils - "ustreamer>=6.8" + "ustreamer>=6.11" # Systemd UDEV bug "systemd>=248.3-2" From 898f8218cab7980fb68b723e3caaadd03d0acb7c Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Thu, 11 Apr 2024 18:28:05 +0300 Subject: [PATCH 12/30] =?UTF-8?q?Bump=20version:=203.330=20=E2=86=92=203.3?= =?UTF-8?q?31?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- PKGBUILD | 2 +- kvmd/__init__.py | 2 +- setup.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index e9e93bed..3482ee9e 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,7 +1,7 @@ [bumpversion] commit = True tag = True -current_version = 3.330 +current_version = 3.331 parse = (?P\d+)\.(?P\d+)(\.(?P\d+)(\-(?P[a-z]+))?)? serialize = {major}.{minor} diff --git a/PKGBUILD b/PKGBUILD index 1655414e..009eef09 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -39,7 +39,7 @@ for _variant in "${_variants[@]}"; do pkgname+=(kvmd-platform-$_platform-$_board) done pkgbase=kvmd -pkgver=3.330 +pkgver=3.331 pkgrel=1 pkgdesc="The main PiKVM daemon" url="https://github.com/pikvm/kvmd" diff --git a/kvmd/__init__.py b/kvmd/__init__.py index 531a301a..66e81984 100644 --- a/kvmd/__init__.py +++ b/kvmd/__init__.py @@ -20,4 +20,4 @@ # ========================================================================== # -__version__ = "3.330" +__version__ = "3.331" diff --git a/setup.py b/setup.py index c2ebf784..8674e330 100755 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ def main() -> None: setup( name="kvmd", - version="3.330", + version="3.331", url="https://github.com/pikvm/kvmd", license="GPLv3", author="Maxim Devaev", From e92b666dfb1d042e4f57af92ce35cd09e4833167 Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Thu, 11 Apr 2024 18:44:30 +0300 Subject: [PATCH 13/30] fix --- kvmd.install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kvmd.install b/kvmd.install index e57d03c7..55bd999d 100644 --- a/kvmd.install +++ b/kvmd.install @@ -83,7 +83,7 @@ post_upgrade() { keyboxd@etc-pacman.d-gnupg.socket fi - if [[ "$(varcmp "$2" 3.331)" -lt 0 ]]; then + if [[ "$(vercmp "$2" 3.332)" -lt 0 ]]; then grep -q "^dtoverlay=vc4-kms-v3d" /boot/config.txt || cat << EOF >> /boot/config.txt # Passthrough From 097198356fa2572ad5642cab2b8adc1df7db3240 Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Thu, 11 Apr 2024 18:45:05 +0300 Subject: [PATCH 14/30] =?UTF-8?q?Bump=20version:=203.331=20=E2=86=92=203.3?= =?UTF-8?q?32?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- PKGBUILD | 2 +- kvmd/__init__.py | 2 +- setup.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 3482ee9e..f0f7eafe 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,7 +1,7 @@ [bumpversion] commit = True tag = True -current_version = 3.331 +current_version = 3.332 parse = (?P\d+)\.(?P\d+)(\.(?P\d+)(\-(?P[a-z]+))?)? serialize = {major}.{minor} diff --git a/PKGBUILD b/PKGBUILD index 009eef09..a153185b 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -39,7 +39,7 @@ for _variant in "${_variants[@]}"; do pkgname+=(kvmd-platform-$_platform-$_board) done pkgbase=kvmd -pkgver=3.331 +pkgver=3.332 pkgrel=1 pkgdesc="The main PiKVM daemon" url="https://github.com/pikvm/kvmd" diff --git a/kvmd/__init__.py b/kvmd/__init__.py index 66e81984..9cd1c098 100644 --- a/kvmd/__init__.py +++ b/kvmd/__init__.py @@ -20,4 +20,4 @@ # ========================================================================== # -__version__ = "3.331" +__version__ = "3.332" diff --git a/setup.py b/setup.py index 8674e330..db6cbdd9 100755 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ def main() -> None: setup( name="kvmd", - version="3.331", + version="3.332", url="https://github.com/pikvm/kvmd", license="GPLv3", author="Maxim Devaev", From 107af57d4e1c961d1dbfc7460500e735315d8108 Mon Sep 17 00:00:00 2001 From: aastein Date: Tue, 16 Apr 2024 00:33:49 +0300 Subject: [PATCH 15/30] add parameter for mouse jiggler interval (#165) * add jiggler_interval * Update __init__.py --- kvmd/plugins/hid/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/kvmd/plugins/hid/__init__.py b/kvmd/plugins/hid/__init__.py index 1e1db544..c94bc314 100644 --- a/kvmd/plugins/hid/__init__.py +++ b/kvmd/plugins/hid/__init__.py @@ -30,6 +30,7 @@ from typing import Any from ...yamlconf import Option from ...validators.basic import valid_bool +from ...validators.basic import valid_int_f1 from .. import BasePlugin from .. import get_plugin_class @@ -37,11 +38,12 @@ from .. import get_plugin_class # ===== class BaseHid(BasePlugin): - def __init__(self, jiggler_enabled: bool, jiggler_active: bool) -> None: + def __init__(self, jiggler_enabled: bool, jiggler_active: bool, jiggler_interval: int) -> None: self.__jiggler_enabled = jiggler_enabled self.__jiggler_active = jiggler_active self.__jiggler_absolute = True self.__activity_ts = 0 + self.__jiggler_interval = jiggler_interval @classmethod def _get_jiggler_options(cls) -> dict[str, Any]: @@ -49,6 +51,7 @@ class BaseHid(BasePlugin): "jiggler": { "enabled": Option(False, type=valid_bool, unpack_as="jiggler_enabled"), "active": Option(False, type=valid_bool, unpack_as="jiggler_active"), + "interval": Option(60, type=valid_int_f1, unpack_as="jiggler_interval") }, } @@ -109,7 +112,7 @@ class BaseHid(BasePlugin): async def systask(self) -> None: factor = 1 while True: - if self.__jiggler_active and (self.__activity_ts + 60 < int(time.monotonic())): + if self.__jiggler_active and (self.__activity_ts + self.__jiggler_interval < int(time.monotonic())): for _ in range(5): if self.__jiggler_absolute: self.send_mouse_move_event(100 * factor, 100 * factor) @@ -134,6 +137,7 @@ class BaseHid(BasePlugin): "jiggler": { "enabled": self.__jiggler_enabled, "active": self.__jiggler_active, + "interval": self.__jiggler_interval, }, } From 06d656c6e0ed633cee4c81140e27669bf40b9cb9 Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Tue, 16 Apr 2024 00:37:50 +0300 Subject: [PATCH 16/30] style fix --- kvmd/plugins/hid/__init__.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/kvmd/plugins/hid/__init__.py b/kvmd/plugins/hid/__init__.py index c94bc314..1c2efeec 100644 --- a/kvmd/plugins/hid/__init__.py +++ b/kvmd/plugins/hid/__init__.py @@ -41,17 +41,17 @@ class BaseHid(BasePlugin): def __init__(self, jiggler_enabled: bool, jiggler_active: bool, jiggler_interval: int) -> None: self.__jiggler_enabled = jiggler_enabled self.__jiggler_active = jiggler_active + self.__jiggler_interval = jiggler_interval self.__jiggler_absolute = True self.__activity_ts = 0 - self.__jiggler_interval = jiggler_interval @classmethod def _get_jiggler_options(cls) -> dict[str, Any]: return { "jiggler": { - "enabled": Option(False, type=valid_bool, unpack_as="jiggler_enabled"), - "active": Option(False, type=valid_bool, unpack_as="jiggler_active"), - "interval": Option(60, type=valid_int_f1, unpack_as="jiggler_interval") + "enabled": Option(False, type=valid_bool, unpack_as="jiggler_enabled"), + "active": Option(False, type=valid_bool, unpack_as="jiggler_active"), + "interval": Option(60, type=valid_int_f1, unpack_as="jiggler_interval"), }, } @@ -135,8 +135,8 @@ class BaseHid(BasePlugin): def _get_jiggler_state(self) -> dict: return { "jiggler": { - "enabled": self.__jiggler_enabled, - "active": self.__jiggler_active, + "enabled": self.__jiggler_enabled, + "active": self.__jiggler_active, "interval": self.__jiggler_interval, }, } From ee982946becf9761d62dba24f120e32a9a09432a Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Tue, 16 Apr 2024 23:29:04 +0300 Subject: [PATCH 17/30] =?UTF-8?q?Bump=20version:=203.332=20=E2=86=92=203.3?= =?UTF-8?q?33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- PKGBUILD | 2 +- kvmd/__init__.py | 2 +- setup.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index f0f7eafe..d2f7afb2 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,7 +1,7 @@ [bumpversion] commit = True tag = True -current_version = 3.332 +current_version = 3.333 parse = (?P\d+)\.(?P\d+)(\.(?P\d+)(\-(?P[a-z]+))?)? serialize = {major}.{minor} diff --git a/PKGBUILD b/PKGBUILD index a153185b..b77ab03d 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -39,7 +39,7 @@ for _variant in "${_variants[@]}"; do pkgname+=(kvmd-platform-$_platform-$_board) done pkgbase=kvmd -pkgver=3.332 +pkgver=3.333 pkgrel=1 pkgdesc="The main PiKVM daemon" url="https://github.com/pikvm/kvmd" diff --git a/kvmd/__init__.py b/kvmd/__init__.py index 9cd1c098..ab9a094f 100644 --- a/kvmd/__init__.py +++ b/kvmd/__init__.py @@ -20,4 +20,4 @@ # ========================================================================== # -__version__ = "3.332" +__version__ = "3.333" diff --git a/setup.py b/setup.py index db6cbdd9..52db4145 100755 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ def main() -> None: setup( name="kvmd", - version="3.332", + version="3.333", url="https://github.com/pikvm/kvmd", license="GPLv3", author="Maxim Devaev", From d2bc31d1cd067e8463d1ea51abcbd7b6883a868f Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Sun, 12 May 2024 03:43:57 +0300 Subject: [PATCH 18/30] pikvm/pikvm#1312: Option to close GPIO menu after click --- kvmd/apps/kvmd/ugpio.py | 6 +++++- web/share/js/kvm/gpio.js | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/kvmd/apps/kvmd/ugpio.py b/kvmd/apps/kvmd/ugpio.py index 74ed204f..872d5f6c 100644 --- a/kvmd/apps/kvmd/ugpio.py +++ b/kvmd/apps/kvmd/ugpio.py @@ -383,15 +383,19 @@ class UserGpio: def __make_item_output(self, parts: list[str]) -> dict: assert len(parts) >= 1 confirm = False + hide = False text = "Click" if len(parts) == 2: text = parts[1] elif len(parts) == 3: - confirm = (parts[1] == "confirm") + opts = parts[1].split(",") + confirm = ("confirm" in opts) + hide = ("hide" in opts) text = parts[2] return { "type": UserGpioModes.OUTPUT, "channel": parts[0], "confirm": confirm, + "hide": hide, "text": text, } diff --git a/web/share/js/kvm/gpio.js b/web/share/js/kvm/gpio.js index db259cee..4bee901a 100644 --- a/web/share/js/kvm/gpio.js +++ b/web/share/js/kvm/gpio.js @@ -150,7 +150,10 @@ export function Gpio(__recorder) { if (item.scheme.pulse.delay) { controls.push(` + ${item.hide ? "data-force-hide-menu" : ""} + data-channel="${item.channel}" data-confirm="${confirm}"> + ${(item.hide ? "• " : "") + item.text} + `); } return `${controls.join("")}
       
    `; From 70484c046e487fcb0fb885b962cf53a4f94c989c Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Sun, 12 May 2024 04:42:11 +0300 Subject: [PATCH 19/30] added noyito pseudo-hid relay --- kvmd/plugins/ugpio/noyito.py | 165 +++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 kvmd/plugins/ugpio/noyito.py diff --git a/kvmd/plugins/ugpio/noyito.py b/kvmd/plugins/ugpio/noyito.py new file mode 100644 index 00000000..f3c04a57 --- /dev/null +++ b/kvmd/plugins/ugpio/noyito.py @@ -0,0 +1,165 @@ +# ========================================================================== # +# # +# KVMD - The main PiKVM daemon. # +# # +# Copyright (C) 2018-2024 Maxim Devaev # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +# ========================================================================== # + + +import contextlib +import functools + +from typing import Callable +from typing import Any + +import hid + +from ...logging import get_logger + +from ... import tools +from ... import aiotools + +from ...yamlconf import Option + +from ...validators.basic import valid_number +from ...validators.os import valid_abs_path + +from . import GpioDriverOfflineError +from . import UserGpioModes +from . import BaseUserGpioDriver + + +# ===== +class Plugin(BaseUserGpioDriver): + # This is like a HID relay, but does not support the common protocol. + # So no status reports, ugh. + # Why make a HID USB if you can't implement such simple things? + # So many questions, and so few answers... + + def __init__( # pylint: disable=super-init-not-called + self, + instance_name: str, + notifier: aiotools.AioNotifier, + + device_path: str, + ) -> None: + + super().__init__(instance_name, notifier) + + self.__device_path = device_path + + self.__device: (hid.device | None) = None # type: ignore + self.__stop = False + + self.__initials: dict[int, bool] = {} + self.__state: dict[int, bool] = dict.fromkeys(range(8), False) + + @classmethod + def get_plugin_options(cls) -> dict: + return { + "device": Option("", type=valid_abs_path, unpack_as="device_path"), + } + + @classmethod + def get_modes(cls) -> set[str]: + return set([UserGpioModes.OUTPUT]) + + @classmethod + def get_pin_validator(cls) -> Callable[[Any], Any]: + return functools.partial(valid_number, min=0, max=7, name="NOYITO relay channel") + + def register_output(self, pin: str, initial: (bool | None)) -> None: + self.__initials[int(pin)] = bool(initial) + + def prepare(self) -> None: + logger = get_logger(0) + logger.info("Probing driver %s on %s ...", self, self.__device_path) + try: + with self.__ensure_device("probing"): + pass + except Exception as err: + logger.error("Can't probe %s on %s: %s", + self, self.__device_path, tools.efmt(err)) + self.__reset_pins() + + async def cleanup(self) -> None: + self.__reset_pins() + self.__close_device() + self.__stop = True + + async def read(self, pin: str) -> bool: + return self.__state[int(pin)] + + async def write(self, pin: str, state: bool) -> None: + try: + return self.__inner_write(int(pin), state) + except Exception: + raise GpioDriverOfflineError(self) + + # ===== + + def __reset_pins(self) -> None: + logger = get_logger(0) + for (pin, state) in self.__initials.items(): + logger.info("Resetting pin=%d to state=%d of %s on %s: ...", + pin, state, self, self.__device_path) + try: + self.__inner_write(pin, state) + except Exception as err: + logger.error("Can't reset pin=%d of %s on %s: %s", + pin, self, self.__device_path, tools.efmt(err)) + + def __inner_write(self, pin: int, state: bool) -> None: + assert 0 <= pin <= 7 + with self.__ensure_device("writing") as device: + report = [0xA0, pin + 1, int(state), 0] + report[-1] = sum(report) + result = device.write(report) + if result < 0: + raise RuntimeError(f"Retval of send_feature_report() < 0: {result}") + self.__state[pin] = state + + @contextlib.contextmanager + def __ensure_device(self, context: str) -> hid.device: # type: ignore + assert not self.__stop + if self.__device is None: + device = hid.device() # type: ignore + device.open_path(self.__device_path.encode("utf-8")) + device.set_nonblocking(True) + self.__device = device + get_logger(0).info("Opened %s on %s while %s", self, self.__device_path, context) + try: + yield self.__device + except Exception as err: + get_logger(0).error("Error occured on %s on %s while %s: %s", + self, self.__device_path, context, tools.efmt(err)) + self.__close_device() + raise + + def __close_device(self) -> None: + if self.__device: + try: + self.__device.close() + except Exception: + pass + self.__device = None + get_logger(0).info("Closed %s on %s", self, self.__device_path) + + def __str__(self) -> str: + return f"Noyito({self._instance_name})" + + __repr__ = __str__ From 6facfbbff9f2a5f76a19b07142a449b01d215452 Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Sun, 12 May 2024 04:49:48 +0300 Subject: [PATCH 20/30] =?UTF-8?q?Bump=20version:=203.333=20=E2=86=92=204.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- PKGBUILD | 2 +- kvmd/__init__.py | 2 +- setup.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index d2f7afb2..16df761e 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,7 +1,7 @@ [bumpversion] commit = True tag = True -current_version = 3.333 +current_version = 4.0 parse = (?P\d+)\.(?P\d+)(\.(?P\d+)(\-(?P[a-z]+))?)? serialize = {major}.{minor} diff --git a/PKGBUILD b/PKGBUILD index b77ab03d..97bfb07a 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -39,7 +39,7 @@ for _variant in "${_variants[@]}"; do pkgname+=(kvmd-platform-$_platform-$_board) done pkgbase=kvmd -pkgver=3.333 +pkgver=4.0 pkgrel=1 pkgdesc="The main PiKVM daemon" url="https://github.com/pikvm/kvmd" diff --git a/kvmd/__init__.py b/kvmd/__init__.py index ab9a094f..64b53337 100644 --- a/kvmd/__init__.py +++ b/kvmd/__init__.py @@ -20,4 +20,4 @@ # ========================================================================== # -__version__ = "3.333" +__version__ = "4.0" diff --git a/setup.py b/setup.py index 52db4145..a918aa27 100755 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ def main() -> None: setup( name="kvmd", - version="3.333", + version="4.0", url="https://github.com/pikvm/kvmd", license="GPLv3", author="Maxim Devaev", From 89eb04c14106f6826d85a1e6aa37cb17f5d515ee Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Mon, 13 May 2024 17:52:04 +0300 Subject: [PATCH 21/30] lint fixes --- kvmd/tools.py | 3 +-- setup.py | 2 +- testenv/tests/test_aiotools.py | 2 +- testenv/tests/validators/test_basic.py | 8 ++++---- testenv/tests/validators/test_hw.py | 8 ++++---- testenv/tests/validators/test_kvm.py | 14 +++++++------- testenv/tests/validators/test_net.py | 2 +- testenv/tests/validators/test_os.py | 2 +- testenv/tests/validators/test_ugpio.py | 2 +- testenv/tox.ini | 4 ++-- 10 files changed, 23 insertions(+), 24 deletions(-) diff --git a/kvmd/tools.py b/kvmd/tools.py index fca68e22..c96ff38f 100644 --- a/kvmd/tools.py +++ b/kvmd/tools.py @@ -26,7 +26,6 @@ import multiprocessing.queues import queue import shlex -from typing import Hashable from typing import TypeVar @@ -45,7 +44,7 @@ def efmt(err: Exception) -> str: # ===== -def rget(dct: dict, *keys: Hashable) -> dict: +def rget(dct: dict, *keys: str) -> dict: result = functools.reduce((lambda nxt, key: nxt.get(key, {})), keys, dct) if not isinstance(result, dict): raise TypeError(f"Not a dict as result: {result!r} from {dct!r} at {list(keys)}") diff --git a/setup.py b/setup.py index a918aa27..5fd7c32e 100755 --- a/setup.py +++ b/setup.py @@ -138,7 +138,7 @@ def main() -> None: classifiers=[ "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "Development Status :: 5 - Production/Stable", - "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: System :: Systems Administration", "Operating System :: POSIX :: Linux", "Intended Audience :: System Administrators", diff --git a/testenv/tests/test_aiotools.py b/testenv/tests/test_aiotools.py index 8c4f65a4..048b1f9c 100644 --- a/testenv/tests/test_aiotools.py +++ b/testenv/tests/test_aiotools.py @@ -111,7 +111,7 @@ async def test_fail__region__access_two() -> None: results = await asyncio.gather(func1(), func2(), return_exceptions=True) assert results[0] is None - assert type(results[1]) == RegionIsBusyError # pylint: disable=unidiomatic-typecheck + assert type(results[1]) is RegionIsBusyError # pylint: disable=unidiomatic-typecheck assert not region.is_busy() await region.exit() diff --git a/testenv/tests/validators/test_basic.py b/testenv/tests/validators/test_basic.py index 06d6deec..7551e4bb 100644 --- a/testenv/tests/validators/test_basic.py +++ b/testenv/tests/validators/test_basic.py @@ -86,7 +86,7 @@ def test_fail__valid_number__min_max(arg: Any) -> None: # pylint: disable=inval @pytest.mark.parametrize("arg", [0, 1, 5, "5 "]) def test_ok__valid_int_f0(arg: Any) -> None: value = valid_int_f0(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert type(value) is int # pylint: disable=unidiomatic-typecheck assert value == int(str(arg).strip()) @@ -100,7 +100,7 @@ def test_fail__valid_int_f0(arg: Any) -> None: @pytest.mark.parametrize("arg", [1, 5, "5 "]) def test_ok__valid_int_f1(arg: Any) -> None: value = valid_int_f1(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert type(value) is int # pylint: disable=unidiomatic-typecheck assert value == int(str(arg).strip()) @@ -114,7 +114,7 @@ def test_fail__valid_int_f1(arg: Any) -> None: @pytest.mark.parametrize("arg", [0, 1, 5, "5 ", "5.0 "]) def test_ok__valid_float_f0(arg: Any) -> None: value = valid_float_f0(arg) - assert type(value) == float # pylint: disable=unidiomatic-typecheck + assert type(value) is float # pylint: disable=unidiomatic-typecheck assert value == float(str(arg).strip()) @@ -128,7 +128,7 @@ def test_fail__valid_float_f0(arg: Any) -> None: @pytest.mark.parametrize("arg", [0.1, 1, 5, "5 ", "5.0 "]) def test_ok__valid_float_f01(arg: Any) -> None: value = valid_float_f01(arg) - assert type(value) == float # pylint: disable=unidiomatic-typecheck + assert type(value) is float # pylint: disable=unidiomatic-typecheck assert value == float(str(arg).strip()) diff --git a/testenv/tests/validators/test_hw.py b/testenv/tests/validators/test_hw.py index a7a28202..b73af65e 100644 --- a/testenv/tests/validators/test_hw.py +++ b/testenv/tests/validators/test_hw.py @@ -37,7 +37,7 @@ from kvmd.validators.hw import valid_otg_ethernet @pytest.mark.parametrize("arg", ["1200 ", 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200]) def test_ok__valid_tty_speed(arg: Any) -> None: value = valid_tty_speed(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert type(value) is int # pylint: disable=unidiomatic-typecheck assert value == int(str(arg).strip()) @@ -51,7 +51,7 @@ def test_fail__valid_tty_speed(arg: Any) -> None: @pytest.mark.parametrize("arg", ["0 ", 0, 1, 13]) def test_ok__valid_gpio_pin(arg: Any) -> None: value = valid_gpio_pin(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert type(value) is int # pylint: disable=unidiomatic-typecheck assert value == int(str(arg).strip()) @@ -65,7 +65,7 @@ def test_fail__valid_gpio_pin(arg: Any) -> None: @pytest.mark.parametrize("arg", ["0 ", -1, 0, 1, 13]) def test_ok__valid_gpio_pin_optional(arg: Any) -> None: value = valid_gpio_pin_optional(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert type(value) is int # pylint: disable=unidiomatic-typecheck assert value == int(str(arg).strip()) @@ -110,7 +110,7 @@ def test_fail__valid_otg_gadget(arg: Any) -> None: @pytest.mark.parametrize("arg", ["0 ", 0, 1, 13, 65535]) def test_ok__valid_otg_id(arg: Any) -> None: value = valid_otg_id(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert type(value) is int # pylint: disable=unidiomatic-typecheck assert value == int(str(arg).strip()) diff --git a/testenv/tests/validators/test_kvm.py b/testenv/tests/validators/test_kvm.py index 9c70c662..b7ea6365 100644 --- a/testenv/tests/validators/test_kvm.py +++ b/testenv/tests/validators/test_kvm.py @@ -116,7 +116,7 @@ def test_fail__valid_msd_image_name(arg: Any) -> None: @pytest.mark.parametrize("arg", [" foo ", "bar", "foo, ,bar,", " ", " , ", ""]) def test_ok__valid_info_fields(arg: Any) -> None: value = valid_info_fields(arg, set(["foo", "bar"])) - assert type(value) == set # pylint: disable=unidiomatic-typecheck + assert type(value) is set # pylint: disable=unidiomatic-typecheck assert value == set(filter(None, map(str.strip, str(arg).split(",")))) @@ -130,7 +130,7 @@ def test_fail__valid_info_fields(arg: Any) -> None: @pytest.mark.parametrize("arg", ["0 ", 0, 1, 13]) def test_ok__valid_log_seek(arg: Any) -> None: value = valid_log_seek(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert type(value) is int # pylint: disable=unidiomatic-typecheck assert value == int(str(arg).strip()) @@ -144,7 +144,7 @@ def test_fail__valid_log_seek(arg: Any) -> None: @pytest.mark.parametrize("arg", ["1 ", 20, 100]) def test_ok__valid_stream_quality(arg: Any) -> None: value = valid_stream_quality(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert type(value) is int # pylint: disable=unidiomatic-typecheck assert value == int(str(arg).strip()) @@ -158,7 +158,7 @@ def test_fail__valid_stream_quality(arg: Any) -> None: @pytest.mark.parametrize("arg", ["1 ", 120]) def test_ok__valid_stream_fps(arg: Any) -> None: value = valid_stream_fps(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert type(value) is int # pylint: disable=unidiomatic-typecheck assert value == int(str(arg).strip()) @@ -172,7 +172,7 @@ def test_fail__valid_stream_fps(arg: Any) -> None: @pytest.mark.parametrize("arg", ["1280x720 ", "1x1"]) def test_ok__valid_stream_resolution(arg: Any) -> None: value = valid_stream_resolution(arg) - assert type(value) == str # pylint: disable=unidiomatic-typecheck + assert type(value) is str # pylint: disable=unidiomatic-typecheck assert value == str(arg).strip() @@ -186,7 +186,7 @@ def test_fail__valid_stream_resolution(arg: Any) -> None: @pytest.mark.parametrize("arg", ["25", " 20000 ", 5000]) def test_ok__valid_stream_h264_bitrate(arg: Any) -> None: value = valid_stream_h264_bitrate(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert type(value) is int # pylint: disable=unidiomatic-typecheck assert value == int(str(arg).strip()) @@ -200,7 +200,7 @@ def test_fail__valid_stream_h264_bitrate(arg: Any) -> None: @pytest.mark.parametrize("arg", ["1 ", 0, 60]) def test_ok__valid_stream_h264_gop(arg: Any) -> None: value = valid_stream_h264_gop(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert type(value) is int # pylint: disable=unidiomatic-typecheck assert value == int(str(arg).strip()) diff --git a/testenv/tests/validators/test_net.py b/testenv/tests/validators/test_net.py index 14f2b57c..a67fbeff 100644 --- a/testenv/tests/validators/test_net.py +++ b/testenv/tests/validators/test_net.py @@ -147,7 +147,7 @@ def test_fail__valid_rfc_host(arg: Any) -> None: @pytest.mark.parametrize("arg", ["0 ", 0, "22", 443, 65535]) def test_ok__valid_port(arg: Any) -> None: value = valid_port(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert type(value) is int # pylint: disable=unidiomatic-typecheck assert value == int(str(arg).strip()) diff --git a/testenv/tests/validators/test_os.py b/testenv/tests/validators/test_os.py index 30981308..8fb5236b 100644 --- a/testenv/tests/validators/test_os.py +++ b/testenv/tests/validators/test_os.py @@ -124,7 +124,7 @@ def test_fail__valid_printable_filename(arg: Any) -> None: @pytest.mark.parametrize("arg", [0, 5, "1000"]) def test_ok__valid_unix_mode(arg: Any) -> None: value = valid_unix_mode(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert type(value) is int # pylint: disable=unidiomatic-typecheck assert value == int(str(value).strip()) diff --git a/testenv/tests/validators/test_ugpio.py b/testenv/tests/validators/test_ugpio.py index 110afd83..be29ea68 100644 --- a/testenv/tests/validators/test_ugpio.py +++ b/testenv/tests/validators/test_ugpio.py @@ -72,7 +72,7 @@ def test_fail__valid_ugpio_item(validator: Callable[[Any], str], arg: Any) -> No @pytest.mark.parametrize("arg", ["foo", " bar", " baz "]) def test_ok__valid_ugpio_driver_variants(arg: Any) -> None: value = valid_ugpio_driver(arg, set(["foo", "bar", "baz"])) - assert type(value) == str # pylint: disable=unidiomatic-typecheck + assert type(value) is str # pylint: disable=unidiomatic-typecheck assert value == str(arg).strip() diff --git a/testenv/tox.ini b/testenv/tox.ini index c0efad82..2f8c08d0 100644 --- a/testenv/tox.ini +++ b/testenv/tox.ini @@ -3,7 +3,7 @@ envlist = flake8, pylint, mypy, vulture, pytest, eslint, htmlhint, shellcheck skipsdist = true [testenv] -basepython = python3.11 +basepython = python3.12 sitepackages = true changedir = /src @@ -11,7 +11,7 @@ changedir = /src allowlist_externals = bash commands = bash -c 'flake8 --config=testenv/linters/flake8.ini kvmd testenv/tests *.py' deps = - flake8==5.0.4 + flake8 flake8-quotes -rrequirements.txt From ce0d1551d6e54dd10152bd7ec0eab7a2380bfbce Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Mon, 13 May 2024 17:52:47 +0300 Subject: [PATCH 22/30] temporary disabled eslint --- testenv/tox.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testenv/tox.ini b/testenv/tox.ini index 2f8c08d0..0d1ed571 100644 --- a/testenv/tox.ini +++ b/testenv/tox.ini @@ -1,5 +1,6 @@ [tox] -envlist = flake8, pylint, mypy, vulture, pytest, eslint, htmlhint, shellcheck +envlist = flake8, pylint, mypy, vulture, pytest, htmlhint, shellcheck +#envlist = flake8, pylint, mypy, vulture, pytest, eslint, htmlhint, shellcheck skipsdist = true [testenv] From aacfd52d6c462bae2685591f89643532c8f1863e Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Mon, 13 May 2024 17:53:30 +0300 Subject: [PATCH 23/30] python 3.12 --- PKGBUILD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PKGBUILD b/PKGBUILD index 97bfb07a..758cf145 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -46,8 +46,8 @@ url="https://github.com/pikvm/kvmd" license=(GPL) arch=(any) depends=( - "python>=3.11" - "python<3.12" + "python>=3.12" + "python<3.13" python-yaml python-aiohttp python-aiofiles From e784dc3e70acab049640001449f825c4862441c4 Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Mon, 13 May 2024 17:54:08 +0300 Subject: [PATCH 24/30] =?UTF-8?q?Bump=20version:=204.0=20=E2=86=92=204.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- PKGBUILD | 2 +- kvmd/__init__.py | 2 +- setup.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 16df761e..9cc7e136 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,7 +1,7 @@ [bumpversion] commit = True tag = True -current_version = 4.0 +current_version = 4.1 parse = (?P\d+)\.(?P\d+)(\.(?P\d+)(\-(?P[a-z]+))?)? serialize = {major}.{minor} diff --git a/PKGBUILD b/PKGBUILD index 758cf145..dcc43ba4 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -39,7 +39,7 @@ for _variant in "${_variants[@]}"; do pkgname+=(kvmd-platform-$_platform-$_board) done pkgbase=kvmd -pkgver=4.0 +pkgver=4.1 pkgrel=1 pkgdesc="The main PiKVM daemon" url="https://github.com/pikvm/kvmd" diff --git a/kvmd/__init__.py b/kvmd/__init__.py index 64b53337..75d5fbeb 100644 --- a/kvmd/__init__.py +++ b/kvmd/__init__.py @@ -20,4 +20,4 @@ # ========================================================================== # -__version__ = "4.0" +__version__ = "4.1" diff --git a/setup.py b/setup.py index 5fd7c32e..103f3cf8 100755 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ def main() -> None: setup( name="kvmd", - version="4.0", + version="4.1", url="https://github.com/pikvm/kvmd", license="GPLv3", author="Maxim Devaev", From 3d8265e6b97dd692f2147abf7dd0bff6c91b690f Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Mon, 13 May 2024 20:26:10 +0300 Subject: [PATCH 25/30] fixed deprecated find_module() --- kvmd/keyboard/keysym.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kvmd/keyboard/keysym.py b/kvmd/keyboard/keysym.py index dd311e98..5e80d789 100644 --- a/kvmd/keyboard/keysym.py +++ b/kvmd/keyboard/keysym.py @@ -22,6 +22,7 @@ import pkgutil import functools +import importlib.util import importlib.machinery import Xlib.keysymdef @@ -87,10 +88,11 @@ def _get_keysyms() -> dict[str, int]: for (finder, module_name, _) in pkgutil.walk_packages(Xlib.keysymdef.__path__): if not isinstance(finder, importlib.machinery.FileFinder): continue - loader = finder.find_module(module_name) - if loader is None: + spec = finder.find_spec(module_name) + if spec is None or spec.loader is None: continue - module = loader.load_module(module_name) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) for keysym_name in dir(module): if keysym_name.startswith("XK_"): short_name = keysym_name[3:] From b2c91628452f69f13f73a32c06d026498cf09cca Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Mon, 13 May 2024 20:28:55 +0300 Subject: [PATCH 26/30] =?UTF-8?q?Bump=20version:=204.1=20=E2=86=92=204.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- PKGBUILD | 2 +- kvmd/__init__.py | 2 +- setup.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 9cc7e136..2e96d7b3 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,7 +1,7 @@ [bumpversion] commit = True tag = True -current_version = 4.1 +current_version = 4.2 parse = (?P\d+)\.(?P\d+)(\.(?P\d+)(\-(?P[a-z]+))?)? serialize = {major}.{minor} diff --git a/PKGBUILD b/PKGBUILD index dcc43ba4..4927140a 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -39,7 +39,7 @@ for _variant in "${_variants[@]}"; do pkgname+=(kvmd-platform-$_platform-$_board) done pkgbase=kvmd -pkgver=4.1 +pkgver=4.2 pkgrel=1 pkgdesc="The main PiKVM daemon" url="https://github.com/pikvm/kvmd" diff --git a/kvmd/__init__.py b/kvmd/__init__.py index 75d5fbeb..19fcd558 100644 --- a/kvmd/__init__.py +++ b/kvmd/__init__.py @@ -20,4 +20,4 @@ # ========================================================================== # -__version__ = "4.1" +__version__ = "4.2" diff --git a/setup.py b/setup.py index 103f3cf8..07214132 100755 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ def main() -> None: setup( name="kvmd", - version="4.1", + version="4.2", url="https://github.com/pikvm/kvmd", license="GPLv3", author="Maxim Devaev", From 53c2d253f2c2a57b78c138b1682eba78e588f584 Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Sat, 18 May 2024 14:33:59 +0300 Subject: [PATCH 27/30] lint fix --- kvmd/plugins/hid/spi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kvmd/plugins/hid/spi.py b/kvmd/plugins/hid/spi.py index 70ad120b..278e68e1 100644 --- a/kvmd/plugins/hid/spi.py +++ b/kvmd/plugins/hid/spi.py @@ -120,7 +120,7 @@ class _SpiPhy(BasePhy): # pylint: disable=too-many-instance-attributes return os.path.exists(f"/dev/spidev{self.__bus}.{self.__chip}") @contextlib.contextmanager - def connected(self) -> Generator[_SpiPhyConnection, None, None]: # type: ignore + def connected(self) -> Generator[_SpiPhyConnection, None, None]: # pylint: disable=contextmanager-generator-missing-cleanup # type: ignore with self.__sw_cs_connected() as switch_cs: with contextlib.closing(spidev.SpiDev(self.__bus, self.__chip)) as spi: spi.mode = 0 From ca639f6be8c3cf99019215f470b0185a5549b5df Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Mon, 8 Jul 2024 04:34:32 +0300 Subject: [PATCH 28/30] pikvm/pikvm#1347: added CPU and MEM to /api/info --- kvmd/apps/__init__.py | 2 +- kvmd/apps/kvmd/info/hw.py | 47 +++++++++++++++++++++++++++++++++++-- web/share/js/kvm/session.js | 11 ++++++--- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/kvmd/apps/__init__.py b/kvmd/apps/__init__.py index b8c4fe5b..25279be5 100644 --- a/kvmd/apps/__init__.py +++ b/kvmd/apps/__init__.py @@ -384,7 +384,7 @@ def _get_config_scheme() -> dict: "hw": { "vcgencmd_cmd": Option(["/usr/bin/vcgencmd"], type=valid_command), "ignore_past": Option(False, type=valid_bool), - "state_poll": Option(10.0, type=valid_float_f01), + "state_poll": Option(5.0, type=valid_float_f01), }, "fan": { "daemon": Option("kvmd-fan", type=valid_stripped_string), diff --git a/kvmd/apps/kvmd/info/hw.py b/kvmd/apps/kvmd/info/hw.py index a436a01f..33cedf70 100644 --- a/kvmd/apps/kvmd/info/hw.py +++ b/kvmd/apps/kvmd/info/hw.py @@ -27,6 +27,8 @@ from typing import Callable from typing import AsyncGenerator from typing import TypeVar +import psutil + from ....logging import get_logger from .... import env @@ -57,11 +59,17 @@ class HwInfoSubmanager(BaseInfoSubmanager): self.__dt_cache: dict[str, str] = {} async def get_state(self) -> dict: - (model, serial, cpu_temp, throttling) = await asyncio.gather( + ( + model, serial, throttling, + cpu_percent, cpu_temp, + (mem_percent, mem_total, mem_available), + ) = await asyncio.gather( self.__read_dt_file("model"), self.__read_dt_file("serial-number"), - self.__get_cpu_temp(), self.__get_throttling(), + self.__get_cpu_percent(), + self.__get_cpu_temp(), + self.__get_mem(), ) return { "platform": { @@ -73,6 +81,14 @@ class HwInfoSubmanager(BaseInfoSubmanager): "temp": { "cpu": cpu_temp, }, + "cpu": { + "percent": cpu_percent, + }, + "mem": { + "percent": mem_percent, + "total": mem_total, + "available": mem_available, + }, "throttling": throttling, }, } @@ -106,6 +122,33 @@ class HwInfoSubmanager(BaseInfoSubmanager): get_logger(0).error("Can't read CPU temp from %s: %s", temp_path, err) return None + async def __get_cpu_percent(self) -> (float | None): + try: + st = psutil.cpu_times_percent() + user = st.user - st.guest + nice = st.nice - st.guest_nice + idle_all = st.idle + st.iowait + system_all = st.system + st.irq + st.softirq + virtual = st.guest + st.guest_nice + total = max(1, user + nice + system_all + idle_all + st.steal + virtual) + return int( + st.nice / total * 100 + + st.user / total * 100 + + system_all / total * 100 + + (st.steal + st.guest) / total * 100 + ) + except Exception as err: + get_logger(0).error("Can't get CPU percent: %s", err) + return None + + async def __get_mem(self) -> (tuple[float, int, int] | tuple[None, None, None]): + try: + st = psutil.virtual_memory() + return (st.percent, st.total, st.available) + except Exception as err: + get_logger(0).error("Can't get memory info: %s", err) + return (None, None, None) + async def __get_throttling(self) -> (dict | None): # https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=147781&start=50#p972790 flags = await self.__parse_vcgencmd( diff --git a/web/share/js/kvm/session.js b/web/share/js/kvm/session.js index 8b89b71c..a183b33e 100644 --- a/web/share/js/kvm/session.js +++ b/web/share/js/kvm/session.js @@ -132,7 +132,7 @@ export function Session() { if (__info_hw_state !== null) { html += ` Platform: - ${__formatPlatform(__info_hw_state.platform)} + ${__formatMisc(__info_hw_state)}
    Temperature: ${__formatTemp(__info_hw_state.health.temp)} @@ -153,8 +153,13 @@ export function Session() { $("about-hardware").innerHTML = html; }; - var __formatPlatform = function(state) { - return __formatUl([["Base", state.base], ["Serial", state.serial]]); + var __formatMisc = function(state) { + return __formatUl([ + ["Base", state.platform.base], + ["Serial", state.platform.serial], + ["CPU", `${state.health.cpu.percent}%`], + ["MEM", `${state.health.mem.percent}%`], + ]); }; var __formatFan = function(state) { From 44e58d8d062bee501fa3016c6464987d741d661f Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Mon, 8 Jul 2024 04:53:24 +0300 Subject: [PATCH 29/30] Removed kvmd-cleanup Systemd kills all orphaned children when using KillMode=mixed --- configs/os/services/kvmd.service | 1 - kvmd/apps/cleanup/__init__.py | 75 ------------------------- kvmd/apps/cleanup/__main__.py | 24 -------- setup.py | 2 - testenv/tests/apps/cleanup/__init__.py | 20 ------- testenv/tests/apps/cleanup/test_main.py | 52 ----------------- 6 files changed, 174 deletions(-) delete mode 100644 kvmd/apps/cleanup/__init__.py delete mode 100644 kvmd/apps/cleanup/__main__.py delete mode 100644 testenv/tests/apps/cleanup/__init__.py delete mode 100644 testenv/tests/apps/cleanup/test_main.py diff --git a/configs/os/services/kvmd.service b/configs/os/services/kvmd.service index 56092f59..1f4d6550 100644 --- a/configs/os/services/kvmd.service +++ b/configs/os/services/kvmd.service @@ -11,7 +11,6 @@ RestartSec=3 AmbientCapabilities=CAP_NET_RAW ExecStart=/usr/bin/kvmd --run -ExecStopPost=/usr/bin/kvmd-cleanup --run TimeoutStopSec=10 KillMode=mixed diff --git a/kvmd/apps/cleanup/__init__.py b/kvmd/apps/cleanup/__init__.py deleted file mode 100644 index 9f729ef1..00000000 --- a/kvmd/apps/cleanup/__init__.py +++ /dev/null @@ -1,75 +0,0 @@ -# ========================================================================== # -# # -# KVMD - The main PiKVM daemon. # -# # -# Copyright (C) 2018-2024 Maxim Devaev # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -# ========================================================================== # - - -import signal -import time - -import psutil - -from ...logging import get_logger - -from ...yamlconf import Section - -from .. import init - - -# ===== -def _kill_streamer(config: Section) -> None: - logger = get_logger(0) - - if config.streamer.process_name_prefix: - prefix = config.streamer.process_name_prefix + ":" - logger.info("Trying to find and kill the streamer %r ...", prefix + " ") - - for proc in psutil.process_iter(): - attrs = proc.as_dict(attrs=["name"]) - if attrs.get("name", "").startswith(prefix): - try: - proc.send_signal(signal.SIGTERM) - except Exception: - logger.exception("Can't send SIGTERM to streamer with pid=%d", proc.pid) - time.sleep(3) - if proc.is_running(): - try: - proc.send_signal(signal.SIGKILL) - except Exception: - logger.exception("Can't send SIGKILL to streamer with pid=%d", proc.pid) - - -# ===== -def main(argv: (list[str] | None)=None) -> None: - config = init( - prog="kvmd-cleanup", - description="Kill KVMD and clear resources", - check_run=True, - argv=argv, - )[2].kvmd - - logger = get_logger(0) - logger.info("Cleaning up ...") - - try: - _kill_streamer(config) - except Exception: - pass - - logger.info("Bye-bye") diff --git a/kvmd/apps/cleanup/__main__.py b/kvmd/apps/cleanup/__main__.py deleted file mode 100644 index 4827fc49..00000000 --- a/kvmd/apps/cleanup/__main__.py +++ /dev/null @@ -1,24 +0,0 @@ -# ========================================================================== # -# # -# KVMD - The main PiKVM daemon. # -# # -# Copyright (C) 2018-2024 Maxim Devaev # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -# ========================================================================== # - - -from . import main -main() diff --git a/setup.py b/setup.py index 07214132..062a5d8d 100755 --- a/setup.py +++ b/setup.py @@ -95,7 +95,6 @@ def main() -> None: "kvmd.apps.htpasswd", "kvmd.apps.totp", "kvmd.apps.edidconf", - "kvmd.apps.cleanup", "kvmd.apps.ipmi", "kvmd.apps.vnc", "kvmd.apps.vnc.rfb", @@ -123,7 +122,6 @@ def main() -> None: "kvmd-htpasswd = kvmd.apps.htpasswd:main", "kvmd-totp = kvmd.apps.totp:main", "kvmd-edidconf = kvmd.apps.edidconf:main", - "kvmd-cleanup = kvmd.apps.cleanup:main", "kvmd-ipmi = kvmd.apps.ipmi:main", "kvmd-vnc = kvmd.apps.vnc:main", "kvmd-nginx-mkconf = kvmd.apps.ngxmkconf:main", diff --git a/testenv/tests/apps/cleanup/__init__.py b/testenv/tests/apps/cleanup/__init__.py deleted file mode 100644 index 8d45fdfd..00000000 --- a/testenv/tests/apps/cleanup/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# ========================================================================== # -# # -# KVMD - The main PiKVM daemon. # -# # -# Copyright (C) 2018-2024 Maxim Devaev # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -# ========================================================================== # diff --git a/testenv/tests/apps/cleanup/test_main.py b/testenv/tests/apps/cleanup/test_main.py deleted file mode 100644 index 1901b6d4..00000000 --- a/testenv/tests/apps/cleanup/test_main.py +++ /dev/null @@ -1,52 +0,0 @@ -# ========================================================================== # -# # -# KVMD - The main PiKVM daemon. # -# # -# Copyright (C) 2018-2024 Maxim Devaev # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -# ========================================================================== # - - -import multiprocessing -import time - -from typing import Literal - -import setproctitle - -from kvmd.apps.cleanup import main - - -# ===== -def test_ok() -> None: - _ = Literal # Makes liters happy - queue: "multiprocessing.Queue[Literal[True]]" = multiprocessing.Queue() - - def ustreamer_fake() -> None: - setproctitle.setproctitle("kvmd/streamer: /usr/bin/ustreamer") - queue.put(True) - while True: - time.sleep(1) - - proc = multiprocessing.Process(target=ustreamer_fake, daemon=True) - proc.start() - assert queue.get(timeout=5) - - assert proc.is_alive() - main(["kvmd-cleanup", "--run"]) - - assert not proc.is_alive() - proc.join() From 8ef1545729298159769e5804feb50ededc5487ea Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Mon, 8 Jul 2024 05:37:53 +0300 Subject: [PATCH 30/30] lint fix --- kvmd/apps/kvmd/ocr.py | 4 ++-- kvmd/plugins/hid/spi.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kvmd/apps/kvmd/ocr.py b/kvmd/apps/kvmd/ocr.py index 2b669e68..bd30afa6 100644 --- a/kvmd/apps/kvmd/ocr.py +++ b/kvmd/apps/kvmd/ocr.py @@ -145,12 +145,12 @@ class Ocr: if left < right and top < bottom: image_cropped = image.crop((left, top, right, bottom)) image.close() - image = image_cropped + image = image_cropped # type: ignore ImageOps.grayscale(image) image_resized = image.resize((int(image.size[0] * 2), int(image.size[1] * 2)), PilImage.Resampling.BICUBIC) image.close() - image = image_resized + image = image_resized # type: ignore _libtess.TessBaseAPISetImage(api, image.tobytes("raw", "RGB"), image.width, image.height, 3, image.width * 3) text_ptr = None diff --git a/kvmd/plugins/hid/spi.py b/kvmd/plugins/hid/spi.py index 278e68e1..dadcc77e 100644 --- a/kvmd/plugins/hid/spi.py +++ b/kvmd/plugins/hid/spi.py @@ -120,8 +120,8 @@ class _SpiPhy(BasePhy): # pylint: disable=too-many-instance-attributes return os.path.exists(f"/dev/spidev{self.__bus}.{self.__chip}") @contextlib.contextmanager - def connected(self) -> Generator[_SpiPhyConnection, None, None]: # pylint: disable=contextmanager-generator-missing-cleanup # type: ignore - with self.__sw_cs_connected() as switch_cs: + def connected(self) -> Generator[_SpiPhyConnection, None, None]: # type: ignore + with self.__sw_cs_connected() as switch_cs: # pylint: disable=contextmanager-generator-missing-cleanup with contextlib.closing(spidev.SpiDev(self.__bus, self.__chip)) as spi: spi.mode = 0 spi.no_cs = (not self.__hw_cs)