Wake-on-LAN and a smart plug get a machine powered. Neither one shows you the boot menu when it does not come back.
I have been building ESP-KVM, an open-source IP-KVM firmware for the ESP32-P4. It captures the target machine’s HDMI, presents itself to that machine as a USB keyboard and mouse, and serves both in a browser - so a box with no working OS (BIOS, boot menu, a kernel that will not come up) is still reachable. It can also hand the target a disk image off its microSD card as a USB drive, so a machine that has lost its boot disk can be booted from a rescue image without anyone walking to the rack. It talks to Home Assistant over MQTT, and that part is what I want to show here.
Have a go before reading further: ESP-KVM is the console itself - the same code the device serves - with a machine behind it that does not exist. It boots, you can drive it, and there is a drive with images in it. Nothing to install and nothing to plug in; it costs you a browser tab.
What lands in HA
Turn on MQTT in the device’s settings, point it at your broker, and it publishes discovery configs on connect - no YAML, no custom component. One device, with:
Sensors - temperature, viewers connected, frame rate, resolution, codec, bitrate, uptime, free PSRAM.
Binary sensors - HDMI signal (is the target actually putting out video?), target USB (has the target enumerated the emulated keyboard?), and target power if you have wired the ATX header.
Buttons - power, reset, force off (holds the power line), Wake-on-LAN, and restart the ESP-KVM itself (diagnostic).
Screen alert - a binary sensor with device_class: problem, plus a sensor holding the words that set it off. The firmware reads the target’s screen as characters, not as a picture, so you can give it a list of phrases to watch for - kernel panic, No boot device, Press F1 to continue - and it tells HA when one of them is on the screen and which ones. That is a machine reporting its own bad news while its OS is not running to report anything.
Availability is a proper LWT topic, so the device greys out in HA when it drops off, and telemetry publishes on an interval you set (30 s default). The screen alert does not wait for that interval - it is watched separately and published within a couple of seconds of the words appearing, because “the target just printed kernel panic” is not a thing to hear about half a minute later.
What that buys you in automations
The combination that is hard to get otherwise is power control plus proof of what happened:
- Target power off but it should be up, or HDMI signal gone for 5 minutes - press power, then notify with a link to the console so you can look at the screen yourself.
- A Linux box wedged hard: the firmware guesses the target’s OS from how it enumerates USB, so the console offers a one-click REISUB instead of yanking power. The MQTT buttons stay the blunt instrument for when that fails.
- “HDMI signal lost” as an alert on its own is a decent early warning that a headless machine has died in a way ping will not tell you about.
- The screen alert is the one that has no equivalent anywhere else in my setup: an unattended box that has stopped at a BIOS prompt or panicked is invisible to ping, to a smart plug, and to anything running on the box itself - but the words are right there on the screen, and now they are a trigger. Mine notifies with the phrase it found and a link to the console.
Setup
Settings → MQTT: broker host and port, username/password, TLS optional (with certificate verification you can turn off for a self-signed broker), base topic, discovery prefix (homeassistant by default), publish interval. Off by default and costs nothing when off.
The two questions
Why not ESPHome? The HDMI capture path - a TC358743 bridge into the P4’s MIPI-CSI receiver, hardware JPEG and H.264 encoders, USB HID on the other side - is a standalone ESP-IDF firmware, not something that fits an ESPHome component. So it meets HA where the boundary is clean: plain MQTT discovery.
Is there a HACS integration? No, and I have no plans for one unless there turns out to be something MQTT cannot cover.
Honest limits
- Do not put this on the public internet. There is HTTPS with a certificate the device issues itself, and a login, but nothing here has had a security review, and it is a keyboard plugged into another machine. LAN, or a VPN - there is a WireGuard client and native Tailscale built in.
- No camera entity yet. The device serves MJPEG at
/streamand a still at/api/v1/video/frame.jpg, which HA’s MJPEG IP Camera and Generic Camera would both take - except both endpoints sit behind a session cookie, and those integrations speak basic auth or nothing. So it only works today with login turned off, which I am not going to recommend. An API token is the obvious fix and is on the list. - MQTT is off by default and none of this is wired for you - the ATX side needs optocouplers and three wires to the motherboard header (documented, but it is a soldering job).
Hardware, briefly
Two boards and a ribbon cable: a Waveshare ESP32-P4-ETH (or an ESP32-P4 Function EV board, which adds WiFi) plus a Geekworm C790 HDMI-to-CSI bridge. HDMI in from the target, USB-C to the target, Ethernet to the LAN. Flashing is a browser flasher at Flash ESP-KVM from the browser - nothing to install.
Repo: GitHub - espkvm/espkvm: IP-KVM on the ESP32-P4: HDMI capture, USB keyboard and mouse, and a browser console over HTTPS · GitHub - and the demo again, since it is the quickest way to see what the console is like: ESP-KVM
Happy to answer anything about the build.

