All notable changes to the Remote Devices integration will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
iot_classcorrected fromlocal_pushtoassumed_state. This integration only transmits IR and RF and never receives state back, solocal_pushwas wrong.assumed_stateis the value HA defines for a device whose state cannot be confirmed.sw_versionis no longer hardcoded in four places. It was a literal that had to be hand-edited on every release. A single helper now reads it frommanifest.json, so it cannot go stale.
- MIT
LICENSE, which the repository had never shipped. - CI now runs
ruff check,ruff format --checkand strictmypyagainst the integration. Previously the workflow validated HACS and hassfest metadata only, so no line of Python was ever executed by CI. - A release gate that fails a tag push when the tag disagrees with the version in
manifest.json.
- Unified the Reconfigure dialog so entries that create their own device and entries attached to an existing device now show the same fields in the same order: Emitter → Target Device (attached entries only) → Device Type → Device Name. Previously attached entries put Target Device first and hid the name, while standalone entries led with the emitter — the two looked inconsistent.
- Editable Device Name in the Reconfigure dialog for attached entries. The name defaults to the current value and, if left blank, falls back to the target device's name (attached) or the device-type label (standalone). Attached entries now also update their title on reconfigure, matching standalone entries.
- Dutch translation (
nl.json) for the full setup and reconfigure flow. - Hint text under each field in the Reconfigure dialog.
- No action required. Existing entries keep working unchanged; reopen Reconfigure to see the unified layout.
- Reverted the Tristar temperature to Temp Up / Temp Down buttons. The 0.12.x
numberstepper only shows−/+controls in a custom Tile card (with thenumeric-inputfeature); in the default device/entities card it renders as a plain value box. Two always-visible "Klik" buttons are the simpler default, so the AC is back to 5 buttons (power, temp_up, temp_down, mode, speed).
- The
numberplatform and the assumed-state temperature entity (andPlatform.NUMBER). A number entity and temp buttons can't coexist cleanly — they'd track temperature independently and drift apart.
- Reload the integration or restart HA after updating; the temperature number is replaced by the Temp Up / Temp Down buttons.
- Tristar temperature number now starts at 25 °C (the PD-8779's power-on default) instead of 22 °C, so the assumed value matches the unit out of the box.
- Tristar PD-8779 temperature as a
numberentity — a−/+stepper (16–31 °C) instead of separate Temp Up / Temp Down buttons. Changing it sends the matching number oftemp_up/temp_downIR presses and tracks an assumed value (no feedback from the AC, so it can drift if the physical remote is also used). - New
numberplatform (Platform.NUMBER).
- The Tristar AC now exposes 3 buttons (power, mode, speed) plus the temperature number, rather than 5 buttons.
- Tristar PD-8779 reimplemented correctly. Real Broadlink captures of the remote revealed it is a plain NEC remote (address
0x04) sending discrete button codes — not the stateful ZH/LT-01 AC protocol assumed in 0.10.0. It is now exposed as 5 button entities (power0x04, temp_up0x05, temp_down0x01, mode0x0D, speed0x06), decoded from packets with valid NEC checksums.
- The
climateplatform, thezhlt01.pyencoder, and all ZH/LT-01 constants — they were based on a wrong assumption about this unit and never worked.Platform.CLIMATEis no longer registered.
- If you added the Tristar device on 0.10.0, reload the integration (or restart HA) after updating: the old (non-functional) climate entity is replaced by the button entities.
- Tristar PD-8779 Air Conditioner device type (IR — ZH/LT-01 protocol) exposed as a new
climateplatform/entity- HVAC modes: off, cool, dry, fan_only, auto (heat omitted — cooling-only unit)
- Target temperature 16–32 °C (1° steps), fan auto/low/medium/high, vertical swing on/off
- Stateful protocol: every change re-sends the full 12-byte ZH/LT-01 frame (power, mode, temp, fan, swing); state is assumed/optimistic
- New
zhlt01.pyencoder (ZHLT01Command) andclimate.pyplatform;Platform.CLIMATEadded to the integration's platforms - New ZH/LT-01 constants in
const.py(timings, mode/fan/swing/power values, temp range)
- Bumped DeviceInfo
sw_versionto 0.10.0 across all platforms (also correctsfan/light, which still read 0.8.1)
- The ZH/LT-01 encoder is untested on real hardware. It is ported faithfully from the ESPHome
zhlt01component and ToniA's HeatpumpIR ZHLT01, but has not been verified against an actual Tristar PD-8779. If a field is wrong, open an issue with a Broadlink-learned capture so the encoding can be corrected.
- Audioengine A5+ Speakers device type (IR — extended NEC, 16-bit address 0x00FD, 3 commands: volume up/down, mute)
- Exposed as a
media_playerentity (volume step + mute, assumed "on" state) plus 3 buttons - No power command: the A5+ powers on/off via the front volume knob, not the IR remote
- Codes verified against the Flipper Zero IR database and the JP1 Remotes forum
- Exposed as a
NECCommandnow supports extended NEC via a newaddress_highargument. When set, the second address byte is sent verbatim instead of as the complement of the low byte — required for the Audioengine address (0xFD is not ~0x00). Standard NEC behaviour is unchanged whenaddress_highis omitted.
- Bumped DeviceInfo
sw_versionto 0.9.0.
- Command classes now inherit from the official HA ABCs.
NECCommand,SharpCommand,DenonCommand,RawBroadlinkCommand,RawTestCommandall extendhomeassistant.components.infrared.InfraredCommand.RawBroadlinkRFCommandextendshomeassistant.components.radio_frequency.RadioFrequencyCommand. Previously they were duck-typed and only worked with ourbroadlink_emitter's permissive entity — now they work with any compliant emitter, including the Broadlink integration in HA core 2026.5+ (infrared.IR_emitter/radio_frequency.RF_emitter) and ESPHome. get_raw_timings()now returns the official flatlist[int]of signed microseconds (positive = pulse, negative = space), matchinginfrared_protocols.Command.get_raw_timings(). Removed the localTiming(high_us, low_us)dataclass — there is noTimingtype in HA's official API.
broadlink_decode.decode_broadlink_b64_to_timings()returnslist[int]instead oflist[Timing].- Bumped DeviceInfo
sw_versionto 0.8.1.
- No user action required. Existing IR devices configured against our
broadlink_emitterstill work (its converter now also accepts the new format). You can also now point them at the HA-core-providedinfrared.IR_emitter/radio_frequency.RF_emitterentities and they'll work — no need for ourbroadlink_emitterfor IR.
broadlink_emitterv0.4.1+ if you're using it (the matching converter update is shipped in that release).
- RF (radio frequency) device support via the new HA 2026.5
radio_frequencyplatform - Airwit Plafondventilator (ceiling fan) device type — RF 433 MHz, OOK modulation
- 13 captured commands: lamp toggle, fan speeds 1-6, natural wind preset, brightness up/down, fan off, all off, fan direction
- Exposed as a
fanentity (speed + preset + direction), alightentity (lamp toggle), and 3 buttons (brightness_up, brightness_down, all_off) - Voice control, Lovelace fan/light cards, scenes, and automations all work natively
- New
rf_commands.pywithRawBroadlinkRFCommand— mirrors the IRRawBroadlinkCommandpattern but producesRadioFrequencyCommandobjects with frequency + OOK modulation - New
broadlink_decode.pyshared helper extracted fromnec.py— used by both IR and RF raw-command classes - Pre-decoding: every Airwit code is decoded once at module import (i7-class HA, no point paying the cost on every press)
- Two-step config flow: pick device type first, then the integration shows only the protocol-matching emitters (IR or RF)
- Renamed integration domain
infrared_remote→remote_devices(breaking; existing users must remove and re-add config entries) - Renamed integration title from "Infrared Remote" to "Remote Devices"
manifest.jsonaddsradio_frequencyto dependencies and bumps minimum HA to 2026.5- Renamed config key
CONF_INFRARED_ENTITY_ID→CONF_EMITTER_ENTITY_ID(and stored valueinfrared_entity_id→emitter_entity_id) since emitters are no longer IR-only button.py: extracted_RemoteButtonBase;IRButtonandRFButtonsubclasses dispatch to the right HA platform- DeviceInfo
manufactureris now "Remote Devices" (was "Infrared Remote") andsw_versionreflects the integration version
- Remove existing "Infrared Remote" config entries
- Update via HACS or replace the custom_components folder
- Add the new "Remote Devices" integration; re-create your TVs, receivers, lamps, etc.
- Philips RGBIC Ambient Floor Lamp device type (NEC protocol, address 0x00, 11 commands: on/off, brightness, 6 colors, night mode)
- Amino Kamai 7X Set-top Box device type (RC6 protocol, raw Broadlink-learned codes, 8 commands: power, channel up/down, play/pause/stop, forward/rewind)
- New
RawBroadlinkCommandclass for devices using protocols too complex to encode (decodes learned Broadlink packets to raw timings)
- Reconfigure flow: "Configure" button on integration entries in Settings > Devices & Services
- Shows which infrared emitter is currently linked
- Allows changing emitter, device type, and device name after setup
- Works for both standalone and attach-to-device entries
- Added Denon AVR "Stereo" surround mode button (code 230)
- Denon AVR: expanded from 7 to 15 commands — added input_cd, input_tuner, input_vcr, input_v_aux, input_cdr_tape, pure_direct, standard, multi_channel
- Renamed input_opt1/opt2 to proper names (input_tv_dbs, input_dvd)
- Denon AVR command codes were wrong: IRDB codes didn't match the actual AVR-2106 remote. Decoded real Broadlink-learned codes to get correct values (e.g., volume_up was 76 in IRDB but 241 in reality).
- Replaced IRDB-sourced Denon commands with codes decoded from actual remote: power_on (225), power_off (226), volume_up (241), volume_down (242), mute (240), input_opt1 (201), input_opt2 (227)
- Denon still not working: Removed incorrect header pulse — Denon protocol has NO header, data starts immediately with address bits. Also corrected timing to exact multiples of 264µs base unit (792µs/1848µs spaces, 43560µs frame gap).
- Denon AVR not working: Denon uses different timing from Sharp (264µs vs 320µs base unit) and requires a header pulse. Split into separate
DenonCommandencoder with correct timing: 264µs mark, 789µs/1841µs spaces, header pulse, and proper 2-bit extension frame structure.
- Sharp TV (Aquos) device type with Sharp protocol encoder (address 1, 20 commands)
- Denon AVR Receiver device type with Sharp/Denon protocol encoder (address 2, 12 commands including discrete power on/off and input selection)
- New
sharp.pyprotocol encoder supporting the Sharp/Denon IR protocol family (5-bit address + 8-bit command, two-frame transmission with inversion check) - Denon AVR media player entity shows as "Receiver" with discrete power on/off commands
- Button icons for number keys, Denon inputs (CD, DVD, Tuner, Phono), surround modes
- Attach to existing device option in config flow — IR button entities merge into an existing device (e.g., your LG WebOS TV) instead of creating a separate device
- Media player entity is skipped in attach mode (the target device already has one)
- New config flow with setup mode choice: "Create new device" or "Attach to existing device"
- Added icon URL to hacs.json so HACS displays the integration icon
- Added error handling around IR send calls in button and media_player platforms (logs and re-raises
HomeAssistantError) - Fixed
sw_versionmismatch in button and media_playerDeviceInfo(was0.3.0, now matches manifest)
- Fixed repository link in README (
your-repo→SurfHost)
- Support for the official
infrared-protocolslibrary (home-assistant-libs/infrared-protocols)- Uses
make_lg_tv_command()from the library for LG TV commands when available - Automatic fallback to built-in NEC encoder if the library is not installed
- Uses
- New
ir_commands.pymodule as unified command factory layer
- Brand icons now in
brand/directory with bothicon.pngandlogo.png(HA 2026.3+ requirement) - Removed SVG from brand folder (HA only supports PNG)
- Button and media_player platforms now use
ir_commandsfactory instead of directly instantiating NEC commands - Updated documentation URL to GitHub repository
- Added
@SurfHostas codeowner
- Integration icon in PNG and PNG@2x formats
- Proper
DeviceInfoon all entities so buttons and media_player group under one device - Optional device name field in config flow (e.g., "Woonkamer TV")
- Renamed from
ir_test_remotetoinfrared_remote
- Entities not grouping under a device in the HA device registry
- Initial release (as
ir_test_remote) - Built-in NEC protocol encoder (no external dependencies)
- LG TV device type with 18 NEC commands (address 0x04)
- Samsung TV device type with 15 NEC commands (address 0x07)
- Raw Test Signal mode for verifying the IR chain
media_playerentity with assumed state (turn on/off, volume, mute)buttonentities for each remote command with MDI icons- Config flow with emitter selection and device type dropdown
- Tested with Broadlink RM4 Pro as emitter and LG TV as target