Smart Home, Dumb Luck, Episode 1: Firing SmartThings and Booting Proxmox With No USB Drive in the House
New series. The goal is simple and, it turns out, not easy to execute: replace my Samsung SmartThings hub with a self-hosted Home Assistant setup. As with all things on this journey, I want it to be hardware I control, independent of Samsung’s cloud and Samsung’s timeline for deciding what my house is allowed to do.
Episode 1 doesn’t even get to Home Assistant. It’s just the story of getting an operating system onto the box that will run it. I did not expect that part alone to take a detour through a dead card reader, a camera that refused a memory card on principle, and my Steam Deck pretending to be a CD-ROM.
The Goal
SmartThings has been fine. But “fine” increasingly means a hub I don’t control, automations that depend on Samsung’s cloud staying up, and zero visibility into why something didn’t fire when it didn’t fire. It’s also in the critical path of waking my homelab up remotely with our wake on LAN trick. I want the automation brain in my house to be something I own outright: local-first, inspectable, and not one outage-notice email away from me finding a new hub.
I researched this thoroughly and settled on a specific architecture after flip-flopping through three different stances in one sitting: Proxmox VE as the hypervisor, Home Assistant OS running inside a VM (to keep its Supervisor and add-on store), and everything else — Tailscale, monitoring, DNS — as lightweight Proxmox LXCs alongside it. I’d briefly talked myself into a simpler Docker-only box before talking myself back out of it. I need a solution AI agents can SSH into and iterate on the config over time. Proxmox’s snapshot-before-you-break-it safety net is worth the extra layer once change is frequent instead of rare.
Choosing the Brains
The hardware needed to be quiet, low-power, and boring in the best sense — always-on infrastructure, not a science project. A Lenovo ThinkCentre M720q Tiny showed up: an i5-8400T, 16GB of RAM, a 256GB NVMe drive, small enough to disappear behind a monitor. It’s also, as it turns out, a genuine community staple for exactly this job — routers, DNS boxes, and Home Assistant hosts built on this same hardware class are common enough that the upgrade path (dual SODIMM slots, a socketed CPU, an M.2 slot) is well documented. Make no mistake: I will not be dual-booting and gaming on this puppy. Just a gamer’s version of a Raspberry Pi.
It arrived with no operating system. That’s where this episode actually starts.
A BIOS Setting Hiding Behind a Decoy
First order of business: Secure Boot off, virtualization on. The BIOS had a “Device Guard” toggle that looked like the obvious switch, but flipping it does something sneaky — it silently re-enables Secure Boot as a side effect, undoing the setting I’d just made. The actual toggle I wanted, “Virtualization” with separate entries for Intel VT-x and VT-d, was sitting one menu deeper, next to Device Guard rather than inside it, a distinction Lenovo’s own support documentation doesn’t make obvious either. Easy to miss, easy to fix once you know it’s there.
Proxmox VE 9.2 downloaded clean. Then came the fiasco.
No USB Drive, No Problem — Or So I Thought
If you’re a reader of this blog, you know I’m often remote. I travel a lot. For this episode I’m no where near my home. Thus, no where near my usual drawer full of “one day I’ll need these” cables, USB drives, and dongles.
So here I am, not only away from keyboard on a phone but away from home all together. I didn’t have a working USB thumb drive anywhere in this location. Not “misplaced,” genuinely zero. What followed was a tour through every alternative I could think of, most of which failed for reasons that had nothing to do with each other:
- PXE network boot, using my Mac as the server. Mac doesn’t ship a native tool for this, so that meant standing up iVentoy inside a Colima VM with bridged networking — a setup nobody on the internet has actually confirmed works, and it didn’t for me either.
- A USB card reader, dead on arrival — confirmed dead by testing it against three completely different computers with a known-good memory card.
- A DJI Osmo Pocket 3, on the theory that any device with removable storage and a USB-C port might double as a card reader. DJI’s firmware validates a card’s filesystem before doing anything with it at all, including exposing it over USB, and a bootable image doesn’t look like camera footage. No dice.
- An iPhone, ruled out on basic principle: iOS has no USB Mass Storage mode, jailbroken or not, and a PC’s BIOS can’t speak the proprietary protocol Apple uses instead.
The Steam Deck: Saboteur, Then Savior
My Steam Deck ended up starring in both the worst part of this ordeal and the part that finally worked. It cost me hours as a would-be PXE server before it saved the entire episode as something much weirder: a fake USB drive.
Round one: trying to make it a PXE server
SteamOS is Arch under the hood, with a real Linux kernel and no VM layer in the way, which made it feel like the obvious upgrade over fighting Colima on the Mac. The plan: run iVentoy directly on the Deck, wire the ThinkCentre to it over a USB-Ethernet adapter, and let it PXE boot straight off the Deck.
Getting there needed unlocking SteamOS’s normally read-only filesystem just to install ordinary tools:
sudo steamos-readonly disable
sudo pacman-key --init
sudo pacman-key --populate archlinux holo
sudo pacman -Sy archlinux-keyring
sudo pacman -S tcpdump ethtoolThen it was one dead end after another, each plausible enough to chase for a while before turning out to be wrong:
- The static IP I assigned to the USB-Ethernet interface kept vanishing. Turned out SteamOS’s NetworkManager was silently reclaiming the interface and stripping it. Fixed with
nmcli device set <iface> managed nobefore reassigning the address. tcpdumpconfirmed the ThinkCentre’s DHCP discover packets were genuinely arriving at the Deck — but nothing ever answered back.- Client MAC filtering looked like a suspect (iVentoy has an allow/deny list), so I explicitly allow-listed the ThinkCentre’s MAC. No change.
- iVentoy’s “Secondary DHCP” setting looked like a suspect too — it’s meant for networks that already have a DHCP server and only want iVentoy to supplement it. Flipped it off. No change.
- Checked for an outbound firewall eating the replies with
sudo iptables -L OUTPUT -n -vandsudo nft list ruleset. Both came back clean.
The actual bug, when I finally found it, was almost insulting: buried in iVentoy’s own log was a line reading Bind Socket(192.168.100.1) to Device enp4s0f3utc2 — one character off from the adapter’s real name, enp4s0f3u1c2. Somewhere in iVentoy’s saved config, u1c2 had become utc2. I renamed the actual kernel interface to match the typo rather than fight iVentoy’s own settings UI:
sudo ip link set enp4s0f3u1c2 down
sudo ip link set enp4s0f3u1c2 name enp4s0f3utc2
sudo ip link set enp4s0f3utc2 upThe log confirmed a clean bind. The DHCP requests still went unanswered. Hours in, I called it: something below the layer any of these tools could see, most likely a driver quirk in how this specific USB Ethernet chipset handles the raw hand-crafted packets a PXE server has to send back to a client that doesn’t have an IP yet, was eating the replies. No amount of ss, tcpdump, or config-file archaeology was going to fix a problem at that layer.
Round two: turning it into a USB drive instead
The fix wasn’t a fix at all — it was giving up on PXE and using the Deck completely differently. Its USB-C port isn’t just a host port; it’s a genuine dual-role port on the same DWC3 controller that lets phones act as USB peripherals. Flip one setting in the Deck’s own BIOS (hold Volume Up + Power to get there): Setup Utility > Advanced > USB Configuration > USB Dual-Role Device, from XHCI to DRD.
Back in SteamOS, Linux’s USB gadget framework can emulate a mass-storage device by hand through configfs, backed directly by a file:
sudo modprobe libcomposite
cd /sys/kernel/config/usb_gadget/
sudo mkdir -p g1 && cd g1
echo 0x1d6b | sudo tee idVendor
echo 0x0104 | sudo tee idProduct
sudo mkdir -p strings/0x409
echo "SteamDeck" | sudo tee strings/0x409/manufacturer
sudo mkdir -p configs/c.1/strings/0x409
sudo mkdir -p functions/mass_storage.usb0
echo 1 | sudo tee functions/mass_storage.usb0/lun.0/ro
echo 0 | sudo tee functions/mass_storage.usb0/lun.0/cdrom
echo /home/deck/iventoy/iventoy-1.0.39/iso/proxmox-ve_9.2-1.iso | sudo tee functions/mass_storage.usb0/lun.0/file
sudo ln -s functions/mass_storage.usb0 configs/c.1/
ls /sys/class/udc/
echo dwc3.1.auto | sudo tee UDCThat last echo is the moment the Deck stopped being a handheld and became, as far as anything plugged into it was concerned, an external drive containing exactly one file: a bootable Proxmox installer, read-only so nothing on the other end could corrupt it. Plugged into the Mac first as a sanity check, it mounted as a volume labeled PVE. Moved the same cable to the ThinkCentre, hit F12, and there was a normal USB storage boot entry, functioning exactly like a flashed flash drive, except the “drive” was a game console that had spent the previous three hours failing to be a PXE server.
Proxmox Is Up
From there it was almost anticlimactic: pick the NVMe as the target disk, set a static IP on the home network (with a note to self to reserve it in the Google Home app afterward, since Nest Wifi doesn’t let you carve out a real DHCP range), swap the enterprise APT repo for the no-subscription one, disable the Ceph repo entirely since a single-node homelab box has no use for it, and reboot into a working Proxmox web UI.
One more small trap on the way: Proxmox 9’s repo files moved to Debian’s newer deb822 .sources format, so the old one-line sed trick for disabling the enterprise repo just returns “no such file.” Worth knowing before you go looking for a file that quietly doesn’t exist anymore.
What’s Next
Episode 2 picks up where the actual plan begins: hardening the box and wiring up remote access so an AI agent can administer it directly, standing up the Home Assistant OS VM, and knocking out the Uptime Kuma and AdGuard Home LXCs, all while the Sonoff Dongle Plus MG24 is still in transit and SmartThings stays live in parallel until every device has migrated.
By the Numbers
- 0 — working USB drives, SD readers, or card readers in the house at the start of this episode
- 5 — distinct workarounds attempted before one actually worked
- 1 — camera (DJI Osmo Pocket 3) that refused to cooperate on principle
- 1 — smartphone (iPhone) ruled out on protocol grounds alone, no testing required
- 1 — single mistyped character in a config file responsible for an entire dead-end PXE server
- 3 — completely different computers used to confirm one USB card reader was, in fact, dead
- 1 — Steam Deck temporarily demoted from “handheld gaming PC” to “USB flash drive”
- 256GB — the NVMe that eventually got Proxmox on it, the boring way, after all of that