Turning a $40 Surface Go into an always-on camera monitor
TL;DR I wanted an always-on screen showing a camera feed. Something that boots straight into the stream with no prompts, survives Wi-Fi drops and camera hiccups, and can be maintained remotely. A used Surface Go 3 running Omarchy turned out to be a great fit, with only a few setup steps. I have my home kitted out with UniFi PoE cameras. Inspired by Casey Neistat’s studio door camera , I made a similar setup: a camera pointed outside with a screen mounted on a wall inside. In practice, this is meaningfully more convenient than a peephole (we also don’t have any windows with a good view of the entrance). When someone knocks, we can glance at the monitor from just about anywhere in the room and see who it is. Until now, I was just using a cheap Amazon Fire HD 8 tablet. My thinking at the time was to make this as simple as possible: get a cheap Android tablet, run VLC for the RTSP stream, attach it to the wall with Command Strips, leave it plugged in, done. This had some downsides. The Fire HD 8 is underpowered, so we could only use a medium-resolution stream (720p), and the stream would lag behind by a few seconds. The simplicity of the VLC setup meant that anytime our network went down for an upgrade or the stream cut out momentarily, we’d have to reconnect manually. That worked for about three years. Then, I suspect, being permanently plugged in at 100% charge took its toll. Over the past week, the stream grew increasingly unreliable, mostly because the tablet failed to connect to my home Wi-Fi. I suspect the Wi-Fi card is dying. So, this presented an opportunity for an upgrade. My main goal was reliability. I wanted anyone in my family to be able to turn this on and get it working with as little interaction as possible. That meant I wanted them to literally just turn it on, walk away, and be greeted by the stream playing in full screen. I also wanted the stream to recover automatically from network and camera feed drops robustly. In addition, I wanted something better suited to this unusual always-on, always-streaming, always-plugged-in design. This eliminated OLED screens; this would be a worst-case scenario for burn-in. It also made devices with battery charge limits more appealing, since those limits could mitigate battery deterioration from always being plugged in. I also wanted something that didn’t feel awful to use, unlike Amazon’s bloated, ad-riddled version of Android for its Fire tablets. I wanted something I could keep getting software updates for forever. That pushed me toward a device I could run Linux on, rather than another Android tablet with an unavoidable end-of-life date. Finally, I still wanted this to be cheap. After doing some research, I settled on something like a Microsoft Surface Go 2. Powerful enough hardware and a nice enough display to handle a high-resolution HEVC stream. Able to run Linux. And, perhaps most importantly, BIOS-level support for battery limiting —when set, the battery stops charging when it reaches 50% of its capacity. Then, the stars aligned even more: I found a base (4 GB, 64 GB eMMC) Surface Go 3 on my local Facebook Marketplace for just $40. Score. Updating the BIOS Whenever I buy a used device I intend to put Linux on, I always update the BIOS using the Windows installation first. Most manufacturers do not have a way to update the BIOS without Windows. In the case of this tablet , released in 2021, I was able to bump my BIOS from a 2022 version to a recent release. BIOS updates often improve system stability and performance. Next, I prepared the UEFI settings for installing Omarchy and using the tablet as a kiosk. To get into the BIOS, hold Volume Up when hitting the power button. For this install, I have no data on the device. I specifically want it to be easy to boot, so that means skipping Omarchy’s default full-disk encryption. At the time of writing, this meant hitting at the disk-formatting confirmation prompt . This tablet only has a single USB-C port, so I needed a USB-C hub to plug in my mouse, keyboard, and USB drive simultaneously. I didn’t have the Surface keyboard (part of why I got a good deal on Marketplace). This one bit me. Omarchy always logs in automatically on encrypted installs because the LUKS prompt is the auth gate. On an unencrypted install, it logs in automatically exactly once. Then a one-shot service deletes , and SDDM shows a login screen forever after. To re-enable autologin, we just put the file back under a filename nothing will remove: Next, in the Omarchy menu, we set up . With that, the boot chain is fully unattended. Turning the machine on will take us straight to the desktop. is already installed in Omarchy. We can use a user service to launch the stream. We can keep the secrets out of the unit. Then, in : Then enable and check it: We can run on a different workspace, since the original workspace is now playing full-screen video. The recovery logic is all in . makes exit on a stalled connection rather than show a frozen frame, and makes it exit when the stream ends. relaunches it, starting with a 2-second delay and backing off toward 30 seconds during a long outage. Wi-Fi needs no special handling: reconnects on its own, and simply fails until it does. stops taps on the touchscreen from pausing or seeking, and uses VAAPI, which matters for heat on a fanless tablet. is there because Omarchy ships a default rule that floats the app ID in an 875×600 window. So, we can give the kiosk its own rule instead, appended to : A simple or a click on the “Stay Awake” icon in the taskbar will do the trick. This can also be done via the CLI: These settings are useful despite our Hyprland rule because the rule only applies while is playing. Without them, the tablet might still lock or sleep during downtime. These settings persist across reboots by default. Once the tablet is deployed, SSH is the intended way to interact with it. Omarchy has easy ways to set up SSH and Tailscale . The SSH setup installs OpenSSH, opens port 22 in (with a rate limit), handles key authorization, and disables password auth. Then, once Tailscale was set up, I disabled key expiry for this node. I like Omarchy for this because it is a rolling distro (based on Arch), which makes it easy to keep up to date. Just SSHing into the machine and running periodically does the trick. When a reboot is necessary, that’s no problem since the RTSP service will reconnect to the stream automatically on boot. Demo of the unattended boot. This turned out as nicely as I had hoped. All my goals were met, for cheap! Enable the battery limiter (Boot configuration -> Battery Limit: Enabled). Disable Secure Boot (Security -> Secure Boot: Off) (currently required to install Omarchy). Change the boot order to put the USB drive first.