IRBouncer: an infrared bridge built like a small distributed system
DevelopmentFundamentalsArchitecture
A Wi-Fi infrared blaster and receiver on an ESP microcontroller, controlled entirely over MQTT, with no cloud and no app. It brings TVs, air conditioners and soundbars onto the network, while still working as a standalone IR translator without a broker.
A tiny device with distributed-system problems
Firmware is usually described by its features. What interested me was that a device this small still has to deal with the same problems as a distributed system: unreliable networks, duplicate messages, overload, partial updates and recovery without physical access.
Receive
Turn physical remote-control signals into structured events.
The device supports 80+ IR protocols and can use one or two receivers pointed in different directions.
Incoming signals are decoded, deduplicated and filtered before they reach the automation layer. The firmware suppresses its own transmissions, handles repeated button presses, filters noisy signals and can rate-limit MQTT publication.
For supported air-conditioner protocols, the device goes beyond the raw IR code and extracts state such as power, mode, temperature and fan speed.
- 80+ IR protocols
- Dual IR receivers
- TX echo suppression
- Global signal deduplication
- Protocol filtering
- Signal stability filtering
- RX rate limiting
Send
Generate and transmit IR commands instead of merely replaying captured signals.
Simple devices can be controlled by sending their decoded protocol and value directly.
Air conditioners can be controlled from parameters such as power, mode, temperature and fan speed. The firmware generates the protocol-specific IR state instead of requiring a previously captured command.
Eight transmission queues handle repeated commands, volume ramps and multi-device sequences. A newer queued command can replace an older one, so continuously changing a value results in the final command being transmitted rather than flooding the device.
- Named protocol transmission
- Raw IR replay
- Protocol-aware AC control
- 8 transmission queues
- Queue replacement
- Retry feedback
On-device automation
The device is not just an MQTT-controlled IR emitter; it contains its own automation engine.
Mapping slots translate incoming IR signals into one or more actions. An action can transmit another IR command, publish an MQTT message, wait for a non-blocking delay, ignore the signal or change the active control layer.
Mappings can operate independently of MQTT, allowing the device to remain useful when the network or broker is unavailable.
Time windows and day-of-week conditions allow simple schedules to run directly on the device.
- 40 persistent mapping slots
- IR → IR translation
- IR → MQTT actions
- Non-blocking macros
- Offline operation
- Time-based conditions
- Shift layers


Designed for remote recovery
The device is intended to be mounted somewhere you cannot easily reach.
More than 60 runtime settings can be changed through MQTT or the serial interface.
Configuration is stored in both human-readable JSON and a packed binary representation protected by CRC32. The binary representation allows fast startup while the JSON representation remains easier to inspect and migrate.
After repeated crash boots, the firmware enters a safe mode that keeps network access and update mechanisms available for remote recovery. A watchdog, LED diagnostics and explicit configuration-loss handling make failures visible.
Firmware can be updated over the air either from the development environment or by providing an update URL through MQTT.
- 60+ runtime settings
- Dual JSON/binary configuration
- CRC32 validation
- Crash-boot safe mode
- Watchdog recovery
- OTA updates
- Remote backup and restore
MQTT as an RPC interface
MQTT is used as the device API rather than simply as an event bus.
Every command can carry a confirmation identifier. The device responds with explicit states such as ok, error, retry, replaced or cancelled.
The protocol is self-describing: clients can query the supported IR protocols and retrieve parameter schemas. This allows a dashboard or automation system to construct controls without hardcoding every protocol into the client.
The device can also expose stateful climate entities to Home Assistant.
- Bidirectional MQTT API
- Command confirmations
- Retry/replacement semantics
- Protocol discovery
- Parameter schemas
- Home Assistant integration
Hardware
A simple ESP-based design built around commodity components.
The prototype uses a NodeMCU ESP8266 with two VS1838B IR receivers and two 940 nm IR LEDs driven through a MOSFET stage.
The receivers are connected to separate GPIOs to provide wider coverage, while the two transmit LEDs point in different directions. The transmitter is driven at the IR carrier frequency through the MOSFET rather than using a mechanical relay.
- ESP8266 / ESP32
- 2× VS1838B receivers
- 2× 940 nm IR LEDs
- MOSFET IR driver
- 38 kHz carrier
Software architecture
The firmware is split into small subsystems rather than one monolithic loop.
The implementation separates IR reception, IR transmission, MQTT communication, mappings, protocol rules, OTA updates, configuration, telemetry and the serial CLI.
Persistent state is stored in LittleFS. MQTT provides the remote control surface while the serial interface provides local diagnostics and recovery.
- IR receiver
- IR sender
- MQTT handler
- Mapping engine
- Protocol rules
- OTA manager
- Settings / storage
- Telemetry
- Serial CLI


The design principle
The interesting part of IRBouncer is not sending an infrared signal. It is treating an embedded device as a small distributed-system node.
Write the contract first. Assume the network will disappear. Make updates remotely possible. Make failure visible. Keep local functionality working when the infrastructure around the device is unavailable.
- Stack
- C++ · PlatformIO · ESP8266 / ESP32 · IRremoteESP8266 · MQTT · ArduinoJson · LittleFS · Home Assistant
- Hardware
- NodeMCU ESP8266 · VS1838B IR receivers · 940 nm IR LEDs · MOSFET driver

