{"id":31812720,"url":"https://github.com/sjmf/kvm-serial","last_synced_at":"2026-05-10T21:32:07.677Z","repository":{"id":205891269,"uuid":"715338569","full_name":"sjmf/kvm-serial","owner":"sjmf","description":"A KVM controller using CH9329","archived":false,"fork":false,"pushed_at":"2025-09-20T14:55:02.000Z","size":386,"stargazers_count":40,"open_issues_count":3,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-20T15:39:34.776Z","etag":null,"topics":["ch9329","keyboard","kvm","pynput","pyserial","python","pyusb"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sjmf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-11-07T00:07:50.000Z","updated_at":"2025-09-20T14:55:06.000Z","dependencies_parsed_at":"2025-05-31T09:36:13.689Z","dependency_job_id":"09238e36-587c-4a1f-8dd5-6a745b5e3099","html_url":"https://github.com/sjmf/kvm-serial","commit_stats":null,"previous_names":["sjmf/ch9329-keyboard","sjmf/ch9329-kvm","sjmf/kvm-serial"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/sjmf/kvm-serial","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sjmf%2Fkvm-serial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sjmf%2Fkvm-serial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sjmf%2Fkvm-serial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sjmf%2Fkvm-serial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sjmf","download_url":"https://codeload.github.com/sjmf/kvm-serial/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sjmf%2Fkvm-serial/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279006601,"owners_count":26084130,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ch9329","keyboard","kvm","pynput","pyserial","python","pyusb"],"created_at":"2025-10-11T07:23:22.862Z","updated_at":"2026-05-10T21:32:07.663Z","avatar_url":"https://github.com/sjmf.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Serial KVM Controller (CH9329 and CH9350L)\n\n[![PyPI](https://img.shields.io/pypi/v/kvm-serial)](https://pypi.org/project/kvm-serial/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE.md)\n[![Black](https://img.shields.io/badge/code%20style-black-black)](https://github.com/sjmf/kvm-serial/actions/workflows/lint.yml)\n[![Run Tests](https://img.shields.io/github/actions/workflow/status/sjmf/kvm-serial/test.yml?label=Unit%20Tests)](https://github.com/sjmf/kvm-serial/actions/workflows/test.yml)\n[![codecov](https://img.shields.io/codecov/c/gh/sjmf/kvm-serial)](https://codecov.io/gh/sjmf/kvm-serial)\n\nA Software KVM for UART-to-USB-HID bridge chips (CH9329 and CH9350L).\n\nControl your computers using an emulated keyboard and mouse!\n\nThis app and python module allows you to control a second device using a UART-to-USB-HID bridge chip\n(CH9329 or CH9350L) and a video capture device. You can find these from vendors on eBay and AliExpress\nfor a low price. However, there is very little software support available for these modules, and protocol\ndocumentation is sparse.\n\nThis software captures keyboard and mouse inputs from the local computer, sending these over a\nserial UART connection to the bridge chip, which will output USB HID mouse and keyboard\nmovements and scan codes to the remote computer.\n\nThe `kvm_serial` package provides options for running the GUI, or as a script providing flexible options.\n\n\u003ca href=\"https://github.com/sjmf/kvm-serial/releases/latest/\"\u003e \u003cimg align=\"left\" src=\"assets/icon.png\" alt=\"App icon\" height=\"100\" /\u003e\u003c/a\u003e\n\n\u003chr /\u003e\n\n__[Download the latest release](https://github.com/sjmf/kvm-serial/releases/latest/)__ for Windows, Mac or Linux.\n\n*See [INSTALLATION.md](docs/INSTALLATION.md) for information on installing serial drivers, if required.*\n\n## GUI Usage\n\nRun the GUI using the [executable for your platform](https://github.com/sjmf/kvm-serial/releases/latest/), or with Python using `python -m kvm_serial`.\n\n![KVM Window](https://wp.finnigan.dev/wp-content/uploads/2025/09/output-4.gif)\n*The Serial KVM window running on OSX, controlling a Windows remote machine*\n\nThe module can be [installed from PyPI](https://pypi.org/project/kvm-serial/) (`pip install kvm-serial`),\nor locally from a cloned git repo (`pip install -e .`).\n\nThe GUI app will do a lot of the work for you: it will enumerate video devices and serial ports,\nand give you a window to interact with the guest in. Application settings can be changed from the\nmenus (File, Options, View), for example if the app doesn't select the correct devices by default.\n\nkvm-serial supports both CH9329 and CH9350L bridge hardware. See the user guides for hardware-specific setup:\n- [CH9329 User Guide](docs/CH9329_GUIDE.md) — cables, wiring, and usage for CH9329 modules\n- [CH9350L User Guide](docs/CH9350L_GUIDE.md) — dipswitch configuration, working states, and usage for CH9350L modules\n- [SUPPORTED_DEVICES.md](docs/SUPPORTED_DEVICES.md) — protocol and feature comparison\n\n## Kit List\n\nThis module requires a little bit of hardware to get going. You will need:\n\n* A UART-to-USB-HID bridge chip (CH9329 or CH9350L) — optionally with an assembled cable or module\n* Video capture card (e.g. HDMI)\n\nYou can likely get everything you need for under £30, which is incredible when compared to the\nprice of a KVM crash cart adapter.\n\n### Bridge Module/Cable\n\n_PLEASE NOTE: I am a hobbyist. I have no affiliation with any manufacturer developing or selling bridge hardware._  \n\n[![Home-made serial KVM module](https://wp.finnigan.dev/wp-content/uploads/2023/11/mini-uart.jpg)](https://wp.finnigan.dev/?p=682)\n*A home-made serial KVM module: CH9329 module soldered to SILabs CP2102. CH340 works, too.*\n\nPre-assembled cables and modules are available from eBay and AliExpress:\n\n- **CH9329 cables:** Search for \"*CH9329 cable usb*\". Just make sure it has \"CH9329\" in the name;\n  a USB-A to USB-A cable won't do and can damage your machine. See the [CH9329 User Guide](docs/CH9329_GUIDE.md)\n  for full hardware and wiring details.\n- **CH9350L modules:** Less common than CH9329 but available; typically come as breakout boards\n  with serial connector and dipswitches. See the [CH9350L User Guide](docs/CH9350L_GUIDE.md) for\n  dipswitch configuration and working state selection.\n\nYou can build your own by soldering a bridge chip to a UART transceiver chip (e.g. SILabs CP2102 or CH340).\n\n### Video Capture Card\n\nYou also need a capture card that takes the display output from your remote machine and presents it\nas a USB device to your local system. The \"*UGREEN Video Capture Card HDMI to USB C Capture\nDevice*\" was a good balance of price versus value. The more you spend on a capture device, the more\nresponsive your video feed will likely be (to a point). HDMI and VGA hardware is available.\n\n## Installing Python Dependencies\n\n_Note:_ These instructions are not required if using the executables, but you may need to do some other setup. See [INSTALLATION.md](docs/INSTALLATION.md) for information on installing serial drivers.\n\n**Standard installation** (running the application from `pip`):\n\n```bash\n# OPTIONAL: Create and activate a Virtual environment\npython -m venv ./.venv\n./.venv/scripts/activate\n\n# Install the module from PyPI and run the GUI\npip install kvm-serial\npython -m kvm-serial\n```\n\nOR using [`uv` package manager](https://docs.astral.sh/uv) (a faster alternative to pip, if available):  \n*Note: `uv run` may not work on Windows. See [#15](https://github.com/sjmf/kvm-serial/issues/15).*\n\n```bash\nuv run kvm-gui\n```\n\n**Install from source** (for development- includes PyInstaller for building executables, pytest for testing, etc.):\n\n```bash\npip install -e \".[dev]\"\n```\n\n## Script Usage\n\nA script called `control.py` is also provided for use directly from the terminal, so you can also control remotes from a headless environment! (e.g. Pi to Pi!)\n\nPackages must be installed first. Use your preferred python package manager, e.g. `pip`, `uv`\n\nUsage examples for the `control.py` script:\n\n```bash\n# Run using module\npython -m kvm_serial.control\n\n# Run using `uv`\nuv run kvm-control\n\n# Run with mouse and video support; use a Mac OSX serial port:\npython -m kvm_serial.control -e /dev/cu.usbserial-A6023LNH\n\n# Run the script using keyboard 'tty' mode (no mouse, no video)\npython control.py --mode tty /dev/tty.usbserial0\n\n# Run using `pyusb` keyboard mode (which requires root):\nsudo python control.py --mode usb /dev/tty.usbserial0\n\n# Increase logging using --verbose (or -v), and use COM1 serial port (Windows)\npython control.py --verbose COM1\n\n# Use CH9350L in state 3 (absolute mouse — recommended for desktop use)\npython control.py --ch9350 --ch9350-state 3 /dev/cu.usbserial-XXXX\n\n# Use CH9350L in state 2 (BIOS keyboard + relative mouse — for BIOS/UEFI use)\npython control.py --ch9350 --ch9350-state 2 /dev/cu.usbserial-XXXX\n\n# Use CH9350L in state 0 (full descriptor handshake)\npython control.py --ch9350 --ch9350-state 0 /dev/cu.usbserial-XXXX\n```\n\nUse `python control.py --help` to view all available options. By default, the CH9329 protocol is used; pass `--ch9350` to switch to CH9350L protocol. See the [CH9329 User Guide](docs/CH9329_GUIDE.md) and [CH9350L User Guide](docs/CH9350L_GUIDE.md) for hardware-specific setup and usage.\n\nMouse capture is provided using the parameter `--mouse` (`-e`). Appropriate system permissions (Privacy and Security) may be required on macOS.\n\nFor live video, use the GUI (`kvm-gui`). See [MODES.md](docs/MODES.md) for keyboard capture mode options.\n\n## Troubleshooting\n\n**Permissions errors on Linux**:\nif your system user does not have serial write permissions (resulting in a permission error), you can add your user to the `dialout` group: e.g. `sudo usermod -a -G dialout $USER`. You must fully log out of the system to apply the change.\n\n**Difficulty installing requirements**: If you get `command not found: pip` or similar when installing requirements, try: `python -m pip [...]` to run pip instead.\n\n## Acknowledgements\nWith thanks to [@beijixiaohu](https://github.com/beijixiaohu), the author of the [ch9329Comm PyPi package](https://pypi.org/project/ch9329Comm/) and [GitHub repo](https://github.com/beijixiaohu/CH9329_COMM/) (in Chinese), some code of which is re-used under the MIT License.\n\nThank you, once again, to everyone who has [contributed](CONTRIBUTING.md) to this project.\n\n## License\n(c) 2023-26 Samantha Finnigan and contributors (except where acknowledged) and released under [MIT License](LICENSE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsjmf%2Fkvm-serial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsjmf%2Fkvm-serial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsjmf%2Fkvm-serial/lists"}