Warning

This documentation is actively being updated as the project evolves and may not be complete in all areas.

NanoKVM Driver

jumpstarter-driver-nanokvm provides comprehensive support for NanoKVM devices thanks to the amazing python-nanokvm library, enabling remote KVM (Keyboard, Video, Mouse) control over the network.

Features

  • Video Streaming: Access live video feed from the connected device

  • Snapshot Capture: Take screenshots of the video stream

  • Keyboard Control: Send text and keystrokes via HID emulation

  • Mouse Control: Full mouse support via WebSocket

    • Absolute positioning (0.0-1.0 normalized coordinates)

    • Relative movement (0.0-1.0 normalized, where 1.0 = full screen)

    • Left/right/middle button clicks

    • Mouse wheel scrolling

  • Image Management: Virtual disk and CD-ROM control

    • Mount/unmount disk and CD-ROM images

    • Download images from URLs

    • Check mounted image status

    • Monitor download progress

  • Device Management: Get device info, reboot the NanoKVM

  • Composite Driver: Access all functionality through a unified interface

Installation

$ pip3 install --extra-index-url https://pkg.jumpstarter.dev/simple jumpstarter-driver-nanokvm

Configuration

Basic Configuration

export:
  nanokvm:
    type: jumpstarter_driver_nanokvm.driver.NanoKVM
    config:
      host: "nanokvm.local"  # Hostname or IP address
      username: "admin"      # Default NanoKVM web interface username
      password: "admin"      # Default NanoKVM web interface password

Advanced Configuration

export:
  nanokvm:
    type: jumpstarter_driver_nanokvm.driver.NanoKVM
    config:
      host: "192.168.1.100"
      username: "admin"
      password: "your-password"
      # Optional: SSH access for serial console (future feature)
      enable_serial: false
      ssh_username: "root"
      ssh_password: "root"
      ssh_port: 22

Config Parameters

Parameter

Description

Type

Required

Default

host

NanoKVM hostname or IP address

str

yes

username

Web interface username

str

no

“admin”

password

Web interface password

str

no

“admin”

enable_serial

Enable serial console access via SSH

bool

no

false

ssh_username

SSH username for serial console

str

no

“root”

ssh_password

SSH password for serial console

str

no

“root”

ssh_port

SSH port for serial console

int

no

22

Architecture

The NanoKVM driver is a composite driver that provides three main interfaces:

  1. video: Video streaming and snapshot capture

  2. hid: Keyboard and mouse HID control

  3. serial: Serial console access (optional, future feature)

API Reference

NanoKVMClient

class jumpstarter_driver_nanokvm.client.NanoKVMClient

Client interface for NanoKVM devices

This composite client provides access to all NanoKVM functionality: - video: Video streaming and snapshots - hid: Keyboard and mouse control - serial: Serial console access (if enabled)

Example:

# Get a snapshot
image = nanokvm.video.snapshot()

# Paste text
nanokvm.hid.paste_text("Hello from Jumpstarter!")

# Get device info
info = nanokvm.get_info()
print(f"Device: {info['mdns']}")
download_image(url: str) dict

Start downloading an image from a URL

Args:

url: URL of the image to download

Returns:

Dictionary with download status, file, and percentage

Example:

status = nanokvm.download_image("https://example.com/image.iso")
print(f"Download: {status['status']}, File: {status['file']}, {status['percentage']}%")
get_cdrom_status() bool

Check if the mounted image is in CD-ROM mode

Returns:

Boolean indicating if CD-ROM mode is active (True=CD-ROM, False=disk)

Example:

if nanokvm.get_cdrom_status():
    print("CD-ROM mode is enabled")
get_image_download_status() dict

Get the status of an ongoing image download

Returns:

Dictionary with download status, file, and percentage complete

Example:

status = nanokvm.get_image_download_status()
print(f"Status: {status['status']}, File: {status['file']}, {status['percentage']}%")
get_info() dict

Get device information

Returns:

Dictionary containing device information: - ips: List of IP addresses - mdns: mDNS hostname - image: Image version - application: Application version - device_key: Device key

get_mounted_image() str | None

Get information about mounted image

Returns:

String with mounted image file path, or None if no image mounted

Example:

file = nanokvm.get_mounted_image()
if file:
    print(f"Mounted: {file}")
is_image_download_enabled() bool

Check if the /data partition allows image downloads

Returns:

Boolean indicating if image downloads are enabled

Example:

if nanokvm.is_image_download_enabled():
    print("Image downloads are available")
mount_image(file: str = '', cdrom: bool = False)

Mount an image file or unmount if file is empty string

Args:

file: Path to image file on the NanoKVM device, or empty string to unmount cdrom: Whether to mount as CD-ROM (True) or disk (False)

Note:

Unmounting may fail if image is currently in use. If unmount fails, you may need to power cycle the connected device first.

Example:

# Mount a disk image
nanokvm.mount_image("/path/to/disk.img", cdrom=False)

# Mount a CD-ROM image
nanokvm.mount_image("/path/to/cdrom.iso", cdrom=True)

# Unmount
nanokvm.mount_image("") or nanokvm.mount_image()
reboot()

Reboot the NanoKVM device

Warning:

This will reboot the NanoKVM itself, not the connected device. The connection will be lost during reboot.

NanoKVMVideoClient

class jumpstarter_driver_nanokvm.client.NanoKVMVideoClient

Client interface for NanoKVM video streaming

This client provides methods to access video stream and snapshots from the NanoKVM device.

snapshot(skip_frames: int = 3) Image

Get a snapshot image from the video stream

Returns:

PIL Image object of the snapshot

NanoKVMHIDClient

class jumpstarter_driver_nanokvm.client.NanoKVMHIDClient

Client interface for NanoKVM HID (Keyboard/Mouse) control

This client provides methods to send keyboard and mouse events to the device connected to the NanoKVM.

mouse_click(button: MouseButton | str = 'left', x: float | None = None, y: float | None = None)

Click a mouse button

Args:

button: Mouse button to click (MouseButton enum or “left”, “right”, “middle” string) x: Optional X coordinate (0.0 to 1.0) for absolute positioning before click y: Optional Y coordinate (0.0 to 1.0) for absolute positioning before click

Example:

# Using string (backward compatible)
hid.mouse_click("left")
hid.mouse_click("left", 0.5, 0.5)

# Using MouseButton enum (recommended)
hid.mouse_click(MouseButton.LEFT)
hid.mouse_click(MouseButton.RIGHT, 0.75, 0.25)
mouse_move_abs(x: float, y: float)

Move mouse to absolute coordinates

Args:

x: X coordinate (0.0 to 1.0, where 0.0 is left and 1.0 is right) y: Y coordinate (0.0 to 1.0, where 0.0 is top and 1.0 is bottom)

Example:

# Move to center of screen
hid.mouse_move_abs(0.5, 0.5)

# Move to top-left corner
hid.mouse_move_abs(0.0, 0.0)

# Move to bottom-right corner
hid.mouse_move_abs(1.0, 1.0)
mouse_move_rel(dx: float, dy: float)

Move mouse relative to current position

Args:

dx: X movement delta (-1.0 to 1.0, where 1.0 is full screen width) dy: Y movement delta (-1.0 to 1.0, where 1.0 is full screen height)

Example:

# Move right by 10% of screen width and down by 10%
hid.mouse_move_rel(0.1, 0.1)

# Move left by 20%
hid.mouse_move_rel(-0.2, 0.0)
mouse_scroll(dx: int, dy: int)

Scroll the mouse wheel

Args:

dx: Horizontal scroll amount dy: Vertical scroll amount (positive=up, negative=down)

Example:

# Scroll up
hid.mouse_scroll(0, 5)

# Scroll down
hid.mouse_scroll(0, -5)
paste_text(text: str)

Paste text via keyboard HID simulation

Args:
text: Text to paste. Supports limited character set:

alphanumeric, basic punctuation, and common symbols

Example:

hid.paste_text("Hello, World!")
hid.paste_text("ls -la\n")
press_key(key: str)

Press a key by pasting a single character

Args:

key: Single character or escape sequence to press

Example:

hid.press_key("a")      # Type 'a'
hid.press_key("A")      # Type 'A'
hid.press_key("\n")    # Press Enter
hid.press_key("\t")    # Press Tab
reset_hid()

Reset the HID subsystem

This can help recover from HID communication issues.

CLI Usage

The NanoKVM driver provides CLI commands accessible through the jmp shell command:

Main Commands

# Get device information
j nanokvm info

# Reboot the NanoKVM device (with confirmation)
j nanokvm reboot

Video Commands

# Take a snapshot (saves to snapshot.jpg by default)
j nanokvm video snapshot

# Take a snapshot with custom filename
j nanokvm video snapshot my_screenshot.jpg

HID Commands

Keyboard Commands

# Paste text via keyboard HID
j nanokvm hid paste "Hello, World!"

# Send commands with newline (use $'...' syntax in bash for escape sequences)
j nanokvm hid paste $'root\n'

# Or use double backslash
j nanokvm hid paste "root\\n"

# Send multiple lines
j nanokvm hid paste $'ls -la\ndate\n'

# Press a single key
j nanokvm hid press "a"

# Press special keys
j nanokvm hid press $'\n'    # Enter
j nanokvm hid press $'\t'    # Tab

# Reset HID subsystem if it's not responding
j nanokvm hid reset

Mouse Commands

# Move mouse to absolute coordinates (0.0-1.0, where 0.0=top/left, 1.0=bottom/right)
j nanokvm hid mouse move 0.5 0.5     # Center of screen
j nanokvm hid mouse move 0.0 0.0     # Top-left corner
j nanokvm hid mouse move 1.0 1.0     # Bottom-right corner

# Move mouse relatively (-1.0 to 1.0, where 1.0 = full screen width/height)
j nanokvm hid mouse move-rel 0.1 0.1   # Move right and down by 10% of screen
j nanokvm hid mouse move-rel -0.2 0.0  # Move left by 20% of screen width

# Click at current position (default: left button)
j nanokvm hid mouse click

# Click with specific button
j nanokvm hid mouse click --button right

# Click at specific coordinates
j nanokvm hid mouse click --x 0.5 --y 0.5 --button left

# Scroll (default: down 5 units)
j nanokvm hid mouse scroll

# Scroll up
j nanokvm hid mouse scroll --dy 5

# Scroll down
j nanokvm hid mouse scroll --dy -5

Image Management Commands

# Mount a disk image
j nanokvm image mount /data/myimage.img

# Mount a CD-ROM image
j nanokvm image mount /data/installer.iso --cdrom

# Unmount current image
j nanokvm image unmount

# Check mounted image status
j nanokvm image status

# Check if mounted image is in CD-ROM mode
j nanokvm image cdrom-status

# Download an image from URL
j nanokvm image download https://example.com/image.iso

# Check if image downloads are enabled
j nanokvm image download-enabled

# Check download progress
j nanokvm image download-status

Example Session

# Connect to the exporter
jmp shell -l my=device

# Inside the shell, use the commands
j nanokvm info
j nanokvm video snapshot my_screen.jpg

# Mount a CD-ROM image
j nanokvm image mount /data/installer.iso --cdrom
j nanokvm image status

# Control the mouse and keyboard
j nanokvm hid mouse move 0.5 0.5
j nanokvm hid mouse click
j nanokvm hid paste "echo 'Hello from NanoKVM'\n"

Usage Examples

Basic Setup

image = nanokvm.video.snapshot()
image.save("snapshot.jpg")
print(f"Snapshot size: {image.size}")

Keyboard Control

# Paste text to the connected device
nanokvm.hid.paste_text("Hello from Jumpstarter!\n")

# Send commands
nanokvm.hid.paste_text("ls -la\n")

# Press individual keys
nanokvm.hid.press_key("a")
nanokvm.hid.press_key("\n")  # Enter
nanokvm.hid.press_key("\t")  # Tab

Mouse Control

# Move mouse to center of screen (normalized 0.0-1.0 coordinates)
nanokvm.hid.mouse_move_abs(0.5, 0.5)

# Move to top-left corner
nanokvm.hid.mouse_move_abs(0.0, 0.0)

# Move to bottom-right corner
nanokvm.hid.mouse_move_abs(1.0, 1.0)

# Click left button
nanokvm.hid.mouse_click("left")

# Click at specific coordinates
nanokvm.hid.mouse_click("left", x=0.5, y=0.25)

# Move mouse relatively (normalized -1.0 to 1.0, where 1.0 = full screen)
nanokvm.hid.mouse_move_rel(0.1, 0.1)   # Move right/down by 10% of screen
nanokvm.hid.mouse_move_rel(-0.2, 0.0)  # Move left by 20% of screen width

# Scroll up
nanokvm.hid.mouse_scroll(0, 5)

# Scroll down
nanokvm.hid.mouse_scroll(0, -5)

Image Management

# Mount a disk image
nanokvm.mount_image("/data/myimage.img", cdrom=False)

# Mount a CD-ROM image
nanokvm.mount_image("/data/installer.iso", cdrom=True)

# Unmount current image
nanokvm.mount_image("")

# Get mounted image info
file = nanokvm.get_mounted_image()
if file:
    print(f"Mounted: {file}")
    is_cdrom = nanokvm.get_cdrom_status()
    print(f"Mode: {'CD-ROM' if is_cdrom else 'Disk'}")

# Download an image
status = nanokvm.download_image("https://example.com/image.iso")
print(f"Download: {status['status']}, File: {status['file']}")

# Check if downloads are enabled
if nanokvm.is_image_download_enabled():
    print("Downloads are available")

# Monitor download progress
status = nanokvm.get_image_download_status()
print(f"Status: {status['status']}, Progress: {status['percentage']}")

Device Management

# Get device info
info = nanokvm.get_info()
print(f"Device: {info['mdns']}")
print(f"IPs: {info['ips']}")
print(f"Application version: {info['application']}")

# Reset HID
nanokvm.hid.reset_hid()

Character Support for paste_text()

The paste_text() method supports a limited character set due to HID keyboard constraints:

  • Alphanumeric: A-Z, a-z, 0-9

  • Punctuation: `~!@#$%^&*()-_=+[]{}\|;:'",.<>/?

  • Whitespace: Tab (\t), Newline (\n), Space

  • Not supported: Extended Unicode, emoji, special control characters