Skip to content

djmattyb206/TrimlightHomeAssistant

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

85 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Trimlight Home Assistant Integration

Trimlight icon

Home Assistant custom integration for Trimlight EDGE lights.

This integration uses the Trimlight EDGE cloud API and adds Home Assistant entities for power, brightness, built-in presets, saved custom presets, custom effect modes, speed control, and current preset tracking.

This is a custom integration, not an official Home Assistant integration.

Features

  • UI-based setup through Home Assistant config flow
  • light.trimlight for power and brightness
  • select.trimlight_built_in_preset for built-in animations
  • select.trimlight_custom_preset for saved custom presets
  • select.trimlight_custom_effect_mode for custom effect modes
  • number.trimlight_effect_speed for effect speed as a 0-100% slider
  • sensor.trimlight_current_preset with effect detail attributes
  • button.trimlight_refresh_presets to refresh preset caches
  • Local preset cache written to your Home Assistant config directory
  • Optional structured debug logging for troubleshooting

Requirements

You need:

  • A Trimlight EDGE controller
  • A Home Assistant installation that supports custom integrations
  • client_id
  • client_secret
  • device_id

The integration validates the credentials during setup by calling the Trimlight device-detail endpoint.

Credential Details

  • client_id The Trimlight EDGE account identifier used by the API. In your setup, this is the same value you have already been using in your Trimlight EDGE scripts.
  • client_secret The Trimlight EDGE API secret. This is not generated by Home Assistant. It must come from Trimlight or from the credentials already used by your existing Trimlight EDGE tooling.
  • device_id The unique device identifier for your Trimlight EDGE controller.

If you already have working Trimlight EDGE scripts, reuse the same client_id, client_secret, and device_id values here.

If you do not know your device_id, use your existing Trimlight scripts or other Trimlight EDGE tooling to fetch it before adding the integration.

Installation

HACS

If you use HACS:

  1. Open HACS.
  2. Add this repository as a custom integration repository if needed.
  3. Download Trimlight.
  4. Restart Home Assistant.

Manual Installation

  1. Open your Home Assistant config directory.
  2. Create custom_components/trimlight if it does not already exist.
  3. Copy the contents of custom_components/trimlight into your Home Assistant config at custom_components/trimlight.
  4. Restart Home Assistant.

For local development, direct copy into the Home Assistant config folder is the fastest workflow. You do not need HACS Redownload if you are copying files directly.

Configuration

After installation:

  1. Go to Settings -> Devices & Services.
  2. Select Add Integration.
  3. Search for Trimlight.
  4. Enter:
    • client_id
    • client_secret
    • device_id

The integration creates a config entry titled Trimlight <last 6 chars of device_id>.

Options

The integration exposes these options in the options flow:

  • Commit custom presets When enabled, updates to a saved custom preset are written back to that saved preset and then re-run by ID. This is most useful for custom speed and brightness changes that you want to persist.
  • Enable debug logging Writes structured JSONL debug events to trimlight_debug_ENTRY_ID.jsonl in your Home Assistant config directory.

Entities

The integration creates these entities:

  • light.trimlight Power and brightness control
  • select.trimlight_built_in_preset Built-in Trimlight animations
  • select.trimlight_custom_preset Saved custom presets from the controller
  • select.trimlight_custom_effect_mode Effect mode for the active custom preset
  • number.trimlight_effect_speed Effect speed displayed as 0-100%
  • sensor.trimlight_current_preset Current preset name plus effect detail attributes
  • button.trimlight_refresh_presets Refresh preset lists from the controller

Sensor Attributes

sensor.trimlight_current_preset exposes:

  • current_effect_id
  • current_effect_category
  • current_effect_mode
  • current_effect_speed
  • current_effect_brightness
  • current_effect_pixel_len
  • current_effect_reverse
  • current_effect_pixels

For saved custom presets, the integration prefers the saved preset definition over stale controller data when it can safely identify the active preset.

Select Entity Attributes

The select entities expose extra lookup attributes:

  • select.trimlight_custom_preset
    • current_id
    • presets
    • name_to_id
    • option_to_id
  • select.trimlight_built_in_preset
    • current_id
    • builtins
  • select.trimlight_custom_effect_mode
    • current_mode_id
    • modes

How The Integration Behaves

Data Updates

  • The integration is cloud_polling.
  • Standard polling interval is 600 seconds.
  • After control actions, the integration schedules a verification refresh after 5 seconds.
  • Power transitions use a 20 second grace window to reduce UI flicker while the controller settles.

Power And Brightness

  • light.turn_on sets the controller switch state to 1.
  • light.turn_off sets the controller switch state to 0.
  • Brightness updates are applied to the active effect.

Built-In Presets

  • Built-in presets are selected with select.trimlight_built_in_preset.
  • If the controller is off, the integration powers it on first.
  • The integration tries the built-in preview path first.
  • If the controller rejects the built-in preview shape, the integration falls back to the saved built-in effect by ID.
  • If the first selection does not stick, the integration may reapply the built-in automatically during verification.

Custom Presets

  • Saved custom presets are selected with select.trimlight_custom_preset.
  • The integration applies saved custom presets by ID.
  • If the controller is off, the integration powers it on first and then applies the preset.
  • If the first selection does not stick, the integration may re-run the preset automatically during verification.
  • Duplicate custom preset names are disambiguated in the selector, for example Name (id 12).

Custom Effect Modes

  • Custom effect modes are selected with select.trimlight_custom_effect_mode.
  • The mode list comes from the built-in CUSTOM_EFFECT_MODES map in the integration.
  • Mode changes apply to the active custom effect.

Speed Control

  • number.trimlight_effect_speed displays speed as 0-100%.
  • The integration converts that to the device's 0-255 speed range.
  • Built-in speed changes are applied to the active built-in effect.
  • Custom speed changes are applied to the active custom effect.
  • When Commit custom presets is enabled, custom speed changes are persisted back to the saved custom preset before the preset is re-run.

Startup And Off-To-On Behavior

  • After powering on from an off state, Custom preset and Custom effect mode may briefly show unknown or remain blank while the controller reports its active effect.
  • This short delay is expected.
  • The Current preset sensor, custom select, and custom effect mode should settle once the controller state catches up.

Preset Cache

Preset cache data is stored in Home Assistant storage and also written as a readable file in your Home Assistant config directory:

  • trimlight_presets_<entry_id>.json

If built-in presets are not returned by the controller, the integration falls back to the static built-in preset list bundled with the integration.

Automation Examples

Turn On And Select A Custom Preset

action:
  - service: light.turn_on
    target:
      entity_id: light.trimlight
  - service: select.select_option
    target:
      entity_id: select.trimlight_custom_preset
    data:
      option: "Seahawks"

Select A Built-In Preset

action:
  - service: select.select_option
    target:
      entity_id: select.trimlight_built_in_preset
    data:
      option: "Rainbow Spin"

Set Effect Speed

action:
  - service: number.set_value
    target:
      entity_id: number.trimlight_effect_speed
    data:
      value: 75

Troubleshooting

  • If custom presets do not appear, press button.trimlight_refresh_presets.
  • If HACS appears to show an older commit, use Update information before Redownload.
  • If the current preset is briefly Unknown or Off during a transition, wait for the verification refresh to complete.
  • If you are testing local code by copying directly into Home Assistant, restart Home Assistant after each integration change.
  • If you enable debug logging, review trimlight_debug_ENTRY_ID.jsonl in your Home Assistant config directory.
  • The integration expects valid Trimlight EDGE API credentials for every request. Invalid credentials will cause setup or refresh failures.

Optional Dashboard Ideas

The integration works with standard Home Assistant cards. Common pairings are:

  • light.trimlight with a Tile card
  • select.trimlight_built_in_preset with a Select card
  • select.trimlight_custom_preset with a Select card
  • select.trimlight_custom_effect_mode with a Select card
  • number.trimlight_effect_speed with a Number card
  • sensor.trimlight_current_preset with an Entity, Template, or Markdown card

If you use Mushroom cards, they work well with these entities, but they are optional and not required for the integration.

Example Lovelace YAML

These examples are optional. They are not required for the integration to work, but they can be useful for building a dashboard around the Trimlight entities.

Current Preset

type: entity
entity: sensor.trimlight_current_preset
name: Current Preset

Built-In Preset Selector

type: entities
entities:
  - entity: select.trimlight_built_in_preset
    name: Built-In Preset

Custom Preset Selector

type: entities
entities:
  - entity: select.trimlight_custom_preset
    name: Custom Preset

Custom Effect Mode Selector

type: conditional
conditions:
  - entity: select.trimlight_custom_preset
    state_not: unknown
  - entity: select.trimlight_custom_preset
    state_not: unavailable
card:
  type: entities
  entities:
    - entity: select.trimlight_custom_effect_mode
      name: Custom Effect Mode

Speed Control

type: conditional
conditions:
  - entity: light.trimlight
    state: "on"
card:
  type: entities
  entities:
    - entity: number.trimlight_effect_speed
      name: Speed Control

Pixel Preview

This markdown card renders a simple 6x5 preview grid using current_effect_pixels from sensor.trimlight_current_preset.

type: markdown
title: Preview
content: >
  {% set pixels =
  state_attr('sensor.trimlight_current_preset','current_effect_pixels') or []
  -%} {% if pixels -%} <table
  style="border-collapse:collapse;border-spacing:0;line-height:0;"> {%- for row
  in range(0,6) %} <tr style="line-height:0;"> {%- for col in range(0,5) %} {%-
  set i = row*5 + col %} {%- set p = (pixels | selectattr('index','equalto', i)
  | first) %} {%- if p is none %} {%- set color = 0 %} {%- set count = 0 %} {%-
  else %} {%- set color = p.color | int %} {%- set count = p.count | int %} {%-
  endif %} {%- set r = color // 65536 %} {%- set g = (color // 256) % 256 %} {%-
  set b = color % 256 %} {%- set hex = '%02X%02X%02X' % (r,g,b) %} <td
  style="width:28px;height:28px;padding:0;text-align:center;vertical-align:middle;">
    <font color="#{{ hex }}" style="line-height:28px;display:inline-block;"><b>{{ count }}</b></font>
  </td> {%- endfor %} </tr> {%- endfor %} </table> {%- else %} No pixel data {%-
  endif %}

Pixel Details

type: markdown
content: >
  {% set pixels =
  state_attr('sensor.trimlight_current_preset','current_effect_pixels') %} {% if
  pixels %} <div style="font-family: monospace; white-space: pre-wrap;
  word-break: break-word;"> {% for p in pixels %} {% set color = p.color | int
  %} {% set r = (color // 65536) %} {% set g = (color // 256) % 256 %} {% set b
  = color % 256 %} {% set hex = '%02X%02X%02X' % (r, g, b) %} <div>idx {{
  p.index }} | count {{ p.count }} | disable {{ p.disable }} | <span
  style="color: rgb({{ r }}, {{ g }}, {{ b }}); font-weight: 600;">
    <font color="#{{ hex }}">{{ color }} (#{{ hex }})</font>
  </span> </div> {% endfor %} </div> {% else %} No pixel data {% endif %}

Automated Test Runner

This repository includes a Windows-friendly test runner for state-based validation:

Recommended setup:

  1. Copy tools/trimlight_test_runner.example.json to tools/trimlight_test_runner.local.json.
  2. Create a token file such as tools/ha_trimlight.token.
  3. Paste your Home Assistant long-lived token into that file.
  4. Edit the local config file with your Home Assistant URL, share path, and preset names.
  5. Run the suite:
.\tools\run_trimlight_tests.ps1

Useful commands:

.\tools\run_trimlight_tests.ps1 -Scenario custom_off_to_on
python .\tools\trimlight_test_runner.py --list-scenarios

Runner output is written to the local debug/ folder. When available, the runner also copies the latest trimlight_debug_*.jsonl file from your Home Assistant share into debug/.

Development Notes

API Documentation

The repository includes Trimlight EDGE API reference material in docs.

License

MIT License. See LICENSE.

About

Home Assistant custom integration for Trimlight EDGE lights.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors