Scripts to switch monitor source based on USB keyboard plug/unplug events.
My home office for work and personal computing and I need to be able to switch back-and-forth between my work and personal computers.
3-Monitor KVM switches can be really pricey!
So I settled on just a basic USB-only KVM switch.
Monitors have multiple source inputs anyways, so why not just switch the source when I switch the KVM?
To do that, we either need to manually change the monitor source (ugh.) or, we need to get one of the computers to change the source for the monitors.
I have three Dell U2415s which support MCCS (Monitor Control Command Set) which video drivers (on Linux) will expose as an I2C bus at /dev/i2c-N.
ddcutil can be used to read/write and explore the settings exposed by the monitors.
Note: If you are using this repo to jury-rig your own KVM, your settings will likely be different. The first step to installing this is figuring out what your settings should be and editing the scripts.
Now, to run the monitor switching scripts, we need to know when the usb KVM switch is toggled. To do that, udev to listen for the events fired when our usb keyboard is plugged in or unplugged.
-
Install ddcutil. On Ubuntu 20.04:
sudo apt install ddcutil -
Find your monitor(s) serial numbers:
sudo ddcutil detectYour output will look something like:
Display 1 I2C bus: /dev/i2c-1 EDID synopsis: Mfg id: DEL Model: DELL U2415 Serial number: CFV9N6B8058L Manufacture year: 2016 EDID version: 1.3 VCP version: 2.1 Display 2 I2C bus: /dev/i2c-3 EDID synopsis: Mfg id: DEL Model: DELL U2415 Serial number: CFV9N6B80KEL Manufacture year: 2016 EDID version: 1.3 VCP version: 2.1 Display 3 I2C bus: /dev/i2c-5 EDID synopsis: Mfg id: DEL Model: DELL U2415 Serial number: CFV9N7BO103L Manufacture year: 2017 EDID version: 1.3 VCP version: 2.1Save the
Serial number: CFV9N6B8058Lfor later. -
Find the capabilities of your monitors
sudo ddcutil capabilities --sn=[YOUR SERIAL NUMBER]Look for
Input Sourcein the output e.g.Feature: 60 (Input Source) Values: 0f: DisplayPort-1 10: DisplayPort-2 11: HDMI-1 12: HDMI-2 -
Edit
src/on-keyboard-plug.shandsrc/on-keyboard-unplug.shto set the[SERIAL],[FEATURE]and[VALUE]you want the monitor to be in when the keyboard is plugged in or unplugged.Note #1: ddcutil lists the values as hexidecimal, but requires a leading
xto interpret command line arguments as hex. So, changing to HDMI-2 on my monitors, I edit the script to usex12as the value.Note #2: Remove the square brackets on
[FEATURE]and[VALUE]Note #3: Add / remove commands depending on how many monitors / serial numbers you have.
-
Figure out your keyboard's vendor ID:
sudo udevadm monitorNow unplug your keyboard and plug it back in. You should see a bunch of events logged to the console like.
UDEV [2520806.444432] add /devices/pci0000:00/0000:00:14.0/usb3/3-1/3-1.2/3-1.2:1.0/0003:045E:00DB.0034 (hid)Stop the monitoring with ctrl-C. The part that matches
045Ein the output above is likely the vendor ID. To confirm, take the3-1.2equivalent from the device path in the output above and find the device in yoursysfilesystem.For example my keyboard's
syspath is/sys/bus/usb/devices/3-1.2sudo udevadm info /sys/bus/usb/devices/3-1.2 | grep -e "DEVPATH" -e "ID_VENDOR_ID"Outputs:
E: DEVPATH=/devices/pci0000:00/0000:00:14.0/usb3/3-1/3-1.2 E: ID_VENDOR_ID=045e -
Edit
src/80-thrifty-kvm.rulesto set your[VENDOR_ID].Note #1: Remove the square brackets replacing all of
[VENDOR_ID].Note #2:
[VENDOR_ID]is insrc/80-thrifty-kvm.rulestwice.
make PREFIX=/usr/local
sudo make install PREFIX=/usr/local
sudo make uninstall PREFIX=/usr/local