Skip to content

About

A Home Assistant integration that enables Lutron Pico remotes to control lights, switches, and other entities.

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

Pico Link

Lutron Pico remotes as domain-aware Home Assistant controllers

HACS Custom GitHub release GitHub License

Pico Link logo


This is a fork of smartqasa/pico-link. Development of this fork was AI-assisted (Claude).

Changes in This Fork

  • UI-only configuration — every Pico is added, edited, and removed from Settings → Devices & Services; YAML configuration has been removed entirely. See Adding a Pico.
  • Multi-Pico config entries — group several identical Picos (e.g. multiple stairway remotes) under one shared, editable configuration instead of configuring each one separately.
  • Dual-light mode (P2B, 2B, 3BRL) — the ON and OFF buttons can switch between two separate lights (e.g. a center fixture and an edge/ring accent light) at a configured color, white temperature, effect, and brightness, instead of just turning one light on and off. The effect and white-temperature choices are picked from what the selected accent light actually supports, not typed in, and repeated OFF taps can cycle through several saved presets, each previewable live while you configure it. See Dual-light mode.
  • Light on/off toggle option — ON and OFF can each independently toggle a light's state instead of always issuing a discrete turn-on/turn-off.
  • Color temperature from ON/OFF holds (2BRL, 3BRL) — holding ON makes a light cooler and holding OFF makes it warmer, leaving RAISE/LOWER on brightness. See Color temperature holds.
  • Effect cycling from RAISE/LOWER (2BRL, 3BRL) — a RAISE or LOWER tap steps a light through a list of favorite effects, while holding still ramps brightness. See Effect cycling.
  • A 2BRL Pico type — the four-button raise/lower Pico (PJ2-2BRL, Pico2ButtonRaiseLower) is supported as a 3BRL without the STOP button, instead of being left out of the device picker.
  • Hold and double-tap actions (3BRL, 4B), double-tap actions (P2B, 2B) — ON, OFF, and STOP on a 3BRL, or any button on a 4B, can each run a custom action sequence when held (in addition to their normal tap behavior) or on two quick taps (instead of it) — a button can use one or the other, checked inline on the options step rather than deferred to a later error, and testable immediately from that same step. ON and OFF on a P2B or 2B can likewise run a custom action on two quick taps, replacing that button's normal tap-or-hold behavior for that gesture. See Custom actions.
  • A pico_link_button event, and device triggers for it — fired for every mapped press/release, so automations (or a tool like Node-RED) can react to a Pico's normalized button/domain without re-deriving it from the raw Lutron event; also selectable straight from the automation editor's device trigger picker, no YAML required. See The pico_link_button event.
  • Custom actions run through Home Assistant's real script engine — STOP buttons and 4B scene buttons support the same conditions, if-then, choose, repeat, and templating available in the automation editor's action picker, not just plain service calls.
  • Calendar versioning — releases are versioned YYYY.MM.DD.XX instead of semantic versioning. See Versioning.
  • Repairs and diagnostics — a hardware type mismatch, a Pico removed from the Lutron bridge, or a configured entity that no longer exists shows up under Settings → Repairs instead of only the log, and every entry supports Home Assistant's standard diagnostics download. See Diagnostics and Repairs.
  • Raising from off respects light_low_pct — a single RAISE (3BRL) or ON hold (P2B/2B) on a light that's off now lands at light_low_pct instead of a single light_step_pct, matching how a native Lutron dimmer behaves.
  • STOP light-preset cycling (3BRL) — outside dual-light mode, STOP can cycle a light through several saved appearances instead of doing nothing, using the same preset editor (with live preview) as dual-light mode. See STOP light-preset cycling.
  • UI polish — brightness, timing, and other percentage/duration fields now use Home Assistant's slider control instead of a plain number box, and a fresh color preset defaults to a visibly non-white color instead of one that looks blank against the dialog background.
  • Clearer multi-step setup/editing — each step's button now reads "Next" instead of "Submit" whenever more steps follow, and a non-4B entry's controlled entities are appended to its title on the plain integration list, since it otherwise gives no hint what an entry controls. See Editing a Pico.
  • 3BRL dual-light scenes — with an accent light configured, a 3BRL's ON selects the center lights, STOP selects the accent light, OFF turns everything off, and RAISE/LOWER cycle the accent light's effects while it's on (or dim the center lights otherwise). The last effect picked is remembered across HA restarts and light reboots. See Dual-light mode.
  • Same-room Pico recommendations — when editing which Picos belong to an entry, an eligible Pico sharing a room with one already added is labeled "Recommended" and sorted to the top, so a matching set is easy to complete. See Editing a Pico.

Overview

Pico Link converts supported Lutron Caséta Pico remotes into configurable, domain-aware Home Assistant controllers.

It listens for:

lutron_caseta_button_event

and routes Pico button events to lights, fans, covers, media players, switches, scenes, scripts, and other Home Assistant actions.

Features include:

  • Fully configured through the Home Assistant UI — no YAML editing
  • Group multiple identical Picos (e.g. several stairway remotes) under one shared configuration
  • Tap-versus-hold detection where supported
  • Brightness, volume, and cover-position stepping
  • Continuous light, cover, and media-player ramping
  • Tap-only fan speed control
  • Domain-specific STOP-button behavior
  • Ordered custom action execution, built with Home Assistant's native action picker
  • Entity placeholder expansion
  • Optimistic light, cover, fan and volume targets for responsive repeated taps, shared by all the Picos in an entry
  • Validation of Pico types, entities, domains, actions, and button mappings
  • Protection against configuring the same physical Pico twice
  • Verification that the configured Pico type matches the reported hardware type

Requirements

  • Home Assistant 2024.10.0 or newer
  • The Home Assistant Lutron Caséta integration configured and working
  • Pico button events available as lutron_caseta_button_event

Pico Link depends on the Home Assistant lutron_caseta integration and is loaded after it.


Supported Pico Types

Type Layout Buttons Supported behavior
P2B Paddle Pico on, off Domain-specific ON/OFF tap and hold behavior
2B Two-button Pico on, off Domain-specific ON/OFF tap and hold behavior
2BRL On / Raise / Lower / Off on, raise, lower, off Like 3BRL without the STOP button
3BRL On / Raise / Stop / Lower / Off on, raise, stop, lower, off Full domain control with dedicated raise/lower buttons
4B Four-button scene Pico button_1, button_2, button_3, off Ordered custom actions only

The configured type is authoritative. Pico Link verifies the hardware type reported by Lutron events. Events are ignored when the reported hardware type does not match the configured type.


Installation

HACS

  1. Open HACS → Integrations.

  2. Open the menu and choose Custom repositories.

  3. Add:

    https://github.com/davidcoulson/pico-link
    
  4. Select Integration as the repository type.

  5. Install Pico Link.

  6. Restart Home Assistant.

Manual installation

Copy the integration directory to:

config/custom_components/pico_link/

The resulting structure should include:

config/
└── custom_components/
    └── pico_link/
        ├── __init__.py
        ├── config_flow.py
        ├── manifest.json
        ├── config.py
        ├── controller.py
        ├── utilities.py
        ├── actions/
        ├── profiles/
        └── translations/

Restart Home Assistant after installation or updates.


Adding a Pico

One config entry can hold a single Pico or several — select multiple in the first step when they should all behave identically (for example, several remotes for the same stairway light). They share one configuration: entities, timing, and behavior are set once and apply to every Pico in the entry.

  1. Go to Settings → Devices & Services.
  2. Click Add Integration and choose Pico Link.
  3. Pick one or more Picos from the list. Only Lutron Pico remotes that aren't already configured (in this or any other entry) are listed — the Smart Bridge, fan speed controllers, and already-configured Picos don't show up. Every Pico you select must be the same type; each one's type is read directly from the model Lutron reports, so there's nothing to select or get wrong.
  4. For P2B, 2B, and 3BRL Picos: fill in the entities for the one domain this entry's Pico(s) control (cover, fan, light, media player, or switch), and leave the other fields empty. Click Submit and you're done — it starts working immediately with sensible default timing and behavior.
  5. For 4B Picos: build an action sequence for each button (button_1, button_2, button_3, off) using Home Assistant's action picker. At least one button must be configured.

The same physical Pico can only belong to one config entry — adding it a second time (on its own or as part of a new group) is blocked automatically, and it drops out of the device list once added.

Editing a Pico

Open the entry under Settings → Devices & Services and click Configure. You land on a menu of what to edit, so a small change doesn't require re-walking every screen:

  • Devices, entities & full setup — the full chain: add or remove Picos from the entry (only Picos of this entry's type that aren't claimed by another entry are offered, and at least one must remain — any offered Pico that's in the same room as one already in this entry is labeled "Recommended" and listed first, since a matching set, e.g. every Pico wired to the same stairway light, is usually exactly what you're looking to add), then, for non-4B entries, the same entity picker used during setup (you can even switch which domain it controls here), the timing and domain-specific options, accent light / STOP light-preset cycling where applicable, and for 3BRL, P2B, and 2B Picos, the custom actions builder — none of which the initial add flow asks about, since the defaults just work. 4B entries get the same button-action editor used during setup, followed by scene hold/double-tap actions.
  • Timing & behavior — just the domain-specific options screen, saved as soon as you submit it.
  • Accent light / dual-light mode — just the accent light (or, for a 3BRL without one, STOP light-preset cycling) screens, saved once that's done.
  • Custom actions (3BRL, P2B, 2B) / Scene buttons and Scene hold & double-tap actions (4B) — jump straight to that one screen.

Changes take effect immediately and apply to every Pico in the entry; Pico Link automatically reloads them all.

Non-4B entries (and new ones from setup) also get their controlled entities appended to the entry's title on the plain Settings → Devices & Services → Pico Link list — for example "Kitchen Pico — Kitchen Lumary" instead of just "Kitchen Pico" — since that list otherwise gives no hint of what an entry actually controls. Up to 3 entity names are listed (by friendly name where known), with any beyond that collapsed into "+N more". This updates whenever the entities step is submitted (including as part of any other edit), not retroactively for entries you don't reopen.

Each step's button reads "Next" instead of "Submit" whenever more steps follow, so it's clear before you click whether you're finishing this Pico's configuration or continuing to another screen.

Each Pico's underlying device and its type are fixed (since the type is read from the hardware, there's nothing to change there anyway) — a Pico can't switch type or move to an entry of a different type. To link a different physical Pico for the first time, add it via a new or existing entry as above; to fully replace an entry's Pico type, remove the entry and add it again.

Removing a Pico

Open the Pico's entry under Settings → Devices & Services, click the three-dot menu, and choose Delete.


Entity Configuration

A domain may be assigned one entity or several. When multiple entities are selected:

  • Commands are sent to all of them.
  • State-dependent calculations use the first selected entity as the reference.

For example, when several lights are assigned, brightness steps are calculated from the first light and the resulting brightness is sent to all assigned lights.


Options

Every timing and domain option is configured on the Timing & behavior step of setup (or editing), pre-filled with these defaults:

Field Applies to Default Range or values
hold_time_ms Light, cover, media 400 100–2000 ms
step_time_ms Light, cover, media 650 100–2000 ms
cover_open_pos Cover 100 1–100 percent
cover_step_pct Cover 10 1–25 percent
cover_inverted Cover false Boolean
fan_on_pct Fan 100 1–100 percent
light_on_pct Light 100 1–100 percent
light_low_pct Light 5 1–99 percent
light_step_pct Light 10 1–25 percent
light_transition_step_ms Light 0 0–2000 ms
light_transition_on Light 0 0–300 seconds
light_transition_off Light 0 0–300 seconds
light_on_off_toggle Light false Boolean
light_hold_color_temp Light (2BRL, 3BRL) false Boolean
light_effects Light (2BRL, 3BRL) [] Effect names, picked from the light's own effects; offered only for a light that has effects
accent_lights Light (P2B, 2B, 3BRL) [] Entity list
accent_light_presets Light (P2B, 2B, 3BRL) one default preset List of presets (see below); cycled through on repeated OFF taps
light_presets Light (3BRL only) [] List of presets (see below); cycled through on every STOP press when non-empty
media_player_vol_step Media player 10 1–20 percent

Only the fields relevant to the Pico's assigned domain are shown. Numeric selectors are clamped to their listed range.

Each entry in accent_light_presets or light_presets has its own (accent_light_* / light_preset_* respectively):

Field Default Range or values
accent_light_color_mode rgb rgb or color_temp; only offered if the accent (or, for light_preset_*, the first configured) light supports white temperature
accent_light_rgb_color [255,255,255] RGB triplet
accent_light_color_temp_kelvin 2700 Kelvin, clamped to the light's supported range
accent_light_effect "" Picked from the light's available effects; overrides color/white temperature when set
accent_light_brightness_pct 100 1–100 percent

Domain Behavior

Lights

P2B and 2B

Gesture Action
ON tap Turn on at light_on_pct (or toggle if light_on_off_toggle)
ON hold Ramp brightness upward — replaced by custom on_double_tap actions on a second quick tap, if configured
OFF tap Turn off (or toggle if light_on_off_toggle)
OFF hold Ramp brightness downward — replaced by custom off_double_tap actions on a second quick tap, if configured

3BRL

Button Tap Hold / double-tap (pick one, see below)
ON Turn on at light_on_pct (or toggle if light_on_off_toggle) Custom on_hold actions on hold, or on_double_tap actions on a second quick tap
OFF Turn off (or toggle if light_on_off_toggle) Custom off_hold or off_double_tap actions
RAISE Increase by light_step_pct Ramp upward (no hold/double-tap actions apply here)
LOWER Decrease by light_step_pct Ramp downward (no hold/double-tap actions apply here)
STOP Custom STOP actions, otherwise no action Custom stop_hold or stop_double_tap actions

Brightness does not ramp below light_low_pct, and raising a light that's off — a single RAISE tap, or a P2B/2B ON hold — lands at light_low_pct rather than a single light_step_pct, matching native Lutron dimmer behavior. See Custom actions for how hold and double-tap actions work.

Dual-light mode

Configuring accent_lights (on the "Accent light" options step, shown only for a P2B, 2B, or 3BRL assigned to the light domain) puts it into dual-light mode. Instead of turning the same light on and off, the buttons switch between two separate lights — for example a center fixture and a ring/edge accent light:

Gesture P2B / 2B 3BRL
ON tap Turn on lights at light_on_pct; turn off accent_lights Same
ON hold Ramp lights brightness upward; turns off accent_lights once the hold threshold is crossed Not applicable
STOP tap — Turn on accent_lights at the current preset; turn off lights. Another STOP while the accent light is on advances to the next preset
OFF tap Turn on accent_lights at the current preset; turn off lights. A second OFF tap while the accent light is already on advances to the next preset instead of switching anything off Turn off both lights and accent_lights
OFF hold Ramp lights brightness downward; once it bottoms out at light_low_pct, switches to accent_lights at the current preset instead of just stopping Not applicable
RAISE/LOWER — While the accent light is showing: step to the next/previous effect in its effect list (alphabetical, wrapping around; tap only, no ramp). Otherwise: step/ramp lights brightness as usual

On a 3BRL, the effect you last picked with RAISE/LOWER is remembered — shared by every Pico in the entry and saved to disk, so it survives a Home Assistant restart — and the next STOP from the center lights (or from off) returns to it instead of the preset's effect, at the preset's brightness. Because STOP always sends the effect explicitly, a light that rebooted in the meantime still comes back on the right effect. Pressing STOP again while the accent light is already on switches to the (next) preset and forgets the remembered effect. If the light no longer offers the remembered effect (renamed or removed), STOP uses the preset and forgets the name; if the light is unavailable and can't list its effects, STOP uses the preset this time but keeps the name for next time.

On a 3BRL, dual-light mode takes over STOP, so it can't be combined with custom STOP actions (middle_button) or STOP light-preset cycling — picking an accent light clears any saved STOP actions. Whether the accent light is "showing" follows the last ON/STOP/OFF on any Pico in the entry for a couple of seconds — the lights may not have reported their new state yet — and the lights' reported states after that (accent on, center off). So switching lights from the app or an automation is respected: with the accent light turned off elsewhere, RAISE/LOWER go back to the center light's brightness. A 3BRL's ON/OFF can still separately use on_hold/off_hold/on_double_tap/off_double_tap alongside dual-light mode — those actions run in addition to (hold) or instead of (double-tap) the tap behavior above.

A P2B/2B's ON/OFF can likewise use on_double_tap/off_double_tap alongside dual-light mode. Since double-tap replaces that button's tap/hold gesture rather than adding to it (see Custom actions), configuring it means a double tap runs the custom action instead of the ON-hold ramp or the OFF-hold switch-to-accent shown in the table above — a plain single tap still selects center or accent exactly as usual.

accent_lights and lights are never on at the same time. light_on_off_toggle is ignored in this mode, since ON and OFF already mean "select center" and "select accent" rather than toggling a single light.

The accent light's appearance is configured on one or more "Accent light appearance" steps — one per preset — after the accent light(s) are selected, since the available choices depend on what that light supports:

  • Effect — picked from a dropdown of the first accent light's actual supported effects (effect_list, alphabetized), instead of typing a name. Leave it on "No effect" to use color or white temperature instead. When set, it takes priority over both.
  • White temperature — only offered when the first accent light supports color temperature; lets you pick "Color" (RGB) or "White temperature" (Kelvin, clamped to that light's supported range) as the preset's appearance when no effect is selected.
  • Color — a plain RGB color, used when neither an effect nor white temperature is selected.

Each preset's step ends with a single What next? choice instead of a pile of checkboxes, since only one of these ever applies at a time:

  • Try it turns the accent light(s) on right away with whatever's currently filled in, so you can see a preset before continuing — it re-shows the same step afterward with your values kept, and doesn't count as finishing the preset.
  • Save and add another preset keeps this one and repeats the step to build a list (accent_light_presets, up to 5). With only one preset, OFF always shows the same appearance, exactly as if presets didn't exist. With more than one, ON always resets back to the first preset — only repeated OFF taps advance through the list, wrapping back to the first after the last. When editing an entry that already has more presets than you've stepped through so far, this is preselected and steps on to the next saved preset.
  • Remove this preset (only offered for a preset that already exists) drops it and moves on to the next one, so a list can be shrunk without clearing accent_lights and rebuilding dual-light mode from scratch. Removing the last saved preset finishes the list; removing the only one asks for a new preset, since dual-light mode needs at least one.
  • Save finishes here, keeping any saved presets after this one unchanged — editing one preset never drops the others.

Rapid repeated brightness taps use the most recently requested brightness for a short period instead of waiting for Home Assistant state to update. That holds across the entry's Picos: a tap on one remote steps on from a tap on another.

STOP light-preset cycling

For a 3BRL assigned to the light domain and not in dual-light mode (accent_lights empty), STOP can instead cycle lights through one or more saved appearances — for example switching a LIFX bulb between white temperatures with the middle button. Configured on the "Light presets" options step (shown only when there's no accent light), which offers the same "What next?" choice (Try it / Save and add another preset / Remove this preset / Save, up to 5 presets) as dual-light presets, plus a leading "Cycle light appearance from STOP" checkbox — leaving it unchecked configures nothing, and STOP keeps its normal behavior instead. Removing the only saved light preset turns STOP cycling off the same way.

Every STOP press advances to the next preset, wrapping back to the first after the last; turning the light on or off via ON/OFF resets the cycle back to the first preset. This is mutually exclusive with both accent_lights and custom STOP actions (middle_button) — configuring one clears the others, and the options flow won't let both be set at once.

Light transitions

light_transition_on and light_transition_off apply only to ON and OFF tap actions. light_transition_step_ms applies to brightness changes from both single RAISE/LOWER taps and continuous holds (including P2B/2B ON/OFF holds). It is capped at step_time_ms so a held ramp does not request a transition longer than the interval between steps; this cap also applies to single taps. A transition of 0 omits the field from the service call, preserving the light's existing behavior. Rapid repeated taps and device/network delays can still make transitions overlap.

Light toggle mode

Enabling light_on_off_toggle (a checkbox on the light options screen) changes both the ON and OFF buttons from discrete turn-on/turn-off actions into a toggle: each checks the light's current state and flips it. This is useful when one Pico controls a single light or light group and you want either button to work correctly regardless of which state it's currently in — handy in the dark, when you can't see which button is which.

  • P2B / 2B: tap toggles; holding still ramps in its original direction (ON hold always ramps up, OFF hold always ramps down), unaffected by this setting.
  • 3BRL: both ON and OFF simply toggle, since they have no hold behavior of their own.
  • Off by default — existing Picos are unaffected until you turn it on.
  • Ignored for a P2B/2B in dual-light mode (see above) — accent_lights already gives ON and OFF distinct, unambiguous meanings.

Color temperature holds

Enabling light_hold_color_temp (a checkbox on the light options screen, 2BRL and 3BRL only) turns ON and OFF holds into a white-temperature dial, while RAISE and LOWER keep adjusting brightness:

Gesture Action
ON tap Turn on, as usual — resolved when you let go, to rule out a hold
ON hold Ramp cooler until released or at the light's coolest; turns the light on first if it's off
OFF tap Turn off, as usual — resolved when you let go
OFF hold Ramp warmer until released or at the light's warmest; does nothing while the light is off
  • Each step moves light_step_pct of the light's supported color temperature range, every step_time_ms — the same pace as a brightness ramp. A light showing a color rather than a white starts from the middle of its range.
  • Taking over ON and OFF holds means those buttons can't also run custom on_hold/off_hold or on_double_tap/off_double_tap actions, and it can't be combined with accent_lights; the options flow says so rather than saving a conflict. STOP's own actions on a 3BRL are unaffected.
  • P2B and 2B don't offer it: their ON/OFF holds already ramp brightness, since they have no RAISE/LOWER.
  • A light that doesn't report a color temperature range ignores the holds.

Effect cycling

Picking favorites in light_effects (on the light options screen, 2BRL and 3BRL only, for a light that has effects) moves RAISE/LOWER taps from brightness to those effects, in the order picked:

Gesture Action
RAISE tap Next favorite, wrapping to the first after the last; turns the light on at light_on_pct with it if it's off
LOWER tap Previous favorite, wrapping to the last; does nothing while the light is off
RAISE/LOWER hold Ramp brightness, unchanged
  • Taps resolve when the button is released, so a hold can be told apart.
  • Stepping starts from the light's current effect. An effect that isn't one of the favorites starts RAISE at the first and LOWER at the last. After the light was off, the next RAISE carries on from the last effect picked, which is remembered across restarts and shared by every Pico in the entry.
  • A favorite the light stops offering (renamed by a firmware update, say) is skipped rather than sent, and stays selectable in the options screen so it can be removed.
  • Can't be combined with accent_lights: in dual-light mode RAISE/LOWER already cycle the accent light's effects.
  • Independent of color temperature holds; a Pico can use both.

Fans

Fan controls are always tap-only. Holding ON, OFF, RAISE, or LOWER does not initiate a ramp. A 3BRL fan Pico can still use on_hold/off_hold/stop_hold or on_double_tap/off_double_tap/ stop_double_tap to run custom actions on a hold or a double-tap, and a P2B/2B fan Pico can use on_double_tap/off_double_tap; see Custom actions.

Button Action
ON Set speed to fan_on_pct
OFF Turn off
RAISE Move up one available fan speed
LOWER Move down one available fan speed
STOP Custom STOP actions, otherwise reverse direction

Fan speed steps are calculated from the entity's percentage_step attribute.

If the fan is off, RAISE moves it to the first nonzero speed.

If the fan does not expose a usable percentage_step, Pico Link falls back to:

0 → 100

Covers

P2B and 2B

Gesture Action
ON tap Open to cover_open_pos
ON hold Move continuously in the ON direction — replaced by custom on_double_tap actions on a second quick tap, if configured
OFF tap Close fully
OFF hold Move continuously in the OFF direction — replaced by custom off_double_tap actions on a second quick tap, if configured
ON or OFF while moving Stop movement

When cover_inverted is enabled, ON and OFF tap and hold directions are reversed.

3BRL

Button Tap Hold
ON Open to cover_open_pos Custom on_hold actions, if configured
OFF Close fully Custom off_hold actions, if configured
RAISE Increase position by cover_step_pct Open continuously
LOWER Decrease position by cover_step_pct Close continuously
STOP Custom STOP actions, otherwise stop Custom stop_hold actions, if configured

Rapid repeated cover taps use the most recently requested target position for a short period instead of waiting for current_position to update.

When changing direction after continuous movement, Pico Link waits for stop_cover to complete before submitting the next position command.

Covers that can't be set to a position (plain open/close covers) can't be stepped, so a RAISE or LOWER tap opens or closes them fully instead, and the ON tap ignores cover_open_pos.


Media Players

P2B and 2B

Gesture Action
ON tap Play or pause
ON hold Raise volume continuously — replaced by custom on_double_tap actions on a second quick tap, if configured
OFF tap Next track
OFF hold Lower volume continuously — replaced by custom off_double_tap actions on a second quick tap, if configured

3BRL

Button Tap Hold
ON Play or pause Custom on_hold actions, if configured
OFF Next track Custom off_hold actions, if configured
RAISE Raise volume one step Raise volume continuously
LOWER Lower volume one step Lower volume continuously
STOP Custom STOP actions, otherwise toggle mute Custom stop_hold actions, if configured

The volume step is configured as a percentage via media_player_vol_step. Volume commands are clamped between 0.0 and 1.0.


Switches

Button Action
ON Turn on
OFF Turn off
STOP Custom STOP actions, otherwise no action
RAISE No action
LOWER No action

Switches have no domain-specific hold behavior — holding ON, OFF, RAISE, or LOWER does nothing extra by itself. A 3BRL switch Pico can still use on_hold/off_hold/stop_hold or on_double_tap/off_double_tap/ stop_double_tap to run custom actions on a hold or a double-tap, and a P2B/2B switch Pico can use on_double_tap/off_double_tap; see Custom actions.


4B Scene Controllers

A 4B Pico does not control a domain directly. Each button executes an action sequence built with Home Assistant's action picker during setup or editing.

Supported buttons:

button_1
button_2
button_3
off

At least one button must have actions configured. Actions execute sequentially in the order they were added; each action completes before the next one begins.

Each button can also optionally define a hold action or a double-tap action (not both), configured on the Scene hold and double-tap actions step in the options flow. These follow the same rules as 3BRL's custom actions: a hold action runs in addition to the button's scene action once held past hold_time_ms; a double-tap action replaces the scene action on two quick taps, which delays that specific button's scene action by up to DOUBLE_TAP_WINDOW_MS (400ms) to confirm a second tap didn't follow — buttons without one configured are completely unaffected.


STOP Actions and Domain Defaults

Custom STOP actions (middle_button) are valid only for 3BRL Picos, configured on the Custom actions step.

Resolution order:

  1. Custom STOP actions configured on the Pico
  2. For a light-domain 3BRL outside dual-light mode: cycling through light_presets, if configured (see STOP light-preset cycling)
  3. Domain-specific STOP behavior when none of the above is configured

Domain defaults

Domain Default STOP behavior
Cover Stop movement
Fan Reverse direction
Light No action
Media player Toggle mute
Switch No action

To use the domain default, leave STOP actions empty on that step.

Custom actions

On the Custom actions step, 3BRL gets ON, OFF, and STOP fields, while 2BRL, P2B and 2B (which have no STOP button) get just ON and OFF — with hold fields for 2BRL and double-tap only for P2B/2B. Filling in both a hold and a double-tap field for one button (3BRL only — see below) is caught right on this step (an inline error naming the conflict), not deferred to a later Setup failed. Leave a button's fields empty to skip it entirely; with nothing configured, no timer is created and there's no behavior change at all.

  • Hold (on_hold / off_hold, 3BRL and 2BRL; stop_hold, 3BRL only) — runs once that button has been held past hold_time_ms, in addition to its normal tap/press behavior (including custom STOP actions), which always still fires immediately on press, unchanged. This is how you can, for example, have ON turn on one light on a tap but a whole room on a hold. Not offered for P2B/2B, since ON/OFF hold is already their built-in brightness-ramp/continuous-move gesture.
  • Double tap (on_double_tap / off_double_tap / stop_double_tap, the last 3BRL only) — on a 3BRL, runs instead of that button's normal tap/press behavior when two taps land within DOUBLE_TAP_WINDOW_MS (400ms, not configurable) of each other; on a P2B/2B, it instead runs instead of that button's normal tap-or-hold behavior — a double tap replaces the gesture rather than adding to it. Configuring this changes that button's timing: since Pico Link can't know a second tap won't follow until the window passes, that button's own normal behavior is delayed by up to 400ms so it can be replaced by the double-tap action if one comes. On P2B/2B this means a held press also starts its brightness ramp (or equivalent) up to 400ms later than usual. Buttons without a double-tap action configured are completely unaffected — this delay only ever applies to a button you've explicitly set one up for. This is how you can, for example, have OFF turn off one light on a tap but a whole room on a double tap.

Test an action on this step (and on 4B's equivalent step) picks one of the fields above and runs it immediately with whatever's currently filled in when you submit, re-showing this same step with your values kept afterward — so a STOP/hold/double-tap action can be checked before you save and walk over to the physical remote.


Custom Actions: Full Home Assistant Action Support

Every custom action field — STOP, hold, and double-tap actions on any Pico type, and 4B button actions — is validated and run with Home Assistant's own action engine — the same one behind automations and scripts — not just a plain list of service calls. That means the action editor's "Building Blocks" are available too: If-then, Choose, Repeat, Wait, Delay, and templates in service data.

This makes state-dependent behavior possible without any code changes. For example, a STOP button that turns on only one of two lights when both are off, but swaps them when exactly one is already on:

- if:
    - condition: state
      entity_id: light.kitchen_accent
      state: "on"
    - condition: state
      entity_id: light.kitchen_center
      state: "off"
  then:
    - action: light.turn_off
      target:
        entity_id: light.kitchen_accent
    - action: light.turn_on
      target:
        entity_id: light.kitchen_center
  else:
    - action: light.turn_on
      target:
        entity_id: light.kitchen_accent
    - action: light.turn_off
      target:
        entity_id: light.kitchen_center

Build this with + Add action → Building blocks → If-then in the STOP button editor; conditions and both branches use the same pickers as a plain action.


Entity Placeholders

Within any STOP, hold, or double-tap custom action field (not 4B button actions, which have no entity domain of their own to expand), these values can be used as a target.entity_id (including inside nested if-then/choose branches):

Placeholder Expands to
covers All configured cover entities
fans All configured fan entities
lights All configured light entities
media_players All configured media-player entities
switches All configured switch entities

Because these placeholders are not real entity IDs, Home Assistant's visual entity picker inside the action editor won't offer them. Use the action editor's Edit in YAML toggle for that action to type a placeholder directly, for example:

action: light.turn_on
target:
  entity_id: lights

A placeholder can also be mixed with explicit entities in the same list, and other target fields (like area_id) are preserved during expansion.


Validation and Error Handling

Pico Link validates each Pico's configuration as it is entered, before the step can be submitted:

  • Exactly one domain's entities must be filled in (non-4B), or at least one 4B button must have actions, before continuing.
  • Entities are restricted to the correct domain by the entity picker itself.
  • Numeric fields are clamped to their allowed range by the field itself.
  • The same physical Pico cannot be configured more than once, and the type is read from the hardware, so it can never be entered incorrectly.

If a Pico's configuration becomes invalid after an update (for example, an assigned entity was deleted), Home Assistant marks that Pico's entry as Setup failed under Devices & Services, with the specific reason shown right on the entry (also logged). Other configured Picos are unaffected. Mutually-exclusive fields (a button's hold and double-tap actions) are additionally caught inline on the options step itself, before they ever reach this point.


Diagnostics and Repairs

Repairs

Two problems, once detected, show up under Settings → Repairs instead of only in the log:

  • Hardware type mismatch — a configured Pico's events keep arriving with a different or unrecognized hardware type. This means the physical device changed, or the wrong type was configured; that Pico's events are ignored until it's resolved. Clears itself automatically the next time a matching event arrives.
  • Pico removed from the bridge — a configured Pico's device no longer exists in Home Assistant's device registry (it was removed or re-paired on the Lutron bridge, or someone deleted the device entry directly). Checked once at startup and again on every device registry change, so it's caught even if it happened while Home Assistant was offline. Clears itself if the device reappears; otherwise, edit or remove the affected Pico Link entry.
  • A configured entity no longer exists — a light, cover, fan, media player, switch, or accent light assigned to a Pico was deleted or renamed. Button presses that target it otherwise fail silently. Checked once Home Assistant has finished starting (so a slower-loading integration isn't flagged before it's registered its entities) and again on every entity registry change; clears itself once every listed entity exists again.

None of these repairs are "fixable" through a guided flow — each points you at what to check, since the fix (correcting the configured type, re-adding the Pico, or pointing the entry at the right entities) happens outside Pico Link.

Diagnostics

Every Pico Link entry supports Home Assistant's standard diagnostics download (its "⋮" menu under Settings → Devices & Services → Download diagnostics). The dump includes the entry's configuration and, for each Pico in it, its device ID, configured type, and controlled domain — useful for your own troubleshooting or for filing a sharper bug report. Nothing in it needs redacting: no credentials or personal data, just entity IDs, device IDs, and configuration values.


The pico_link_button event

Pico Link fires a pico_link_button event on the bus for every press and release that passes device, hardware-type, and button validation — regardless of what (if anything) it goes on to control. This lets an automation, a Node-RED flow, or anything else listening on the event bus react to a Pico's normalized semantics directly, without re-deriving them from the raw lutron_caseta_button_event (device ID → configured type → normalized button name).

Event data:

Field Description
device_id The Pico's Home Assistant device ID
type Configured Pico type (P2B, 2B, 3BRL, or 4B)
button Normalized button name (on, off, stop, raise, lower, button_1, button_2, button_3)
action press or release
domain The domain this Pico controls (light, cover, fan, media_player, switch), or null for a 4B Pico

This fires alongside — not instead of — Pico Link's own configured behavior; it's an additional hook, not a replacement for middle_button, on_hold, or any other configured action. Example automation trigger:

trigger:
  - platform: event
    event_type: pico_link_button
    event_data:
      device_id: <your Pico's device ID>
      button: "on"
      action: press

Device triggers

For the same thing without writing YAML by hand, use the automation editor's own trigger picker: Add Trigger → Device → (your Pico) → and choose one of the listed "<button> pressed" / "<button> released" options. This builds the same event trigger shown above — it's a UI shortcut over pico_link_button, not a separate mechanism, and only offers the buttons that Pico's type actually has (e.g. a P2B only offers ON/OFF; a 4B offers its four scene buttons).

Each configured Pico shows up twice in the device picker: once as the Lutron Caséta device (with Lutron's own triggers) and once as a Pico Link device with the same name (with these triggers). Home Assistant gives every integration its own device, so Pico Link creates a mirror of each Pico it controls, placed in the same area. Only the Pico Link one lists the pico_link_button triggers.


Troubleshooting

Pico Link loads but no buttons work

Confirm:

  1. The Lutron Caséta integration is loaded.
  2. The Pico emits lutron_caseta_button_event.
  3. The Pico device selected during setup matches the physical remote sending the event.
  4. The configured type matches the type reported in the event.
  5. The assigned entities still exist and use the correct domain.

A Pico's entry shows "Setup failed"

The specific validation error is shown right on the entry (expand it under Settings → Devices & Services), not just in the log — for example, a reassigned/deleted entity, or (for 3BRL/4B) a button with both a hold and a double-tap action configured. Use Configure on the entry to fix it.

Configured and reported Pico types do not match

Since the type is read from the hardware at setup time, this should only happen if a Pico was physically swapped at the same Lutron device registration without being re-paired. Remove the integration entry and add the Pico again to re-detect its type.

Rapid cover or light taps

Pico Link retains recent requested brightness, effect, color temperature, cover-position, fan-speed and volume targets for about two seconds, so repeated taps do not depend on immediate entity-state updates. The targets are shared by all the Picos in an entry, since they control the same entities.

If a command fails (the device is unreachable or times out), its target is dropped, so the next tap steps from the entity's reported state rather than from a step that never happened.

When behavior appears out of sync after an external change, wait briefly before the next tap so Pico Link resynchronizes from Home Assistant.

Fan holds do not ramp

This is intentional. Fan controls are tap-only.


Updating

Versioning

Releases use calendar versioning: YYYY.MM.DD.XX (e.g. 2026.09.06.01). XX starts at 01 each day and increments for additional releases on that same date.

After installing an updated version:

  1. Restart Home Assistant.
  2. Check Settings → Devices & Services for any Pico Link entry showing Setup failed or a repair notification.
  3. Test ON, OFF, RAISE, LOWER, STOP, and custom actions for each configured Pico type.

Editing a Pico's options through Configure reloads only that Pico and does not require a Home Assistant restart.


Support Development

Support development

About

A Home Assistant integration that enables Lutron Pico remotes to control lights, switches, and other entities.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages