Open firmware for Control4 controllers: EA-1/EA-3/EA-5 and HC-800/HC-250. Will not run an automation system. Essentially exposes the IO from these devices to the network. Intended to be reused in newer Control4 systems or Home Assistant.
Local HTTP/WebSocket API for IR, serial, relays, contacts and Zigbee. No cloud, no Control4 software.
Working on EA-1 hardware: IR TX/RX, code library, both serial ports, Zigbee, wifi, mDNS, front LEDs, web UI. Clean-room MCU firmware flashed and stock restored, so the flash path works both ways. HC-800 next.
EA series is a rootfs overlay, not a full rebuild. All share the PowerVR SGX 545, no public driver, so we keep the stock 3.12 kernel. Buildroot is planned for HC-800/HC-250: the HC-800 uses an Intel Atom D525 with GMA 3150, which has an open driver, but not one that meets the Android LXC UI requirements.
No Control4 code is included. Their binaries are analysed to recover facts (addresses, pin maps, protocol shapes); everything shipped is written from those. See docs/openness.md.
- Zigbee: EM357
- MCU (EA): TM4C1231D5
- MCU (HC): LM3S1162
MCU/Zigbee use UART (HC) or a CP2104 USB-to-UART (EA).
| EA-1 | EA-3 | EA-5 | HC-250 | HC-800 | |
|---|---|---|---|---|---|
| SoC | Intel CE5310 | ? | ? | ? | Intel D525 |
| GPU | SGX 545 | SGX 545 | SGX 545 | ? | GMA 3150 |
| MCU | TM4C1231D5 | TM4C1231D5 | TM4C1231D5 | LM3S1162 | LM3S1162 |
| IR out | 5 | 6 | 6 | 4 | 6 |
| — IR jacks | 2 | 3 | 4 | 4 | 6 |
| — Serial/IR combo | 2 | 3 | 2 | – | – |
| — Front blaster | 1 | 1 | 1 | 1 | 1 |
| — IR receiver | 1 | 1 | 1 | 1 | 1 |
| Serial | 2 | 3 | 4 | – | 2 |
| Relays | – | 1 | 4 | 1 | 4 |
| Contacts | – | 1 | 4 | 1 | 4 |
| Coax out / in | – | 1 / 1 | 2 / 2 | – | 1 / – |
| Aux out / in | – | 1 / 1 | 2 / 2 | 1 / 1 | 2 / 1 |
| Video out | HDMI | HDMI | HDMI | HDMI/composite | HDMI/composite |
| USB | 1 | 1 | 1 | 1 | 1 |
| eSATA | – | – | 1 | – | 1 |
| Ethernet | 1 | 2-port switch | 5-port switch | 1 | 1 |
| Wifi | yes¹ | yes² | yes | yes | yes |
| Zigbee | yes | yes | yes | yes | yes |
¹ removed on PoE V2 ² removed on V2 ? unverified, – not fitted
External ports only. Every IR and serial port on the back panel is driven by the IO microcontroller; the internal MCU, Zigbee and debug UARTs are not listed.
Only the EA-1 column is confirmed against hardware; the rest come from the
published specs and are marked ? where they are guesses.
One image serves every board. Per-board counts live in one case statement in
overlay/install.sh; API and UI read them from
/api/capabilities.
./build-overlay.sh # build daemons + package the overlay
ohc discover # find the controller
ohc backup <host> # ALWAYS back up first
ohc deploy <host> # install openHomeController
ohc restore <host> backups/<name> # put Control4 back, any timeUI at http://<controller>/. mDNS name is
openhomecontroller-<model>-<eth-mac>.local.
Interactive reference at /api. Spec is generated from the handlers.
curl http://<host>/api/capabilities # board inventory — call first
curl http://<host>/api/status # daemon state
curl -X POST http://<host>/api/ir/tv/powerStored codes become endpoints: POST /api/ir/<device>/<button>. Pronto and
emitter mask stay on the controller, so drivers only need the two names.
| Endpoint | |
|---|---|
GET /api/capabilities |
what this board has |
GET /api/status |
all daemons, queried concurrently |
GET/POST/DELETE /api/ir/codes |
code library |
POST /api/ir/send |
raw Pronto or stored code |
POST /api/ir/learn |
one-shot learn |
POST /api/ir/<device>/<button> |
fire a stored button |
GET/POST /api/led |
front panel |
POST /api/{iod,audio}/command |
raw daemon line protocol |
WS /ws/ir |
live capture stream |
WS /ws/serial/<port>?baud=N |
serial console, binary frames only |
Serial ports are also raw TCP from serial.base_port (7001 on EA-1). Zigbee NCP
is a raw socket on 6638 for ZHA/bellows.
make check # toolchain preflight
make # overlay + MCU firmware
make test # rust + MCU protocol + overlay service tests
make fw # MCU firmware only
make deploy HOST=<ip>Needs Rust with i686-unknown-linux-musl, Node, and arm-none-eabi-gcc.
make check verifies the toolchain can actually cross-compile — on a Mac with
both Homebrew rust and rustup, that differs from whether the target is installed.
| Path | |
|---|---|
packages/ohc-webd |
web backend + React UI (axum; UI embedded, pre-gzipped) |
packages/ohc-iod |
IO daemon: MCU protocol, IR, relays, contacts, serial |
packages/ohc-serialbridge |
raw UART over TCP (Zigbee) |
packages/ohc-display |
HDMI/GDL plane setup (C, stock stack) |
firmware/io-mcu |
clean-room TM4C1231D5 firmware |
overlay/ |
device payload: services, install, uninstall |
tools/ |
discover, deploy, backup/restore, MCU flash, probes |
docs/ |
research site (Docusaurus); markdown in docs/content/ |
Read docs/recovery.md before writing to a device.
- Back up first.
ohc backup <host>. uninstall.shrestores the stock inittab and re-enables Control4.- MCU flasher refuses to write below
0x1000, so the TI bootloader survives and a bad app image is always re-flashable. - CEFDK on EA controllers is not interruptible. A bad kernel needs hardware recovery; we don't touch it.
/dev/ttyS2on EA-1 is the PIC watchdog. Writing to it can reboot the board. Nothing here opens it.
MIT. Not affiliated with or endorsed by Control4.