Cases for 3D printing¶
+PiKVM V3 HAT cases¶
+-
+
- v3.3 model (Kickstarter, Store) +
- Unofficial but great v3.3 case mod for Noctua fan +
- v3.2 model (Pre-release) +
commit 6aefecaf18fb6526e57ea1c4ff1b7e19612c66ba Author: <> Date: Tue Apr 9 16:41:11 2024 +0000 Deployed c7269fa with MkDocs version: 1.5.3 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/3d_printing/index.html b/3d_printing/index.html new file mode 100644 index 0000000..ef8c7cd --- /dev/null +++ b/3d_printing/index.html @@ -0,0 +1,1812 @@ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +Double-check the correct assembly of the device, and make sure that you have connected + all the necessary cables to the host: USB, HDMI and ATX.
+Flash the memory card with PiKVM OS + and insert it to Raspberry Pi.
+Carefully read and follow the First Steps Guide.
+ It describes how to perform the first power-on, how to find PiKVM on the network, login, change passwords, and so on.
+ Follow the steps described there and come back to this page.
Just reminding again:
+PiKVM comes with the following default passwords:
+root
, password root
.admin
, password admin
, no 2FA code.These are two separate entities with independent accounts.
+To change passwords, you will need to use the console access via SSH or the Web Terminal.
+If you are using the Web Terminal, enter the su -
command to get the root
access (enter the root
user password).
[root@pikvm ~]# rw
+[root@pikvm ~]# passwd root
+[root@pikvm ~]# kvmd-htpasswd set admin
+[root@pikvm ~]# ro
+
If you require additional user for the Web UI access, use the following:
+[root@pikvm ~]# kvmd-htpasswd set <user> # Set a new user with password or change of an existing one
+[root@pikvm ~]# kvmd-htpasswd del <user> # Remove/delete a user
+
Optionally you can enable the two-factor authentication for more security.
+Changing the VNCAuth passkey and IPMI password at the first start of PiKVM is not required, +since these services are disabled by default. But it is here just so that you remember their existence.
+Try to manage the computer using PiKVM with the Web Interface.
+ Make sure that you get an image and both keyboard and mouse are working.
+ If something doesn't work, check out our FAQ (it's really useful).
+ If nothing helped, you can get support in our Discord chat.
Many USB video capture devices tell the server's video card that the HDMI cable is supposedly disconnected. +This may lead to the fact that if you boot the server without an active stream, the server will not detect +your capture card. This is easy to fix:
+Switch filesystem to RW-mode: +
[root@pikvm ~]# rw
+
Edit file /etc/kvmd/override.yaml
and add these lines:
+
kvmd:
+ streamer:
+ forever: true
+ cmd_append: [--slowdown]
+
Finish: +
[root@pikvm ~]# ro
+[root@pikvm ~]# systemctl restart kvmd
+
Check that everything is working.
+Configure access to PiKVM from the Internet using port forwarding + or Tailscale VPN, if you need it.
+Explore the features of PiKVM using the site's table of contents and have fun!
+With this part, you will be able to remotely turn on, turn off and restart your computer!
+This can be partially replaced by using Wake-on-LAN in the software, but it will not allow +to reboot a hung system, and it is not as reliable as an ATX controller. Sometimes the Wake-on-LAN +on the host just stops working, for its own or network reasons.
Insert the flexible flat cable of the HDMI-CSI bridge into the narrow white connector on the Raspberry Pi
+(the closest one to big USB sockets). It is labeled CAMERA
. To insert you need to open the connector first.
+On the Raspberry Pi side you can gently lift the black part up and a little bit sideways:
Opening the MIPI CSI slot on the Raspberry Pi | +
---|
+ |
For the HDMI-CSI bridge this operation depends on the version you bought. +Either pull it gently up as on the Raspberry or push it sideways. +Make sure that the cable is inserted on the correct side and until it stops, and then push the black latch back. +Never connect or disconnect the flat cable from a powered device. This is not Plug-and-Play, and you can damage it. +Also use only the cable that was included with the device package, or make sure that the third-party cable has the correct pinout.
+HDMI-CSI bridge connected to Raspberry Pi 4 | +
---|
+ |
Connect USB dongle to exactly this port. It is bound in the software so the OS does not confuse the video device with something else.
+Raspberry Pi 2 and 3 | +Raspberry Pi 4 | +
---|---|
+ | + |
There are many revisions of the Raspberry Pi boards and you may come across one that we haven't tested. +If the binding fails, the device will be available for all ports. +Everything will work, but if you use a webcam and Linux mistakes it for a dongle, +write to us and we will fix it.
To control the power, two display LEDs (power and HDD activity) and two buttons (power and reset) are provided +on the front panel of the computer case. They are connected by wires to pins on the motherboard.
+ +All you have to do is connect the PiKVM ATX controller to their wires by making a parallel connection. +Please note that the pinout differs on different motherboards, so before you continue, +check the documentation on your motherboard for correct pinout.
+The following illustration shows how the connection between the power LED and the power button should be performed:
+ +On the left are the wires from the PiKVM ATX controller, the pad in the middle indicates the pins on the motherboard, +and on the right are the LED and button of the target host. The implementation of this scheme is left to your discretion +and can be performed, for example, by cutting wires and performing twisting, followed by insulation with duct tape.
+Be careful and respect the polarity of the LEDs. The polarity of the button does not matter (they have no polarity at all). +The connection of HDD LED and reset switch is performed in the same way.
PiKVM + Multiport Switches compatibility
+Please note that this switch requires a USB port for control. The following devices can provide this:
+The following devices are not compatible:
+PiKVM comes with the following default passwords:
+root
, password root
.admin
, password admin
, no 2FA code.These are two separate entities with independent accounts.
+To change passwords, you will need to use the console access via SSH or the Web Terminal.
+If you are using the Web Terminal, enter the su -
command to get the root
access (enter the root
user password).
[root@pikvm ~]# rw
+[root@pikvm ~]# passwd root
+[root@pikvm ~]# kvmd-htpasswd set admin
+[root@pikvm ~]# ro
+
If you require additional user for the Web UI access, use the following:
+[root@pikvm ~]# kvmd-htpasswd set <user> # Set a new user with password or change of an existing one
+[root@pikvm ~]# kvmd-htpasswd del <user> # Remove/delete a user
+
Optionally you can enable the two-factor authentication for more security.
+Changing the VNCAuth passkey and IPMI password at the first start of PiKVM is not required, +since these services are disabled by default. But it is here just so that you remember their existence.
+To upload the firmware to Pico HID, you can use any computer with a USB port.
+pico-hid.uf2
.pico-hid.uf2
file to this flash drive.x1 Raspberry Pi Pico board with soldered pins.
+x1 USB-A to Micro-USB cable.
+x10 dupont wires female-female.
+x1 1N5819 diode. It's optional but strongly recommended. Any similar one will do.
+Warning
+The diode is needed to provide power to the Pico HID regardless of the target host state, +which prevents the backpowering problem. It will allow you to keep the keyboard buttons pressed +during the target host power cycle, which is, for example, important for MacOS to get into the boot menu.
+Do not connect the red wire (the VSYS (Pico) -> 5V (Pi)
line) without a diode.
+If you can't find a diode, don't connect this wire at all.
To update, run following commands under the root
user:
[root@pikvm ~]# pikvm-update
+
If you encounter an error like:
+[root@pikvm ~]# pikvm-update
+bash: pikvm-update: command not found
+
It's most likely you have an old OS release. You can update the OS as follows:
+[root@pikvm ~]# curl https://files.pikvm.org/update-os.sh | bash
+
Next time you will be able to use the usual method with pikvm-update
.
TL;DR: By default, you can add only one additional device to choose from, such as USB Ethernet, or USB Serial, or an extra Mass Storage Drive.
+There is a hardware limit on the number of devices that can be emulated at the same time. +Each USB device uses so-called endpoints to communicate with the host. +Depending on the type, the device consumes a different number of endpoints, +while their total number is limited by the capabilities of the chip, for Raspberry Pi it is 8.
+It is quite difficult to calculate the number of endpoints used, but in the case of PiKVM, +you can focus on the following numbers:
+Device | +Endpoints | +
---|---|
Keyboard, mouse | +1 for each | +
Mass Storage Drive | +2 for each | +
USB Ethernet, USB Serial | +3 for each | +
V2 and V3 emulates one mouse by default, V4 emulates two mouses. Thus, V2 and V3 use 4 endpoints, and V4 uses 5 by default.
+Creating an axtra Mass Storage Drive consumes additional endpoints, as well as USB Serial and USB Ethernet, +so only a limited number of devices can be selected for the final configuration, for example, one USB Ethernet.
+If you need something more non-standard, you can disable the regular Mass Storage Drive +and the additional mouse (on V4) to free up some extra endpoints.
+The kvmd-otg
service is responsible for setting up USB emulation. If the endpoint limit is exceeded,
+the service will not be able to start and no emulated USB device will work.
In the log it looks something like this:
+# journalctl -u kvmd-otg
+...
+kvmd-otg[382]: kvmd.apps.otg INFO --- ===== Preparing complete =====
+kvmd-otg[382]: kvmd.apps.otg INFO --- Enabling the gadget ...
+kvmd-otg[382]: kvmd.apps.otg INFO --- WRITE --- /sys/kernel/config/usb_gadget/kvmd/UDC
+kvmd-otg[382]: OSError: [Errno 524] Unknown error 524
+kvmd-otg[382]: During handling of the above exception, another exception occurred:
+kvmd-otg[382]: Traceback (most recent call last):
+kvmd-otg[382]: File "/usr/bin/kvmd-otg", line 9, in <module>
+kvmd-otg[382]: main()
+kvmd-otg[382]: File "/usr/lib/python3.10/site-packages/kvmd/apps/otg/__init__.py", line 348, in main
+kvmd-otg[382]: options.cmd(config)
+kvmd-otg[382]: File "/usr/lib/python3.10/site-packages/kvmd/apps/otg/__init__.py", line 278, in _cmd_start
+kvmd-otg[382]: _write(join(gadget_path, "UDC"), udc)
+kvmd-otg[382]: File "/usr/lib/python3.10/site-packages/kvmd/apps/otg/__init__.py", line 83, in _write
+kvmd-otg[382]: with open(path, "w") as file:
+kvmd-otg[382]: OSError: [Errno 524] Unknown error 524
+systemd[1]: kvmd-otg.service: Main process exited, code=exited, status=1/FAILURE
+systemd[1]: kvmd-otg.service: Failed with result 'exit-code'.
+systemd[1]: Failed to start PiKVM - OTG setup.
+
In this case, you need to disable some of the previously enabled devices and restart PiKVM.
+This document describes the PiKVM API. Since the system consists of microservices, here is a common API with a common entry point provided by Nginx. The examples above use curl
and websocat
with the -k
option to disable SSL certificate verification, since the self-signed certificateis used in the default installation.
There is a third-party library for using the PiKVM API. +Please note that this is an unofficial library, so use it carefully.
+All APIs are restricted to authentication. To make requests, you either need to auth each request individually, +or get a token and pass it as a cookie with each request.
+With enabled 2FA, you will need to add the one-time code to the password without spaces.
+That is, if the password is foobar
and the code is 123456
, then you need to use foobar123456
as the password.
The code can be generated using any TOTP library, for example in Python:
+import requests
+import pyotp
+
+user = "admin"
+passwd = "admin"
+secret = "3OBBOGSJRYRBZH35PGXURM4CMWTH3WSU" # Can be found in /etc/kvmd/totp.secret
+
+print(requests.get(
+ url="https://pikvm/api/info",
+ verify=False, # For self-signed SSL certificate
+ headers={
+ "X-KVMD-User": user,
+ "X-KVMD-Passwd": passwd + pyotp.TOTP(secret).now(),
+ },
+).text)
+
Since in the borderline case of the 2FA code lifetime, the code may be invalid, +it makes sense to either handle error 403 by repeating the request in seconds.
+A more correct way is to combine this method and check the remaining lifetime +and postpone the request if there is a second or so left. You can find out how much +time is left in this way:
+totp = pyotp.TOTP(secret)
+now = int(time.time())
+remaining = now - (now % totp.interval)
+
There are two options here:
+Using X-headers. Just pass X-KVMD-User
and X-KVMD-Passwd
with the request:
$ curl -k -H X-KVMD-User:admin -H X-KVMD-Passwd:admin https://<pikvm-ip>/api/auth/check
+
Using HTTP Basic Auth. Please note: contrary to the standard, this method DOES NOT use the WWW-Authenticate
header. HTTP Basic Auth in this implementation is intended only for compatibility with other systems, such as Prometheus.
$ curl -k -u admin:admin https://<pikvm-ip>/api/auth/check
+
Get the access token for the user using POST /api/auth/login
:
$ curl -k -v -X POST --data user=admin --data passwd=admin https://pikvm/api/auth/login
+...
+< Set-Cookie: auth_token=796cb83b11de4fcb749bc1bad14a91fb06dede84672b2f847fef1e988e6900de; Path=/
+...
+
On success the cookie auth_token
will be received with 200 OK
. On invalid user or password you will get 403 Forbidden
.
The handle GET /api/auth/check
can be used for check the auth status. Return of 200 OK
will signal that user is authenticated. If the token or any of the single-request auth methods are missing, 401 Unauthorized
will be returned. In case of incorrect credentials or token, 403 Forbidden
will be returned.
The handle POST /api/auth/logout
can be used to invalidate session token. The response codes will be similar to the previous handle.
Most of the data during the user's work with pikvm is transmitted over WebSocket. This includes mouse events, keyboard input, change the state of the various subsystems (such as ATX and Mass Storage Drive). Each event type will be described in the corresponding paragraph for its component. When connecting via WebSocket, the client receives current states as separate events. Then, as the states change, it will receive new events.
+In a normal situation, opening a socket session triggers the video streamer to start. The streamer works as long as there is at least one client connected via WebSocket. After the last connection is closed and the client timeout expires, the streamer will also be terminated.
+It is possible create a session that will not start the streamer and will not be counted when counting clients to stop the streamer. To do this, use the URL parameter stream=0
:
$ websocat -k wss://<pikvm-ip>/api/ws?stream=0 -H X-KVMD-User:admin -H X-KVMD-Passwd:admin
+
{"event_type": "gpio_model_state", "event": {"scheme": {"inputs": {"led1": {"hw": {"driver": "__gpio__", "pin": 19}}, "led2": {"hw": {"driver": "__gpio__", "pin": 16}}}, "outputs": {"button1": {"switch": false, "pulse": {"delay": 0.1, "min_delay": 0.1, "max_delay": 0.1}, "hw": {"driver": "__gpio__", "pin": 26}}, "button2": {"switch": false, "pulse": {"delay": 0.1, "min_delay": 0.1, "max_delay": 0.1}, "hw": {"driver": "__gpio__", "pin": 20}}, "relay1": {"switch": true, "pulse": {"delay": 0.1, "min_delay": 0.1, "max_delay": 0.1}, "hw": {"driver": "relay", "pin": 0}}, "relay2": {"switch": true, "pulse": {"delay": 2.0, "min_delay": 0.1, "max_delay": 5.0}, "hw": {"driver": "relay", "pin": 1}}}}, "view": {"header": {"title": "Switches"}, "table": [[{"type": "label", "text": "Generic GPIO leds"}], null, [{"type": "label", "text": "Test 1:"}, {"type": "input", "channel": "led1", "color": "green"}, {"type": "output", "channel": "button1", "text": "Click"}], [{"type": "label", "text": "Test 2:"}, {"type": "input", "channel": "led2", "color": "green"}, {"type": "output", "channel": "button2", "text": "Click"}], null, [{"type": "label", "text": "HID Relays /dev/hidraw0"}], null, [{"type": "label", "text": "Relay #1:"}, {"type": "output", "channel": "relay1", "text": "Boop 0.1"}], [{"type": "label", "text": "Relay #2:"}, {"type": "output", "channel": "relay2", "text": "Boop 2.0"}]]}}}
+{"event_type": "info_extras_state", "event": {"vnc": {"name": "VNC", "description": "Show VNC information", "icon": "share/svg/vnc.svg", "path": "vnc", "keyboard_cap": false, "daemon": "kvmd-vnc", "port": 5900, "place": 20, "enabled": true}, "ipmi": {"name": "IPMI", "description": "Show IPMI information", "icon": "share/svg/ipmi.svg", "path": "ipmi", "keyboard_cap": false, "daemon": "kvmd-ipmi", "port": 623, "place": 21, "enabled": true}}}
+{"event_type": "info_hw_state", "event": {"platform": {"type": "rpi", "base": "Virtual Raspberry Pi"}, "health": {"temp": {"cpu": 36.511, "gpu": 35.0}, "throttling": {"raw_flags": 0, "parsed_flags": {"undervoltage": {"now": false, "past": false}, "freq_capped": {"now": false, "past": false}, "throttled": {"now": false, "past": false}}}}}}
+{"event_type": "info_meta_state", "event": {"server": {"host": "localhost.localdomain"}, "kvm": {}}}
+{"event_type": "info_system_state", "event": {"kvmd": {"version": "1.102"}, "streamer": {"app": "ustreamer", "version": "1.25", "features": {"WITH_OMX": false, "WITH_GPIO": false, "WITH_PTHREAD_NP": true, "WITH_SETPROCTITLE": true, "HAS_PDEATHSIG": true}}, "kernel": {"system": "Linux", "release": "5.8.10-arch1-1", "version": "#1 SMP PREEMPT Thu, 17 Sep 2020 18:01:06 +0000", "machine": "x86_64"}}}
+{"event_type": "wol_state", "event": {"enabled": false, "target": {"ip": "255.255.255.255", "port": 9, "mac": ""}}}
+{"event_type": "gpio_state", "event": {"inputs": {"led1": {"online": true, "state": false}, "led2": {"online": true, "state": false}}, "outputs": {"button1": {"online": true, "state": false, "busy": false}, "button2": {"online": true, "state": false, "busy": false}, "relay1": {"online": false, "state": false, "busy": false}, "relay2": {"online": false, "state": false, "busy": false}}}}
+{"event_type": "hid_state", "event": {"online": true, "keyboard": {"online": true, "leds": {"caps": false, "scroll": false, "num": false}}, "mouse": {"online": true}}}
+{"event_type": "atx_state", "event": {"enabled": true, "busy": false, "leds": {"power": false, "hdd": false}}}
+{"event_type": "msd_state", "event": {"enabled": true, "online": true, "busy": false, "storage": {"size": 234950152192, "free": 23514271744, "images": {}, "uploading": false}, "drive": {"image": null, "connected": false, "cdrom": true}, "features": {"multi": true, "cdrom": true}}}
+{"event_type": "streamer_state", "event": {"limits": {"max_fps": 40}, "params": {"desired_fps": 30, "quality": 80}, "snapshot": {"saved": null}, "streamer": null, "features": {"quality": true, "resolution": false}}}
+{"event_type": "loop", "event": {}}
+
After connecting the client receives a bundle of states of all KVMD subsystems. After the batch is completed, it sends a loop
event, which means that the websocket has entered event loop mode. Now it will send new states and respond to client's requests.
Another type of event is ping
, which can be sent by the client: {"event_type": "ping", "event": {}}
. If the server is running, it will respond with pong: {"event_type": "pong", "event": {}}
.
For keypresses, set event_type
to key
and fill in the event
structure with key
and state
, where key
is the key from mapping and state
is boolean that determines if the key is pressed or released:
# python, install websocket-client
+import websocket
+import ssl, time
+uri = "wss://10.0.0.7/api/ws?stream=0"
+headers = {"X-KVMD-User": "admin", "X-KVMD-Passwd": "admin"}
+ws = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE})
+ws.connect(uri, header=headers)
+ws.send('{"event_type": "key", "event": {"key": "Enter", "state": true}}')
+time.sleep(0.05)
+ws.send('{"event_type": "key", "event": {"key": "Enter", "state": false}}')
+ws.close()
+
The GET /api/info
handle returns the general information about the PiKVM device.
Parameters:
+fields=...
(optional) - Only specified categories will be returned, for example fields=system,hw
. By default all categories will be displayed.$ curl -k -u admin:admin https://<pikvm-ip>/api/info
+
{
+ "ok": true,
+ "result": {
+ "extras": { // Installed applications; null on internal error
+ "ipmi": {
+ "daemon": "kvmd-ipmi",
+ "description": "Show IPMI information",
+ "enabled": true,
+ "icon": "share/svg/ipmi.svg",
+ "keyboard_cap": false,
+ "name": "IPMI",
+ "path": "ipmi",
+ "place": 21,
+ "port": 623
+ },
+ "vnc": {
+ "daemon": "kvmd-vnc",
+ "description": "Show VNC information",
+ "enabled": true,
+ "icon": "share/svg/vnc.svg",
+ "keyboard_cap": false,
+ "name": "VNC",
+ "path": "vnc",
+ "place": 20,
+ "port": 5900
+ }
+ },
+ "hw": { // Hardware info
+ "health": {
+ "temp": {
+ "cpu": 36.511, // /sys/class/thermal/thermal_zone0/temp / 1000; null on error
+ "gpu": 35.0 // vcgencmd measure_temp; null on error
+ },
+ "throttling": { // vcgencmd get_throttled; null on error
+ "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.1", // /proc/device-tree/model; null on error
+ "serial": "0000000000000000", // /proc/device-tree/serial-number; null on error
+ "type": "rpi"
+ }
+ },
+ "meta": { // /etc/kvmd/meta.yaml; null on error
+ "kvm": {},
+ "server": {
+ "host": "localhost.localdomain"
+ }
+ },
+ "system": {
+ "kernel": {
+ "machine": "x86_64",
+ "release": "5.8.14-arch1-1",
+ "system": "Linux",
+ "version": "#1 SMP PREEMPT Wed, 07 Oct 2020 23:59:46 +0000"
+ },
+ "kvmd": {
+ "version": "2.1"
+ },
+ "streamer": {
+ "app": "ustreamer",
+ "features": { // {} on error
+ "HAS_PDEATHSIG": true,
+ "WITH_GPIO": false,
+ "WITH_OMX": false,
+ "WITH_PTHREAD_NP": true,
+ "WITH_SETPROCTITLE": true
+ },
+ "version": "2.1" // "" on error
+ }
+ }
+ }
+}
+
Each category is represented by its own event in the websocket (info_hw_state
, info_system_state
, etc). The event content has the same format as the category content in API.
The GET /api/log
handle displays logs from all KVMD services as plain text.
Parameters:
+follow=1
(optional) - Turns the request into long-polling mode and follow log messages in real time.seek=N
(optional) - Runs the log for the specified time in seconds, for example seek=3600
will show the log for the last hour.$ curl -k -u admin:admin https://<pikvm-ip>/api/log
+
The GET /api/atx
handle shows the current ATX state.
$ curl -k -u admin:admin https://<pikvm-ip>/api/atx
+
{
+ "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
+ }
+ }
+}
+
The POST /api/atx/power
handle changes ATX power state to desired.
Parameters:
+action=...
- Describes desired state:on
- Turn on (do nothing in case PSU is already on).off
- Turn off (aka soft-off), emulates click on the power button.off_hard
- Perform long press on the power button (5+ seconds).reset_hard
- Emulates pressing reset button (hardware hot reset).wait=1
(optional) - Says if call should return immediately or just after finishing operation.$ curl -X POST -k -u admin:admin https://<pikvm-ip>/api/atx/power?action=on
+
The POST /api/atx/click
handle sends the ATX button press event.
Parameters:
+button=...
- Specifies the desired PC case button:power
- Short click on the power button.power_long
- Long press on the power button (5+ seconds).reset
- Short click on the reset button.wait=1
(Optional) - Says if call should return immediately or just after finishing operation.$ curl -X POST -k -u admin:admin https://<pikvm-ip>/api/atx/click?button=power
+
The GET /api/msd
handle shows the current MSD state.
$ curl -k -u admin:admin https://<pikvm-ip>/api/msd
+
The POST /api/msd/write
uploads an image to MSD.
Parameters:
+image=...
- Specifies the name of the image.$ # create a test image
+$ dd if=/dev/zero of=test.iso bs=1M count=1
+
+$ # upload it to pikvm
+$ curl -v -X POST --data-binary @test.iso -k -u admin:admin https://<pikvm-ip>/api/msd/write?image=test.iso
+
The POST /api/msd/write_remote
handle downloads an image from HTTP(S) URL to the MSD.
Parameters:
+url=...
- Image URL.image=...
(optional) - Image name.timeout=N
(optional) - Remote request timeout, 10 seconds by default.Note
+This is a long-polling request. Do not interrupt the request until the download is complete, otherwise the download will stop.
+$ # create test image
+$ dd if=/dev/zero of=test.iso bs=1M count=1
+
+$ # upload it to pikvm
+$ curl -v -X POST -k -u admin:admin https://<pikvm-ip>/api/msd/write_remote?url=http://example.com/test.iso
+
The POST /api/msd/set_params
handle changes the current image and/or set drive parameters
Parameters:
+image=...
(optional) - Change the current image.cdrom=1|0
(optional) - Change the media type to the CD-ROM on 1
, otherwise to the Flash.$ curl -X POST -k -u admin:admin "https://<pikvm-ip>/api/msd/set_params?image=test.iso&cdrom=1"
+
The POST /api/msd/set_connected
connects or disconnect the MSD to the host.
Parameters:
+connected=1|0
- Change the state.$ curl -X POST -k -u admin:admin https://<pikvm-ip>/api/msd/set_connected?connected=1
+
The POST /api/msd/remove
handle removes the specified image.
Parameters:
+image=...
- The image name.$ curl -X POST -k -u admin:admin https://<pikvm-ip>/api/msd/remove?image=test.iso
+
The POST /api/msd/reset
handle resets the drive.
$ curl -X POST -k -u admin:admin https://<pikvm-ip>/api/msd/reset
+
The GET /api/gpio
handle shows the current GPIO state.
$ curl -k -u admin:admin https://<pikvm-ip>/api/gpio
+
The POST /api/gpio/switch
handle interacts with selected GPIO driver channel in switch
mode.
Parameters:
+channel=...
- The GPIO driver channel.state=1|0
- The new switch state.wait=1
(optional) - Says if call should return immediately or just after finishing operation.The POST /api/gpio/pulse
handle interacts with selected GPIO driver channel in pulse
mode.
Parameters:
+channel=...
- The GPIO driver channel.delay=N.N
(optional) - The pulse time in seconds (float), 0
for default delay.wait=1
(optional) - Says if call should return immediately or just after finishing operation.The GET /api/export/prometheus/metrics
handle returns the Prometheus metrics. Also see here for details.
$ curl -k -u admin:admin https://<pikvm-ip>/api/export/prometheus/metrics
+
You can find all existing APIs in the KVMD source tree. We would appreciate your help with documentation.
Legacy warning
+This page describes the legacy keyboard and mouse emulator used in old DIY builds. +There is no point using it today because there is a more modern and better replacement for the new Pico HID. +This one can also serve as an in-place compatible replacement for the Arduino HID in the old build.
+PiKVM V3 note
+Use the SPI HID for V3. Otherwise, you won't be able to use the Serial console.
+Power up PiKVM and switch it to RW-mode using command rw
.
Add these lines to /etc/kvmd/override.yaml
:
kvmd:
+ hid:
+ type: serial
+ reset_pin: 4
+ device: /dev/kvmd-hid
+
Create file /etc/udev/rules.d/99-kvmd-extra.rules
:
KERNEL=="ttyAMA0", SYMLINK+="kvmd-hid"
+
Run systemctl disable getty@ttyAMA0.service
.
Remove console=ttyAMA0,115200
or console=serial0,115200
and kgdboc=ttyAMA0,115200
or kgdboc=serial0,115200
from /boot/cmdline.txt
.
Perform reboot
.
Using the PS/2 firmware currently have some limitations:
+Both of these problems will be solved in the nearest future and the two different firmware versions will be combined into one universal one.
+To select the PS/2 firmware, follow the instructions for the USB, but with one exception:
+make
you will need to edit file platformio-avr.ini
Open the file and find these lines:
+[_common]
+build_flags =
+ -DHID_PS2_KBD_CLOCK_PIN=7
+ -DHID_PS2_KBD_DATA_PIN=5
+ -DHID_USB_CHECK_ENDPOINT
+# ----- The default config with dynamic switching -----
+ -DHID_DYNAMIC
+ -DHID_WITH_USB
+ -DHID_SET_USB_KBD
+ -DHID_SET_USB_MOUSE_ABS
+# ----- PS2 keyboard only -----
+# -DHID_WITH_PS2
+# -DHID_SET_PS2_KBD
+# ----- 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 -----
+# -DHID_WITH_USB
+# -DHID_WITH_PS2
+# -DHID_SET_PS2_KBD
+# -DHID_SET_USB_MOUSE_REL
+
By default, the firmware works with USB HID and supports dynamic mode switching. You can choose one of the other modes by commenting some lines and uncommenting others. This example to use a USB mouse and PS/2 keyboard:
+...
+# ----- 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 -----
+...
+
Next, connect Arduino pins to the female PS/2 port of your motherboard. Choose the purple port. If your motherboard only have one port, it's probably universal and can be used either for the keyboard or for the mouse. Most likely, it is painted in two colors: green and purple. You can use it either.
+Female PS/2 port (front view) | +Pinout | +
---|---|
+ | Arduino pin 7 <-> PS/2 CLOCK Arduino pin 5 <-> PS/2 DATA Arduino GND pin <-> PS/2 GND |
+
Warning
+Connect VIN pin of Arduino to any Raspberry's 5v pin for PS/2 only device. But you don't need to connect the Arduino VIN pin if you connected USB (Arduino will get power through it).
+Using an SPI connection, an Arduino Micro (not Pro) or compatible can be flashed from the Pi and used as an HID keyboard and mouse. Unlike UART, SPI does not share pins with Bluetooth on the Raspberry Pi so the Bluetooth radio does not need to be disabled.
+ +Before powering either device, double-check the connections. The following should be wired from the Pi to either the level shifter or the Arduino. While the Arduino tolerates 3.3V logic input, 5V outputs from the Arduino can damage or destroy the Raspberry Pi and must not be connected directly to 3.3V GPIO pins directly.
+There are very few parts needed besides the Raspberry Pi to build the solution. Some parts may be purchased with or without headers, if headers are not pre-soldered, it may be necessary to order some breakaway header strips and solder them to the boards prior to assembly unless the wires will be soldered directly to the boards.
+Note
+A smaller "Pro Micro" board is available in a 3.3V model but the SS connection (RX_LED) is not available as a separate pin or solderable hole. If using this board, a jumper wire can be soldered to the resistor for the RX_LED but there is risk of burning the resistor, the LED, the board, or other components in the process. Advantages of this board include not requiring a logic level converter and reduced breadboard or board space for building the solution.
+For the primary functionality, most connections are made using a 4-channel bidirectional level shifter
+An additional circuit is used with a transistor to reset the HID for mode changes and for SPI programming as follows:
+Pictures of this setup are also available in full resolution for download to assist for both the Raspberry Pi and the Arduino board. A smaller version of the images has been included on this page and can be downloaded.
+Raspberry Pi Closeup | +Breadboard with Arduino | +
---|---|
+ | + |
Programming assumes the Arduino is powered via USB, either from the connected host or the Pi itself. If the USB is not connected, 5 V may be provided by the Raspberry Pi GPIO but should be disconnected prior to connecting USB to the Arduino's USB port. The Raspberry Pi does not have backcurrent protection, a circuit using one or more Schottky diodes can be built to OR power from multiple sources but it's easier and more cost effective to avoid conflict and voltage differences between power supplies by leaving the 5 V wire disconnected.
+As of the latest package release, the kvmd service supports SPI. It should be sufficient to ensure the packages are up-to-date with the latest release, the programmer is installed, and the SPI device overlay is loaded at boot.
+rw
dtoverlay=spi0-1cs
to /boot/config.txt
reboot
.Instructions on flashing the Arduino can be found on the page Flash the Arduino HID.
+If programming fails, ensure the Arduino is powered and check the wiring again. If there is a misconfiguration, power off the Pi and the Arduino, correct the wiring, and try again. Note it is not recommended or required to supply 5V power from the Raspberry Pi if the Arduino is USB powered, if the issue appears to be power related it may be removed from the solution and replaced with a powered USB connection if it will aid in troubleshooting but check all other wires first to ensure there are no shorts.
+After you have double and triple-checked your wiring (in particular make sure the pins you are using on the Pi are correct, the documentation uses the GPIO pin labels, NOT the sequential pin numbers from 1-40. A good pinout reference is @Gadgetoid's version, you might try flashing the Arduino by holding down the RESET button on the chip while running make install
. If this works, then at least you know your SPI wiring is correct.
Wiring problems are a common issue but there could be other reasons for programming not to complete. While it is not possible to list every possible problem and solution here, there is an active user community in our Discord with others familiar with the solution and willing to help.
+Once the installation has completed, all that should remain is to add the following configuration to /etc/kvmd/override.yaml
and restart the kvmd service. If the first line exists due to existing overrides, omit that line and either add or update the hid section as appropriate.
kvmd:
+ hid:
+ type: spi
+ chip: 0
+ bus: 0
+ sw_cs_pin: 7
+ reset_pin: 25
+ reset_inverted: true
+
After saving the changes to /etc/kvmd/override.yaml
, restart kvmd
and clear your browser cache. The command to restart kvmd
is
# systemctl restart kvmd
+
If your device is still in read-write mode, ro
will put the SD back in read-only mode.
Due to an ancient buggy driver, the USB absolute mouse on Windows 98 moves only within the upper-left quarter of the screen. To fix this, just recompile the firmware with uncommented flag -DHID_WITH_USB_WIN98
in platformio-avr.ini
.
{"use strict";/*!
+ * escape-html
+ * Copyright(c) 2012-2013 TJ Holowaychuk
+ * Copyright(c) 2015 Andreas Lubbe
+ * Copyright(c) 2015 Tiancheng "Timothy" Gu
+ * MIT Licensed
+ */var Va=/["'&<>]/;qn.exports=za;function za(e){var t=""+e,r=Va.exec(t);if(!r)return t;var o,n="",i=0,a=0;for(i=r.index;i