Capturing codes, sending them, and wiring both into automations.
| Entity | Type | Purpose |
|---|---|---|
| Emitter | infrared | Send IR. Consumed by device integrations and infrared.send_command. |
| Receiver | infrared | Reports captured signals while learning mode is on. |
| Learning mode | switch | Opens the capture window. Closes itself. |
| Last captured code | sensor | Most recent capture; base64 and timings in its attributes. |
| Capture health | sensor | Listening state plus capture, noise and error counters. See continuous listening. |
| Temperature / Humidity | sensor | RM pro and RM4 pro. The RM4 mini has no sensor fitted despite reporting one. |
The blaster's LED lights up. The add-on holds it armed and polls it once a second, re-arming every 20 seconds ahead of the firmware timeout.
Aim at the blaster from within a metre or so. The Receiver entity's state updates to the capture timestamp.
Last captured code now holds the code, with the full packet in its attributes.
The switch turns itself off after 15 seconds of quiet, or 60 seconds total. Each capture extends the window, so you can record several buttons in one session.
A signal is a list of signed microsecond durations. Positive is carrier on, negative is
carrier off. This is a 32-bit NEC frame — the 9 ms header burst is unmistakable on the
left, then 32 bits where a long gap means 1 and a short gap means 0:
{{ state_attr('sensor.living_room_blaster_last_captured_code', 'base64') }}
{{ state_attr('sensor.living_room_blaster_last_captured_code', 'timings') }}
The base64 attribute is the Broadlink packet exactly as the official integration
stores it, so it drops straight into remote.send_command with a
b64: prefix if you still use that elsewhere.
actions:
- action: infrared.send_command
target:
entity_id: infrared.living_room_blaster_emitter
data:
timings: [9000, -4500, 560, -560, 560, -1690, 560]
modulation: 38000
repeat_count: 1
Or publish to the topic yourself:
actions:
- action: mqtt.publish
data:
topic: broadlink2mqtt/a1b2c3d4e5f6/emitter/set
payload: >-
{"timings": [9000, -4500, 560], "modulation": 38000, "repeat_count": 0}
repeat_count genuinely works here. Upstream's encoder leaves the packet's
repeat byte at zero and the core PR never set it; this add-on patches it in. Use
1 or 2 for stubborn air conditioners.
automation:
- alias: Store the last IR code
triggers:
- trigger: state
entity_id: sensor.living_room_blaster_last_captured_code
actions:
- action: input_text.set_value
target:
entity_id: input_text.ir_scratchpad
data:
value: "{{ state_attr(trigger.entity_id, 'base64') }}"
Leave learning mode on and use the receiver as a trigger, comparing against a known capture:
automation:
- alias: Dim the lights on the remote's red button
triggers:
- trigger: state
entity_id: infrared.living_room_blaster_receiver
conditions:
- condition: template
value_template: >-
{{ state_attr('sensor.living_room_blaster_last_captured_code', 'base64')
== 'JgBQAAABJ5MTOBM4ExMTExMTExMT...' }}
actions:
- action: light.turn_on
target:
entity_id: light.living_room
data:
brightness_pct: 30
automation:
- alias: Hold IR learning open
triggers:
- trigger: state
entity_id: switch.living_room_blaster_learning_mode
to: "off"
conditions:
- condition: state
entity_id: input_boolean.ir_capture_session
state: "on"
actions:
- action: switch.turn_on
target:
entity_id: switch.living_room_blaster_learning_mode
Flip input_boolean.ir_capture_session on while you work through a remote, then
off when you are done. Raising capture_limit is the simpler alternative.
The point of a real infrared entity is that other integrations can drive it.
Anything that asks for an infrared emitter — LG Infrared and the rest of the growing set —
will list your Broadlink blaster and handle the codes for you, with no captures needed at all.
The receiver opens the same door in the other direction: HAIR lists the official Broadlink integration as transmit-only, and this add-on is what makes its live Sniffer work with a blaster you already own.