A build for a RPi-based desktop control touchscreen.
I want a unified system to control various desktop devices. My criteria are:
- Touchscreen with status feedback (which device is selected, etc.)
- Avoid IP control as much as feasible
- Be faster than controls on various devices
- Monitor input switching is a far reach
- My Orei UKM-404 USB matrix switch is 1 button per device, so each device I want to move from output 2 to output 1 is 3 presses, and there is a delay between them.
- Be able to interact with my Home Assistant for room control
- Allow for expansion in the future
- Document this and make it flexible enough for other people to build
- Add some cyberdeck styling :)
Total BOM is looking to be < $250, currently around $212.
- Raspberry Pi 4 - $35 for 1GB, which may be enough
- Pi 4 has better DDC/CI support than older models - see here
- The case I'm using only supports Pi 4 or older.
- Raspberry Pi 4 Touchscreen - $60+
- MicroSD Card (32GB seems fine) - $7
- 2x cable-style MicroHDMI Male to HDMI Female Adapters - $7
- 2x Short HDMI extensions - $7
- Short ethernet cable and coupler - $8
- USB Hub/speaker/mic - $20
- USB-C Power Adapter/Cable - $20
- SmartiPi Touch Pro Case w/ large build area - $30
- 2x USB-TTL Adapter - $10
- Others should be fine, but a quality one might save some trouble. :)
- Tiny USB Hub - $8 (Optional)
- Raspbian OS
- Electron
- Uses Python backend launch model from Python Electron proof of concept, but using an HTTP backend instead
- Flask
- Device-specific libraries and debug tools listed with External Device types
This is a complex chain, but actually easy to use:
- Both HDMI and Displayport generally support the the VESA Display Data Channel Command Interface standard (DDC/CI) (a copy of the spec can be found here). Many monitors support this functionality, but some do not or may have odd issues (flashes, etc).
- On this, you can issue commands in the Monitor Control Command Set (MCCS) (a copy of the spec can be found here), which standarizes sending Virtual Control Panel (VCP) commands that equate to typical monitor physical control functions.
- VCP 60h is input selection, and the values are generally standardized:
- 01h - 02h: Analog video (R/G/B) (typically VGA) inputs (2x)
- 03h - 04h: Digital video (TMDS) over DVI inputs (2x)
- 05h - 06h: Composite video inputs (2x)
- 07h - 08h: S-video inputs (2x)
- 09h - 0Bh: Tuners inputs (3x)
- 0Ch - 0Eh Component video (YPbPr / YCbCr) inputs (3x)
- 0Fh - 10h DisplayPort inputs (2x)
- 11h - 12h Digital Video (TMDS) over HDMI inputs (2x)
- It's unclear how monitors with more inputs than covered (such as the Acer X32 FP with 4 HDMI inputs) or non-covered inputs (USB-C comes to mind, but it's likely treated as a DisplayPort)
- Linux and Windows both have solid DDC/CI support. DDCutil on Linux is the easiest way to test this, and there are bindings for a bunch of languages.
- Linux Debug tool: DDCUtil - CLI tool, great for at least testing
- Python library: None - just use subprocess to call ddcutil.
- monitor-commander is a CLI tool itself
As an example, the following matrix switches support RS-232:
- OREI UKM-404 USB Matrix switch(not recommending for other reasons - Do NOT use the network connection.)
- GoFanco 4x4 HDMI Matrix Switch
Notes:
- These simple RS-232 devices cannot handle typing-speed commands - commands must be sent all at once.
- By default, the OREI is 9600 baud, while the GoFanco is 115200 baud. Both are 8N1.
- The OREI includes a premade 3-pin to serial adapter, and the GoFanco includes 3-pin connectors (since it uses them for audio too). Additional connectors are available on Amazon.
- Linux Debug tool:
cu
orminicom
- Python library: PySerial - Python serial library
Hubspace is Home Depot's Afero-based smart home product line, and I have a ceiling fan with it. I could do this through HomeAssistant, but that integration is a little messy. I know a guy who wrote a clean Python backend, and may eventually make a better HA integration, but in the mean time, why not use the Python backend directly? Nosce te ipsum.
- Python library and debug tool: Hubspace-ng
It'd be nice to be able to provide some Home Assistant controls. I don't want to use HA to control the monitors/etc., but I'd love to be able to control other home-automation devices.
- Linux Debug tool: HASS-CLI
- Python library: HomeAssistant-API
Especially with multiple monitors, flexibility is useful. I eventually want to find a good Matrix switch.
They are very rare outside of KVMs, and they tend to be feature limited.
My monitors (and many others) only have HDMI 2.0, which can only do 2K@144Hz in SDR. For 4K, higher refresh rates, and HDR, you need HDMI 2.1 (with up to 48Gbps bandwidth) or DP 1.4+.
I think USB is slightly simpler here. I'd rather not tie up GPIO pins with something that is easily handled via USB, and I may need a number of RS232 serial connections.
I want a DSI touchscreen because I want both HDMI ports to control 2 monitors. There are very few DSI touchscreens, and the Pi one - while not the biggest or best - is a de-facto standard, so I can get a pre-made case for it. I also want to minimize fidgetiness - some other touchscreens require non-standard kernel params, etc.
It's unnecessary, may add complexity, and brings a host of security issues. Devices with it baked in often have bad implementations; custom implementations might mean a bunch of small edge devices.
- Oak? - Kiosk-focused variant of Electron Not updated in 3 years
- Tkinter - TK library built into python - Generally ugly, slow, not great with async
- Can be made prettier with CustomTKinter?) or Tkss for CSS-like stylesheets
- Seems like it can do Fullscreen
- Add videos via TKVideoPlayer (which also can be used with customtkinter)
- More widgets via AwesomeTKinter
- TKfontawesome - Fontawesome Icons
- Kivy - was having trouble setting up in a conda env
- LibAvg - Generally requires a source build
- Pyglet - Python native GUI library, has video and fullscreen support Few native widgets, poor documentation, big API changes in 2.0, none of the 3P widgets are updated (Glooey isn't a priority for the author, Kytten is dead and I can't find the mentioned fork, Pyglet-GUI is 9 years old)
- PySimpleGUI - Python wrapper for multiple UI toolkits - free for personal use only?
- NiceGUI - discovered late, not very themable, and native mode needs https://github.com/r0x0r/pywebview, which needs... Qt or GTK!
- QT on Python - not natively available for Pi and too much work to implement!
- Multiple Distros
- PyQT - Python 3rd-party Qt wrapper, GPL v3, no wheel for QT on Pi
- QT for Python - Official QT Python wrapper, LGPL, no wheel for QT on Pi
- APIs are nearly identical
- Building QT
- This is some serious work.
- Even the docker solution looks painful
- This doc points out it needs the headers for the video card driver to do hardware acceleration?
- Can use QT Creator to make UIs in QML, which I could largely load at runtime
- Can be fullscreen via the fullscreen prop
- Can do video via QAbstractVideoSurface
- Dear PyGUI - Python native GUI library - Not up-to-date on Pi
- Multiple Distros
- Arwes - Awesome looking, but not wholly ready for prime time - might use for background and frame still?
- Lack of documentation
- Many elements that should be part of the framework (like Button) are instead part of the demo site app and would need re-implemented
- Augmented UI - Only covers frame-like elements, not really the aesthetic I want
- Codepens
- Pure CSS Cyberpunk Buttons - would need major animation tweaks and stuff, but might be a starting point
- Cyberpunk 2077 Theme CSS - button is less refined, but I could use some of the other things
- Slack / Discord Cyberpunk 2077 redesign w/ Preact - Possibly a bit too Cyberpunk the game, but I may steal a few things
- I already had my Hubspace-ng library and some prototype code.
- I wasn't originally doing an Electron GUI.
- JS is just a bit messier than I want for the backend.
- Someone else has done something similar?
- CyberDeck using this case - I found the case before I found this, but I might snag another :)
- Clone repo
- Run
pip install -e .
from the root project folder - Run
npm install
from the electron-react-app folder