[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-83982":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":13,"stars7d":17,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":18,"compositeScore":19,"rankGlobal":10,"rankLanguage":10,"license":20,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":23,"hasPages":21,"topics":24,"createdAt":10,"pushedAt":10,"updatedAt":40,"readmeContent":41,"aiSummary":10,"trendingCount":16,"starSnapshotCount":16,"syncStatus":14,"lastSyncTime":42,"discoverSource":43},83982,"HAIR","DAB-LABS\u002FHAIR","DAB-LABS","IR device admin panel for Home Assistant. Learn signals, assign to devices, create triggers, all from the GUI. Built on HA 2026.4+ infrared platform. ESPHome and Broadlink compatible.","",null,"Python",68,3,2,6,0,9,15,53.21,"MIT License",false,"main",true,[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39],"broadlink","climate","custom-component","esphome","hacs","home-assistant","homeassistant","infrared","iot","ir-blaster","ir-remote","media-player","pronto","remote-control","smarthome","2026-06-12 04:01:42","\u003Cp align=\"center\">\n  \u003Cimg src=\"images\u002FHAIR-readme-hero-v0.2.png\" alt=\"HAIR Full Service barbershop banner with the TX mascot welcoming the new RX mascot at the shop entrance, RX IS HERE speech bubble overhead\" width=\"900\" \u002F>\n\u003C\u002Fp>\n\n# HAIR\n\n***HAIR moves your IR codes out of vendor clouds, blaster memory, and config files, and into Home Assistant itself.*** Point any remote at an ESPHome IR receiver, press a button, and HAIR turns that signal into a native HA entity. A button you can fire from any dashboard. An event that ***triggers automations***. A command broadcast through any blaster on HA's native `infrared` platform, whether that is an ESPHome IR LED, a [Tuya Local](https:\u002F\u002Fgithub.com\u002Fmake-all\u002Ftuya-local) IR blaster, a Broadlink RM, an SMLIGHT SLZB, or anything else that adopts the platform.\n\nNo manufacturer picker. No model lookup. No code file downloads. No YAML. Just point, press, use.\n\n## Platform state\n\nHome Assistant's native `infrared` platform shipped transmit (TX) support in HA 2026.4 and receive (RX) support via `InfraredReceiverEntity` in HA 2026.6.\n\n### Infrared platform compatibility\n\nHAIR works with any integration that exposes HA's native `infrared` entity platform. These integrations have adopted it:\n\n| Integration | Source | TX | RX | Status |\n|---|---|---|---|---|\n| [ESPHome](https:\u002F\u002Fesphome.io\u002F) | Core | Yes | Yes | Since 2026.4 (TX), 2026.6 (native RX) |\n| [Tuya Local](https:\u002F\u002Fgithub.com\u002Fmake-all\u002Ftuya-local) | HACS | Yes | No | Since 2026.4 |\n| [Broadlink](https:\u002F\u002Fwww.home-assistant.io\u002Fintegrations\u002Fbroadlink\u002F) | Core | Yes | No | Since 2026.5 |\n| [SMLIGHT](https:\u002F\u002Fwww.home-assistant.io\u002Fintegrations\u002Fsmlight\u002F) | Core | Yes | No | Since 2026.5 |\n\nOn HA 2026.6+, HAIR subscribes to native `InfraredReceiverEntity` instances via `infrared.async_subscribe_receiver()`. Any integration that implements the receiver entity works as a HAIR receiver automatically. On HA 2026.4-2026.5, HAIR falls back to the legacy ESPHome event bus bridge (see [ESPHome Receiver Setup](#esphome-receiver-setup) below).\n\nAs more integrations adopt the `infrared` platform, HAIR picks them up with no changes needed on HAIR's side.\n\nHAIR fingerprints every captured signal using short\u002Flong (S\u002FL) pulse-duration analysis. Each pulse is classified short or long, producing a pattern that identifies the signal regardless of minor timing jitter between presses. S\u002FL works across NEC, Samsung, JVC, LG, Sony, and RC-5\u002FRC-6 without needing to decode the protocol. The Sniffer groups signals by source remote, deduplicates repeated presses, filters held-button repeat frames, and tracks hit counts, all in real time.\n\n## Screenshots\n\n| Devices Overview | Device Detail |\n|:---:|:---:|\n| ![Devices overview showing HAIR Devices, Triggers, Emitters, Receivers, and Proxies](images\u002Fscreenshots\u002Fdevices-overview.png) | ![Device detail with learned commands, S\u002FL fingerprints, and trigger buttons](images\u002Fscreenshots\u002Fdevice-detail.png) |\n\n| Action Mapping | Sniffer |\n|:---:|:---:|\n| ![Action mapping popover for binding commands to HA entity features](images\u002Fscreenshots\u002Faction-mapping.png) | ![Sniffer showing captured signals with S\u002FL diamond fingerprints, trigger buttons, and hit counts](images\u002Fscreenshots\u002Fsniffer-signals.png) |\n\n| Assign Signal | Create Trigger | Promote Device |\n|:---:|:---:|:---:|\n| ![Assign dialog for mapping a captured signal to a device command](images\u002Fscreenshots\u002Fassign-dialog.png) | ![Create Trigger dialog with S\u002FL diamond pattern and min hits setting](images\u002Fscreenshots\u002Ftrigger-dialog.png) | ![Promote dialog for creating a new HAIR device from an unknown remote](images\u002Fscreenshots\u002Fpromote-dialog.png) |\n\n## Requirements\n\n- Home Assistant **2026.4** or later\n- Python 3.12+\n- **For capture (RX):** any integration that exposes HA's native `InfraredReceiverEntity` (HA 2026.6+) -- ESPHome IR receivers work day-one, and any other integration that adopts the receiver entity works automatically. On HA 2026.4-2026.5, HAIR falls back to the legacy ESPHome event-bus bridge (see [ESPHome Receiver Setup](#esphome-receiver-setup) for the YAML stub).\n- **For send (TX):** at least one integration on HA's native infrared platform (ESPHome infrared entities, [Tuya Local](https:\u002F\u002Fgithub.com\u002Fmake-all\u002Ftuya-local) IR blasters, Broadlink RM series, SMLIGHT SLZB devices, etc.)\n\n## Installation\n\n### HACS (Recommended)\n\n1. Open HACS in your Home Assistant instance\n2. Go to **Integrations**\n3. Click the three-dot menu > **Custom repositories**\n4. Add `https:\u002F\u002Fgithub.com\u002FDAB-LABS\u002FHAIR` with category **Integration**\n5. Search for \"HAIR\" and install\n6. Restart Home Assistant\n\n### Manual\n\n1. Copy `custom_components\u002Fhair` into your HA `custom_components\u002F` directory\n2. Restart Home Assistant\n\n## Setup\n\n1. Go to **Settings > Devices & Services**\n2. Click **Add Integration** and search for \"HAIR\"\n3. The config flow auto-detects your IR hardware (emitters and receivers)\n4. Once added, find **HAIR** in the sidebar\n\n### ESPHome Receiver Setup\n\nThis setup is only needed if you are on HA 2026.4 or 2026.5 (before native `InfraredReceiverEntity` shipped), or if you are on 2026.6+ but have not yet migrated your ESPHome YAML to register the receiver entity on the `infrared` platform. In both cases, HAIR uses the legacy event-bus bridge below to receive signals from your ESPHome IR receiver.\n\nIf you are on HA 2026.6+ and your ESPHome YAML registers the receiver via the `infrared` platform, HAIR subscribes to it directly through `infrared.async_subscribe_receiver()` and this bridge is not needed. The Devices tab will show a `RX-NATIVE` badge on the receiver card when that path is active, or `RX-BRIDGE` when this legacy bridge is in use.\n\nAdd this to your ESPHome device's `remote_receiver` block to wire up the bridge:\n\n```yaml\nremote_receiver:\n  id: ir_receiver\n  pin:\n    number: GPIO5   # your IR receiver data pin\n    inverted: true\n  dump: pronto\n  on_pronto:\n    then:\n      - homeassistant.event:\n          event: esphome.remote_received\n          data:\n            protocol: \"PRONTO\"\n            code: !lambda 'return x.data;'\n```\n\nThe `on_pronto` trigger catches every IR signal regardless of protocol (NEC, Samsung, Sony, RC-5, etc.) and fires it as a `homeassistant.event` on the HA bus. HAIR's Signal Monitor subscribes to these events automatically.\n\nWhen you are ready to migrate to the native receiver path on HA 2026.6+, add the `infrared` platform receiver entry to your ESPHome YAML (canonical examples in [`esphome\u002F`](esphome\u002F)) and reflash. HAIR will detect the native receiver and switch over automatically. You can keep the legacy `on_pronto` bridge in place during the transition: HAIR will not double-process signals, and the panel will show both `RX-NATIVE` and `RX-BRIDGE` badges until you remove the bridge from your YAML.\n\nFor ready-made, HAIR-tested configurations for common ESP32 boards and IR devices (XIAO Smart IR Mate, Athom RF IR Remote, generic ESP32s), see [`esphome\u002F`](esphome\u002F) in this repo. Each device has two tiers: minimal (just the IR pieces) and full (preserves device-specific features like touch pads and status LEDs).\n\n## Features\n\n**Native Receiver Support (HA 2026.6+)** - HAIR subscribes to native `InfraredReceiverEntity` instances via `infrared.async_subscribe_receiver()`. Hardware-agnostic. Any integration that adopts the receiver entity works automatically. On HA 2026.4-2026.5, HAIR falls back to the legacy ESPHome event-bus bridge with no change required from you.\n\n**Signal Sniffer** - Passive IR listener that runs in the background. Every IR transmission your receivers detect is captured, fingerprinted, and grouped by source device. Signals are deduplicated automatically: press the same button ten times and you see one signal with a hit count of ten. Repeat frames (sent when you hold a button down) are filtered out so only actual command signals appear. The Sniffer shows you what remotes are active in your home and which buttons are being pressed, all in real time. Use the Test button on any captured signal to fire it through an emitter picker before assigning it to a device, useful for spot-checking that the signal you captured actually controls the device you think it does.\n\n**HAIR Clipper** - Build virtual remotes by pasting Pronto hex codes, for when you have a code from an online converter, a vendor datasheet, or an ESPHome log but no live signal to sniff. Create a named remote on the Clipper tab, then add a button by pasting its Pronto code. The dialog validates the code as you paste it (the detected carrier frequency, the burst pair count, an S\u002FL diamond preview, and specific error messages when something is off) so you know it is well-formed before you save. A pasted signal behaves exactly like a sniffed one: test it through an emitter, turn it into a trigger, assign it to a device, or promote the whole remote.\n\n**Signal Aliases** - Give any signal a nickname by clicking its S\u002FL diamond pattern and typing. The alias replaces the diamonds in the list so you can tell your signals apart at a glance, in both the Sniffer and Clipper. An alias is a label on the signal, not a command name, so the same signal can still become differently-named commands on different devices.\n\n**Device Management** - Create profiles for your IR-controlled devices (TVs, ACs, fans, lights, switches, screens). Assign captured signals as named commands from a device-type-aware template list, or enter custom names. Assigning a signal copies it into the device and leaves the original in place, so the same signal can be assigned to more than one device or as more than one command. Each device gets native HA entities automatically based on its type. One-click duplicate clones an existing device with all its commands, action mappings, and emitter assignments preserved, useful when you have several remotes of the same model or a stack of similar AC units.\n\n**Drag-to-Reorder** - Arrange things in the order that makes sense to you, and the order sticks across reloads. Drag the commands inside a device (reflected in the dashboard button entities), drag whole device cards on the Devices tab, and drag remotes or the signals within a remote on both the Sniffer and Clipper. On the Sniffer and Clipper, a grip handle replaces the leading icon on each remote (blue on the Sniffer, copper on the Clipper) and a lighter grip sits on each signal row. A newly seen or newly added remote or signal lands on top until you move it, so the latest thing is always easy to find.\n\n**Action Mapping** - Explicitly bind IR commands to HA entity features through a popover UI. When you map a command to \"Volume Up,\" the media_player entity knows to call that command when the HA volume service is used. Features are only exposed when commands are mapped, so your entities stay clean.\n\n**Triggers** - Turn any IR signal into a native HA event entity. Create a trigger from a learned device command, from an unknown signal in the Sniffer, or from a pasted signal in the Clipper. Each trigger gets an `event` entity under a virtual \"HAIR Triggers\" device, firing an `ir_command_received` event whenever the matching signal is received. Use triggers to build HA automations that react to physical remote presses (e.g., pressing a TV power button also turns off the room lights). A configurable \"min hits\" threshold (minimum button presses) lets you require multiple presses within a 5-second window before the trigger fires, which is useful for preventing accidental activations. The Devices tab shows all active triggers with real-time fire animations.\n\n**Emitter Routing & Broadcast Control** - Assign one or more IR emitters to each device with explicit control over how commands are broadcast. Lock a device to a single emitter for room-scoped control (an AC pinned to the bedroom emitter so commands never leak to the living room), or assign multiple emitters for a wide broadcast (a single \"TV Power\" command fires through emitters in every room simultaneously). Routing is configured per-device, so you can mix tight per-room targeting for some devices with whole-house broadcast for others.\n\n**Command Templates** - Guided setup suggests which commands to capture based on device type. Select from predefined names (Power On, Volume Up, Mode: Cool, etc.) or enter custom names for anything not in the list.\n\n**Migration Visibility** - `RX-NATIVE` and `RX-BRIDGE` badges on receiver and proxy cards show at a glance which receive path each piece of hardware is using. If you have multiple ESPHome devices and you have migrated some YAML but not others, the badges make the partial-migration state obvious so you know which devices still need attention.\n\n**Mobile Navigation** - The HAIR panel includes a navigation button on phone and tablet viewports so you can return to the HA sidebar without relying on the edge-swipe gesture. Hidden on desktop.\n\n## Using HAIR\n\n### The Devices Tab\n\nThe main view shows five sections:\n\n**HAIR Devices** - Your managed IR device profiles. Each card shows the device name, type, command count, and how many emitters are assigned. Drag a card to reorder your devices; the order persists. Each card also carries two small corner actions: a duplicate icon in the top-right to clone the device with all its commands and emitter assignments preserved, and a delete icon in the bottom-right for removing the device without opening its detail view. Click anywhere else on the card to expand its detail view inline, where you can change the device type, manage emitters, drag-to-reorder commands, and see every learned command with its S\u002FL diamond fingerprint pattern. From the detail view you can test commands, delete them, or assign action mappings.\n\n**Triggers** - Active IR triggers that fire HA event entities when their signal is detected. Each trigger card shows the trigger name with a lightning bolt icon. When a trigger fires, the card flashes with an amber glow animation in real time.\n\n**Emitters** - Your IR transmitter hardware (e.g., ESPHome infrared entities, Tuya Local IR blasters, Broadlink RM series, SMLIGHT SLZB devices). These are the physical IR LEDs that send commands. Each emitter card shows its entity ID and a TX badge, plus a `TX-NATIVE` badge once the device exposes the transmitter on HA's native infrared platform.\n\n**Receivers** - Your IR receiver hardware. These feed captured signals into the Sniffer. Each receiver card shows its source integration, its entity ID, and one of two RX badges. `RX-NATIVE` means the device is exposing the receiver via HA's native `InfraredReceiverEntity` (HA 2026.6+) and HAIR is subscribing through the official API. `RX-BRIDGE` means HAIR is consuming `esphome.remote_received` events from the legacy event-bus bridge. Both work; the badge tells you which path is active. Devices on the bridge path that also have a native receiver registered will show both badges side by side during the migration window.\n\n**Proxies** - Hardware devices that have both TX and RX capabilities. A single ESPHome board with an IR LED and an IR receiver shows up here with TX and RX badges plus their NATIVE \u002F BRIDGE state, so you can see the full migration picture for that device in one card.\n\n### The Sniffer Tab\n\nThe Sniffer is a passive listener that shows every IR signal your receivers pick up. Signals are grouped by source device (identified by carrier frequency and preamble fingerprint) and displayed with hit counts, signal counts, and last-seen timestamps.\n\nEach source device row can be expanded to show individual signals with their S\u002FL diamond fingerprint. From here you can assign a signal directly to a HAIR device as a named command, or promote an unknown source device into a full HAIR device profile. Before promoting, click the pencil button on the source device row to give it a custom name -- otherwise the new device inherits the auto-generated source name (e.g., \"Unknown Remote 1\"). Setting the name first means the promoted device lands in your Devices tab already labeled correctly.\n\nThe Test button on any captured signal opens an emitter picker so you can choose which IR emitter to fire the test signal through, and broadcast through multiple emitters at once if you want. The picker remembers your selection for the session so subsequent Tests skip straight to Send.\n\nDevices already managed by HAIR are tagged with a \"HAIR Device\" badge. You can dismiss noisy sources (like a neighbor's remote leaking through a window) and bring them back later with the \"Show Dismissed\" toggle (hover tooltip: \"Restore previously hidden remotes\"). When dismissed remotes are still firing in the background, the button quietly glows blue and shows a small dot indicator, so you can tell at a glance that there is still activity arriving from remotes you have hidden, without re-exposing those signals in the live feed. Clicking the button clears the dot and reveals the dismissed remotes so you can restore the ones you actually want back.\n\nYou can give any signal an alias by clicking its diamond pattern and typing a name. The alias replaces the diamonds in the row, which makes it easy to tell signals apart before you assign them. Assigning a signal no longer removes it from the Sniffer either. The signal is copied into the device and stays in the list, so you can assign the same signal to several devices, or as several commands, and reuse it later. Only Delete, Dismiss, and Clear All take a signal out of the Sniffer.\n\nRemotes and signals are yours to arrange. Drag the grip handle on a remote to reorder your remotes, and drag the grip on a signal row to reorder the signals inside a remote. The order you set is remembered, and a newly seen remote or signal appears at the top until you move it.\n\n### The Clipper Tab\n\nThe Clipper tab is for building remotes by hand, for when you cannot or do not want to sniff them live. Instead of pointing a remote at a receiver, you paste a Pronto hex code for each button.\n\nClick \"+ Add Remote\" to make a named remote, then expand it and click \"+ Add Signal\" to add a signal. Paste the Pronto code into the dialog. As you paste, HAIR validates the code and shows a green or red check, the detected carrier frequency, the burst pair count, and the same S\u002FL diamond fingerprint you see in the Sniffer, along with a specific message if anything is wrong (a header that is not `0000`, a truncated code, non-hex characters, or an unusual carrier frequency). Press Enter or click Create once it validates, and give it an alias up front if you like. Pasting a code that is already on the remote is refused, so a remote never ends up with two identical signals.\n\nFrom there a clipped signal is identical to a sniffed one. Test it through an emitter, create a trigger from it, assign it to an existing HAIR device, or promote the whole remote into a new device. Clipped remotes are never aged out automatically, so anything you build here stays until you delete it. Drag the grip handle on a remote to reorder your remotes, and drag the grip on a signal row to reorder the signals inside a remote.\n\nPronto is the only paste format for now. Raw timings, Broadlink base64, and protocol-plus-command entry are not supported. A device database picker that pre-fills commands is planned for a future release and will live alongside the paste field on this same tab.\n\n### Adding a Device\n\nThere are four ways to add a device.\n\n**From scratch:** Click the \"Add Device\" button in the tab bar on the Devices tab. Enter a name, pick a device type, and select which IR emitters should broadcast commands for this device. HAIR creates the device profile and the corresponding HA entities immediately.\n\n**From the Sniffer (promote an unknown source):** When HAIR detects a remote it doesn't recognize, it appears in the Sniffer as an unknown source device. Click the pencil button on the source row to give it a custom name first, then promote it to a full HAIR device. Setting the name before promoting means your new device shows up in the Devices tab already labeled the way you want it, instead of carrying the auto-generated \"Unknown Remote N\" name forward. This path is ideal when you have the physical remote in hand and want to capture its signals first.\n\n**From the Clipper (promote a built remote):** A remote you build by hand in the Clipper promotes the same way a sniffed one does. Once you have pasted its signals with \"+ Add Remote\" and \"+ Add Signal\", click Promote on the remote to turn it into a full HAIR device. This is the path for a device you have Pronto codes for (from a converter, datasheet, or ESPHome log) but cannot capture live.\n\n**From an existing device (duplicate):** Click the duplicate icon in the top-right corner of any device card. HAIR opens a dialog pre-filled with `\u003Coriginal name> (Copy)` so you can rename the clone before it lands. All of the original device's commands, action mappings, and emitter assignments are copied across; triggers stay attached to the original. This path is ideal when you have several remotes of the same model (a stack of similar AC units, two identical TVs in different rooms) or when you want a sandbox copy to experiment with action mappings without breaking the working device.\n\n### Learning Commands\n\nNavigate to the Sniffer tab and press buttons on your physical remote. HAIR captures each signal in real time. Expand the source device row, then click on a signal to assign it to one of your HAIR devices. Pick a command name from the device-type-aware template list (e.g., \"Power On,\" \"Volume Up,\" \"Mode: Cool\") or enter a custom name.\n\nWhen you don't have the physical remote to hand, build the command in the Clipper instead: paste the button's Pronto code on the Clipper tab, then Assign it to a device exactly as you would a sniffed signal. Sniffed and clipped signals are interchangeable once captured.\n\nYou can also start from a device. A device's detail view has two add-command buttons, \"+ Sniffed Signal\" and \"+ Clipped Signal\", which take you to the Sniffer or the Clipper tab so you can capture or paste the signal and assign it back to the device.\n\n### Action Mapping\n\nAfter learning commands, open a device's detail view and click the \"ACTIONS\" badge on any command row. A popover shows all available actions for that device type. Pick an action to bind it to that command. For example, mapping \"Power On\" to the `turn_on` action means the HA media_player's power button will fire that IR command. Actions already mapped to other commands are shown with their current assignment so you can reassign with a single click.\n\n### Triggers\n\nTriggers let you use incoming IR signals as automation triggers in Home Assistant. There are three ways to create a trigger.\n\nFrom a device command: expand a device in the Devices tab and click the trigger button on any command row. This creates a trigger linked to that command's signal. If a trigger already exists for that command, the button opens the trigger in edit mode instead.\n\nFrom the Sniffer: expand an unknown device and click the trigger button on any signal row. This creates a trigger from the raw signal fingerprint, which is useful for signals you want to react to without assigning them to a HAIR device.\n\nFrom the Clipper: expand a clipped remote and click the trigger button on any signal row, the same as in the Sniffer. This turns a pasted Pronto code into an automation trigger without having to assign it to a device first.\n\nEach trigger has a configurable \"min hits\" value (minimum button presses, 1 to 10) that controls how many times the signal must be received within a 5-second window before the trigger fires. Setting this to 2 or 3 is useful for preventing triggers from firing on stray or accidental presses.\n\nActive triggers appear in the Triggers section at the bottom of the Devices tab. When a trigger fires, its card flashes with an amber glow animation. Each trigger creates an `event` entity (e.g., `event.hair_triggers_tv_power`) that you can use directly in HA's automation editor as a trigger condition.\n\n## Entity Platforms\n\nDevices automatically get native HA entities based on their type:\n\n| Type | HA Entity | Controls |\n|------|-----------|----------|\n| Media Player | `media_player` | Power, volume, mute, source, channels, navigation, transport |\n| AC | `climate` | HVAC modes, temperature presets, fan modes |\n| Fan | `fan` | Power, speed stepping, oscillate |\n| Light | `light` | On\u002Foff, brightness stepping |\n| Switch | `switch` | On\u002Foff |\n| Screen | `cover` | Open, close, stop |\n| Other | `remote` | Generic IR command sender |\n\nEvery device also gets a `remote` entity for sending arbitrary Pronto hex codes and a `button` entity for each learned command. The button entities give you one-tap access to any IR command from dashboards, automations, or scripts, regardless of device type.\n\nTriggers create `event` entities under a shared \"HAIR Triggers\" device. Each trigger entity fires an `ir_command_received` event when its signal is detected, making it available as an automation trigger in HA's automation editor.\n\nEntity features are driven by explicit action mappings. A media_player only exposes volume control if you map commands to the volume actions. This keeps your entities clean and avoids exposing features your remote doesn't support.\n\n## How It Works\n\nHAIR sits between you and HA's IR platform. It does not replace your IR hardware integrations (ESPHome, Tuya Local, Broadlink, etc.). It complements them by providing the admin layer those integrations lack.\n\n### Capture (RX)\n\nHAIR uses a dual-path receive architecture. On HA 2026.6 and later, HAIR subscribes to native `InfraredReceiverEntity` instances via `infrared.async_subscribe_receiver()`. This is hardware-agnostic: any integration that exposes a receiver entity on the `infrared` platform works automatically, no per-vendor code in HAIR. On HA 2026.4-2026.5, HAIR falls back to the legacy ESPHome event-bus bridge (see [ESPHome Receiver Setup](#esphome-receiver-setup) above for the YAML stub). Both paths feed the same signal-processing pipeline so fingerprinting, deduplication, and trigger matching behave identically regardless of which path is active. The Devices tab surfaces which path each receiver is using via `RX-NATIVE` and `RX-BRIDGE` badges.\n\n### Transmit (TX)\n\nHAIR transmits IR signals via any integration that exposes HA's native `infrared` platform. Currently ESPHome, [Tuya Local](https:\u002F\u002Fgithub.com\u002Fmake-all\u002Ftuya-local), Broadlink, SMLIGHT, and other integrations that adopted the platform.\n\n### Signal Fingerprinting\n\nCaptured IR signals are fingerprinted using S\u002FL (short\u002Flong) pulse-duration classification. Each pulse in the signal is classified as short or long, producing a pattern that uniquely identifies the signal regardless of minor timing jitter between presses. In the UI, these patterns are shown as two-tone diamond sequences for quick visual identification.\n\nS\u002FL fingerprinting covers all major consumer IR protocols including NEC, Samsung, JVC, LG, Sony, and RC-5\u002FRC-6. Repeat frames (sent while a button is held) are filtered automatically. Signals are grouped by source device using carrier frequency and preamble analysis, so the Sniffer knows which remote a signal came from without needing to decode the specific protocol.\n\n### Architecture\n\nTwo signal sources feed one catalog: live capture (Sniffer) and manual Pronto paste (Clipper).\n\n```\n  Remote Control                              Pasted Pronto hex\n        |                                            |\n  IR Receiver Hardware                               |\n        |                                            |\n  +--------------------------+---------------------------+\n  | Native (HA 2026.6+)      | Legacy (HA 2026.4-2026.5) |\n  | InfraredReceiverEntity   | ESPHome remote_receiver   |\n  | async_subscribe_receiver | esphome.remote_received   |\n  +--------------------------+---------------------------+\n        |                                            |\n  HAIR Signal Monitor (RX capture)        Clipper (manual paste)\n        |                                            |\n        +---------------------+----------------------+\n                              |\n   Signal Store  (S\u002FL fingerprint + dedup; tracks sniffed vs manual)\n                              |\n                  Trigger Manager --> Event Entities (HA automations)\n                              |\n   HAIR Admin Panel  (Sniffer tab + Clipper tab)\n                              |\n   Assign signal \u002F Promote remote --> Device Manager --> Entity Factory\n                              |\n   HA Entities (media_player, climate, fan, light, switch, cover, remote, button)\n                              |\n   HA infrared Platform (infrared.send_command)  \u003C-- TX path: any platform integration\n                              |\n   IR Emitter Hardware (ESPHome, Tuya Local, Broadlink, SMLIGHT, etc.)\n```\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n## License\n\nMIT. See [LICENSE](LICENSE) for details.\n","2026-06-11 04:11:59","CREATED_QUERY"]