### Install and start Tailscale client Source: https://docs.pikvm.org/tailscale/ These commands enable write mode, install the tailscale-pikvm package, enable and start the tailscaled service, and bring up the Tailscale interface. The comment notes to run pacman -Syy first if you skipped the update step. ```bash [root@pikvm ~]# rw # If you were afraid to pikvm-update above first run pacman -Syy [root@pikvm ~]# pacman -S tailscale-pikvm [root@pikvm ~]# systemctl enable --now tailscaled [root@pikvm ~]# tailscale up ``` -------------------------------- ### Example wpa_supplicant-wlan0.conf before WPA3 edit Source: https://docs.pikvm.org/wifi/ Shows the default wpa_supplicant configuration with a hashed psk. This is the starting point for enabling WPA3 support. ```conf network={ ssid="MyNetwork" #psk="P@assw0rd" psk=4134d31e95e6387761d485796310894b1ac5e9bb86b3b96e0dd3473cea440014 } ``` -------------------------------- ### Default preset configuration in /etc/kvmd/override.yaml Source: https://docs.pikvm.org/usb/ Example configuration for enabling USB Serial Port and Microphone, with the serial port not started by default. The 'start' parameter is available for all USB devices. ```yaml otg: devices: serial: enabled: true start: false audio: enabled: true ``` -------------------------------- ### Install Bluetooth packages Source: https://docs.pikvm.org/bluetooth_hid/ Switch filesystem to RW-mode and install bluez, bluez-utils, and raspberrypi-bluetooth packages. ```bash # rw # pacman -Syy # pacman -Su bluez bluez-utils raspberrypi-bluetooth ``` -------------------------------- ### Enable and start NetworkManager and ModemManager Source: https://docs.pikvm.org/modem/ Enable and start the services for modem management. ```bash [root@pikvm ~]# systemctl enable --now NetworkManager ModemManager ``` -------------------------------- ### Install NetworkManager and ModemManager Source: https://docs.pikvm.org/modem/ Install the required packages for modem management. ```bash [root@pikvm ~]# pacman -S modemmanager networkmanager ``` -------------------------------- ### Recommended configuration with LDAP external Source: https://docs.pikvm.org/auth_advanced/ Recommended setup: keep htpasswd as internal with admin user forced, and use ldap as external. Type and file are defaults in this example. ```yaml kvmd: auth: internal: #type: htpasswd force_users: [admin] #file: /etc/kvmd/htpasswd external: type: ldap ... ``` -------------------------------- ### Install ustreamer from source Source: https://docs.pikvm.org/blog/2020/09/22/we-need-help-testing-ustreamer/ Commands to install ustreamer from source on Pi-KVM. Requires root (rw) and read-only (ro) mode switches. The build uses WITH_OMX=1 and installs to /usr. ```bash # rw # mv /usr/bin/ustremer /usr/local/bin/ustreamer.bak # git clone https://github.com/pikvm/ustreamer # cd ustreamer # make -j5 WITH_OMX=1 # make PREFIX=/usr install # ro ``` -------------------------------- ### Install ftdi_eeprom Source: https://docs.pikvm.org/xh_hk4401/ Installs the ftdi_eeprom package using apt. ```bash sudo apt install ftdi_eeprom ``` -------------------------------- ### Make setup script executable Source: https://docs.pikvm.org/tailscale/ Sets the executable bit on the setup script so it can be run by systemd. ```bash [root@pikvm ~]# chmod +x /usr/local/bin/setup-tailscale-overlay.sh ``` -------------------------------- ### Example .route53.auth file Source: https://docs.pikvm.org/letsencrypt/ Example AWS credentials file format. Replace placeholders with your access key and secret access key. ```ini [default] aws_access_key_id=XXXXXX aws_secret_access_key=XXXX/XXXXX ``` -------------------------------- ### Install Cloudflare DNS plugin Source: https://docs.pikvm.org/letsencrypt/ Switch filesystem to RW and install the certbot-dns-cloudflare plugin using pacman. ```bash # rw # pacman -S certbot-dns-cloudflare ``` -------------------------------- ### Redfish Root Service Discovery - Example Output Source: https://docs.pikvm.org/api/ Example JSON response from the Redfish root service discovery endpoint. ```json { "@odata.id": "/redfish/v1", "@odata.type": "#ServiceRoot.v1_6_0.ServiceRoot", "Id": "RootService", "Name": "Root Service", "RedfishVersion": "1.6.0", "Systems": { "@odata.id": "/redfish/v1/Systems" } } ``` -------------------------------- ### Install and start chrony on PiKVM Source: https://docs.pikvm.org/latency/ Use these commands on PiKVM to install and run chrony for NTP synchronization. It stops systemd-timesyncd and starts chronyd. ```bash [root@pikvm ~]# pacman -Syy [root@pikvm ~]# pacman -S chrony [root@pikvm ~]# systemctl stop systemd-timesyncd [root@pikvm ~]# systemctl start chronyd ``` -------------------------------- ### Complete example with internet access Source: https://docs.pikvm.org/usb_ethernet/ Full configuration example for a host that can access PiKVM and has internet access. Includes allow_tcp, forward_iface wlan0, DNS servers, and network range. ```yaml otgnet: firewall: allow_tcp: [80, 443] forward_iface: wlan0 commands: post_start_cmd_append: - "--dhcp-option=6,1.1.1.1,1.0.0.1" iface: ip_cmd: - /usr/bin/ip net: 10.65.0.0/28 ``` -------------------------------- ### Install and start chrony on client Linux Source: https://docs.pikvm.org/latency/ Use these commands on a Linux client to install chrony for accurate NTP synchronization. It stops systemd-timesyncd and starts chronyd. ```bash [root@localhost ~]# pacman -Syy [root@localhost ~]# pacman -S chrony [root@localhost ~]# systemctl stop systemd-timesyncd [root@localhost ~]# systemctl start chronyd ``` -------------------------------- ### Get GPIO state - example output Source: https://docs.pikvm.org/api/ Example JSON response from the GET /api/gpio endpoint showing the model scheme and current state of GPIO outputs. ```json { "ok": true, "result": { "model": { "scheme": { "inputs": {}, "outputs": { "__v3_usb_breaker__": { "hw": { "driver": "__gpio__", "pin": "5" }, "pulse": { "delay": 0.0, "max_delay": 0.0, "min_delay": 0.0 }, "switch": true } } }, "view": { "header": { "title": [ { "text": "GPIO", "type": "label" } ] }, "table": [] } }, "state": { "inputs": {}, "outputs": { "__v3_usb_breaker__": { "busy": false, "online": true, "state": true } } } } } ``` -------------------------------- ### Prepare NFS storage directories Source: https://docs.pikvm.org/msd/ Install nfs-utils, remount the MSD as read-write, create the NFS mount point directories, and remount as read-only. Run as root. ```bash [root@pikvm ~]# rw [root@pikvm ~]# pacman -S nfs-utils [root@pikvm ~]# kvmd-helper-otgmsd-remount rw [root@pikvm ~]# mkdir -p /var/lib/kvmd/msd/NFS_Primary [root@pikvm ~]# mkdir -p /var/lib/kvmd/msd/NFS_Secondary [root@pikvm ~]# kvmd-helper-otgmsd-remount ro ``` -------------------------------- ### Register PiKVM with NetBird using a setup key Source: https://docs.pikvm.org/netbird/ Recommended registration method for headless devices. Uses a setup key from the NetBird dashboard and the --disable-dns flag to prevent writes to /etc/resolv.conf on the read-only filesystem. ```bash [root@pikvm ~]# netbird up --setup-key --disable-dns ``` -------------------------------- ### Example output for system info Source: https://docs.pikvm.org/api/ Sample JSON response from the /api/info endpoint showing hardware health and platform details. Includes CPU, memory, temperature, throttling flags, and board information. ```json { "ok": true, "result": { "hw": { "health": { "cpu": { "percent": 2 }, "mem": { "available": 1568993280, "percent": 14.6, "total": 1836331008 }, "temp": { "cpu": 45.277 }, "throttling": { "ignore_past": false, "parsed_flags": { "freq_capped": { "now": false, "past": false }, "throttled": { "now": false, "past": false }, "undervoltage": { "now": false, "past": false } }, "raw_flags": 0 } }, "platform": { "base": "Raspberry Pi 4 Model B Rev 1.5", "board": "rpi4", "model": "v3", "serial": "10000000C8DA432D", "type": "rpi", "video": "hdmi" } } } } ``` -------------------------------- ### Incorrect YAML merging example Source: https://docs.pikvm.org/cheatsheet/ Shows the wrong way to define sections under the same key in YAML. This will cause errors when starting services. ```yaml kvmd: gpio: drivers: ... kvmd: gpio: scheme: ... ``` -------------------------------- ### Get Switch state - curl example Source: https://docs.pikvm.org/api/ Retrieves the current state of the PiKVM Switch. Uses basic authentication with default admin credentials. ```bash $ curl -k -u admin:admin https:///api/switch ``` -------------------------------- ### Install platformio-core and avrdude Source: https://docs.pikvm.org/flashing_hid/ Required for recent PiKVM images that no longer ship with flashing tools. Run these commands as root. ```bash pacman -Syu pacman -S platformio-core avrdude ``` -------------------------------- ### Create systemd unit for Tailscale overlay Source: https://docs.pikvm.org/tailscale/ Defines a oneshot systemd service that runs the setup script after local filesystems and /tmp are mounted, but before tailscaled.service starts. ```ini [Unit] Description=Setup overlayfs for Tailscale After=local-fs.target tmp.mount Before=tailscaled.service [Service] Type=oneshot ExecStart=/usr/local/bin/setup-tailscale-overlay.sh RemainAfterExit=yes [Install] WantedBy=multi-user.target ``` -------------------------------- ### Example configuration for PS/2 keyboard with USB absolute mouse Source: https://docs.pikvm.org/arduino_hid/ This example shows how to comment out the default dynamic switching lines and uncomment the PS/2 keyboard + USB absolute mouse lines in platformio-avr.ini. Use this to select the PS/2 firmware. ```ini ... # ----- The default config with dynamic switching ----- # -DHID_DYNAMIC # -DHID_WITH_USB # -DHID_SET_USB_KBD # -DHID_SET_USB_MOUSE_ABS # ----- PS2 keyboard only ----- ... # ----- PS2 keyboard + USB absolute mouse ----- -DHID_WITH_USB -DHID_WITH_PS2 -DHID_SET_PS2_KBD -DHID_SET_USB_MOUSE_ABS # ----- PS2 keyboard + USB relative mouse ----- ... ``` -------------------------------- ### Install Docker and required tools on Ubuntu Source: https://docs.pikvm.org/building_os/ Commands to install git, make, curl, binutils, and docker.io on Ubuntu. After running these, re-login to apply the usermod group changes. ```bash [user@localhost ~]$ sudo apt-get install git make curl binutils -y [user@localhost ~]$ sudo apt-get install docker.io [user@localhost ~]$ sudo usermod -aG docker $USER ``` -------------------------------- ### Create systemd unit for NetBird overlay Source: https://docs.pikvm.org/netbird/ Systemd unit file that runs the overlay setup before NetBird starts and saves state back on stop. Save as /etc/systemd/system/netbird-overlay.service. ```ini [Unit] Description=Setup tmpfs overlay for NetBird After=local-fs.target tmp.mount Before=netbird@netbird.service [Service] Type=oneshot ExecStart=/usr/local/bin/setup-netbird-overlay.sh ExecStop=/bin/sh -c 'cp -a /tmp/netbird-state/. /root/netbird-state/' RemainAfterExit=yes [Install] WantedBy=multi-user.target ``` -------------------------------- ### Create config.mk for target system Source: https://docs.pikvm.org/building_os/ Example config.mk file. Set BOARD and PLATFORM variables. If your password contains #, escape it with a backslash (e.g., ROOT_PASSWD = pass\#word). ```makefile # Base board BOARD = rpi4 # Hardware configuration PLATFORM = v2-hdmi # Target hostname HOSTNAME = pikvm # ru_RU, etc. UTF-8 only LOCALE = en_US # See /usr/share/zoneinfo TIMEZONE = Europe/Nicosia # For SSH root user ROOT_PASSWD = change_me # Web UI credentials: user=admin, password=admin_change_me WEBUI_ADMIN_PASSWD = admin_change_me # IPMI credentials: password=ipmi_change_me IPMI_ADMIN_PASSWD = ipmi_change_me ``` -------------------------------- ### Get HID devices state with curl Source: https://docs.pikvm.org/api/ Sends a GET request to /api/hid to retrieve the current HID device state. The example uses basic authentication with admin:admin and the -k flag to skip certificate verification. The response includes device status, jiggler settings, keyboard and mouse outputs. ```bash $ curl -k -u admin:admin https:///api/hid ``` ```json { "ok": true, "result": { "busy": false, "connected": null, "enabled": true, "jiggler": { "active": false, "enabled": true, "interval": 60 }, "keyboard": { "leds": { "caps": false, "num": false, "scroll": false }, "online": false, "outputs": { "active": "", "available": [] } }, "mouse": { "absolute": true, "online": false, "outputs": { "active": "usb", "available": [ "usb", "usb_rel" ] } }, "online": true } } ``` -------------------------------- ### Create Tailscale overlay setup script Source: https://docs.pikvm.org/tailscale/ Creates a bash script that mounts a tmpfs, prepares overlay directories, mounts an overlayfs with /root/tailscale-state as lowerdir, and bind-mounts the merged directory to /var/lib/tailscale. ```bash #!/bin/bash set -e # Make tmpfs for tailscale overlay mkdir -p /tmp/tailscale-tmpfs mountpoint -q /tmp/tailscale-tmpfs || mount -t tmpfs tmpfs /tmp/tailscale-tmpfs # Prepare overlay dirs mkdir -p /tmp/tailscale-tmpfs/upper mkdir -p /tmp/tailscale-tmpfs/work mkdir -p /tmp/tailscale-merged # Mount overlay (lowerdir = persistent readonly state in /root) mountpoint -q /tmp/tailscale-merged || mount -t overlay overlay \ -o lowerdir=/root/tailscale-state,upperdir=/tmp/tailscale-tmpfs/upper,workdir=/tmp/tailscale-tmpfs/work \ /tmp/tailscale-merged # Bind merged to /var/lib/tailscale mountpoint -q /var/lib/tailscale && umount /var/lib/tailscale || true mount --bind /tmp/tailscale-merged /var/lib/tailscale ``` -------------------------------- ### GET /api/streamer/snapshot Source: https://docs.pikvm.org/api/ Captures a snapshot from the video stream. Can optionally perform OCR text recognition or generate a preview image. For optical character recognition, the coordinates origin starts at top left. ```APIDOC ## GET /api/streamer/snapshot ### Description Captures a snapshot from the video stream. Can optionally perform OCR text recognition or generate a preview image. For optical character recognition, the coordinates origin starts at top left. ### Method GET ### Endpoint /api/streamer/snapshot ### Parameters #### Query Parameters - **save** (boolean) - Optional - Whether to save the snapshot, default: `false`. Enable: `1`, `true`, or `yes`. Disable: `0`, `false`, or `no`. - **load** (boolean) - Optional - Whether to load an existing snapshot, default: `false`. Enable: `1`, `true`, or `yes`. Disable: `0`, `false`, or `no`. - **allow_offline** (boolean) - Optional - Whether to allow taking snapshots when offline, default: `false`. Enable: `1`, `true`, or `yes`. Disable: `0`, `false`, or `no`. - **ocr** (boolean) - Optional - Whether to perform OCR text recognition on the snapshot, default: `false`. Enable: `1`, `true`, or `yes`. Disable: `0`, `false`, or `no`. - **ocr_langs** (string) - Optional - Comma-separated list of language codes for OCR recognition. Typically, a 3-letter code, such as `eng` for English or `deu` for German. Run `pacman -Ss tesseract-data` on PiKVM to get the full list. - **ocr_left** (integer) - Optional - X coordinate of the top left corner of the OCR region, default: `-1`. Acceptable values: `≥0`. - **ocr_top** (integer) - Optional - Y coordinate of the top left corner of the OCR region, default: `-1`. Acceptable values: `≥0`. - **ocr_right** (integer) - Optional - Width of the OCR region, default: `-1`. Acceptable values: `≥0`. - **ocr_bottom** (integer) - Optional - Height of the OCR region, default: `-1`. Acceptable values: `≥0`. - **preview** (boolean) - Optional - Whether to generate a preview image, default: `false`. Enable: `1`, `true`, or `yes`. Disable: `0`, `false`, or `no`. - **preview_max_width** (integer) - Optional - Maximum width for preview image, default: `0`. Any positive integer value. - **preview_max_height** (integer) - Optional - Maximum height for preview image, default: `0`. Any positive integer value. - **preview_quality** (integer) - Optional - JPEG quality for preview (valid stream quality value), default: `80`. Any integer value in the 0..100 range. ### Request Example ``` $ curl -k \ -u admin:admin \ 'https:///api/streamer/snapshot?save=1&preview_quality=95' \ --output=file.jpg ``` ### Response #### Success Response - When `ocr=true`: Content-Type: `text/plain`, Body: Recognized text from the image. - When `preview=true` or default: Content-Type: `image/jpeg`, Body: JPEG image data (either preview or full snapshot). #### Error Response - When snapshot unavailable: Status: 503 Service Unavailable, Error: UnavailableError. #### Response Example ``` % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 107k 100 107k 0 0 619k 0 --:--:-- --:--:-- --:--:-- 619k ``` ``` -------------------------------- ### Create /var/lib/bluetooth and add tmpfs mountpoint Source: https://docs.pikvm.org/bluetooth_hid/ Create an empty directory for Bluetooth data and add a tmpfs mountpoint to /etc/fstab. ```bash # mkdir /var/lib/bluetooth # echo 'tmpfs /var/lib/bluetooth tmpfs nodev,nosuid,mode=0755 0 0' >> /etc/fstab ``` -------------------------------- ### Start video stream with websocat Source: https://docs.pikvm.org/video/ Opens a WebSocket connection to the PiKVM stream endpoint. Requires ffmpeg and websocat installed. Assumes PiKVM is at https://pikvm with a self-signed certificate. Keep this command running in the first terminal. ```bash [user@host ~]$ websocat -k wss://pikvm/api/ws?stream=1 -H X-KVMD-User:admin -H X-KVMD-Passwd:admin ``` -------------------------------- ### Basic USC configuration example Source: https://docs.pikvm.org/auth_advanced/ Configuration example allowing processes run from users `monitoring` and `backup-service` to authenticate via Unix Socket Credentials. Both users must exist prior to listing them in the configuration. ```yaml kvmd: auth: usc: users: ["monitoring", "backup-service"] ``` -------------------------------- ### Example output for GET /api/atx Source: https://docs.pikvm.org/api/ JSON response showing the current ATX state. The 'busy' field indicates if ATX is busy performing an operation and does not accept commands. The 'leds' object shows HDD and power LED states. ```json { "ok": true, "result": { "busy": false, // True if ATX is busy performing an operation and does not accept commands "enabled": true, "leds": { "hdd": false, "power": false } } } ```