Sends Bang & Olufsen Beo4 IR commands through Home Assistant's infrared platform. Any emitter on that platform works as long as it can produce a 455 kHz carrier. This integration is vibe-coded, using the official LG Infrared integration as inspiration: https://github.com/home-assistant/core/tree/dev/homeassistant/components/lg_infrared
- Home Assistant 2026.9 or later
- An infrared emitter entity, for example ESPHome
ir_rf_proxyon an ESP32.
Tested and working:
- IoTorero RF433 IR Remote Controller, sold by Athom: https://www.athom.tech/blank-1/esphome-rf433-ir-remote-controller
Most other IR proxies should work too. Beo4 uses a 455 kHz carrier, which manufacturers rarely mention (the IoTorero doesn't either), so there's no way to know for sure without trying. ESP32-based devices running ESPHome improve the chances, since the ESP32's RMT peripheral can generate 455 kHz, but it still depends on the rest of the device's hardware.
Got it working with another device? Feel free to report back by opening an issue (https://github.com/cklit/ha-beo4-infrared/issues), and it will be added to the list.
Note! The configuration below is only necessary if you're building your own IR transmitter. The IoTorero device mentioned above works out of the box with this integration.
remote_transmitter:
id: ir_tx
pin: GPIOXX
carrier_duty_percent: 50%
infrared:
- platform: ir_rf_proxy
name: IR Transmitter
remote_transmitter_id: ir_txThe carrier frequency is sent with each command, so the transmitter doesn't need any 455 kHz setting and can still be used for 38 kHz devices.
HACS → three-dot menu → Custom repositories → add this repository (https://github.com/cklit/ha-beo4-infrared) as type Integration. Install, restart, then add Beo4 Infrared under Settings → Devices & services and pick the emitter.
Mode select (Audio / Video). Decides which link the non-source keys go to. Restored after a restart. Changing it sends nothing.
Source buttons always go to their own link and switch the mode, like on a real Beo4:
| Button | Link | Command |
|---|---|---|
| TV | Video 0x00 | 0x80 |
| DVD | Video 0x00 | 0x86 |
| DTV (formerly Sat) | Video 0x00 | 0x8A |
| V.Aux2 | Video 0x00 | 0x8D |
| Camera | Video 0x00 | 0x87 |
| PC | Video 0x00 | 0x8B |
| V.Mem | Video 0x00 | 0x85 |
| Radio | Audio 0x01 | 0x81 |
| CD | Audio 0x01 | 0x92 |
| A.Mem | Audio 0x01 | 0x91 |
| A.Aux | Audio 0x01 | 0x83 |
| N.Radio (Phono) | Audio 0x01 | 0x93 |
| N.Music (A.Tape2) | Audio 0x01 | 0x94 |
Other buttons go to the current mode's link:
| Button | Command |
|---|---|
| Standby | 0x0C |
| Mute | 0x0D |
| Vol + / Vol - | 0x60 / 0x64 |
| Go / Stop | 0x35 / 0x36 |
| Up / Down | 0x1E / 0x1F |
| Left / Right | 0x32 / 0x34 |
| Exit | 0x7F |
| Red / Green / Yellow / Blue | 0xD9 / 0xD5 / 0xD4 / 0xD8 |
| 0–9 | 0x00–0x09 |
State is assumed. Nothing is read back from the product.
protocol.py is a port of ESPHome's remote_base/beo4_protocol.cpp. The test suite compares its output against vectors generated by compiling and running ESPHome's encoder. All 65,536 link/command pairs were checked to match during development.
pip install -r requirements_test.txt
pytestMIT

0 comments
log in to comment.