ControllerX

repository·main·Indexed 18 days ago

https://github.com/xaviml/controllerx

A Home Assistant integration for creating controller-based automations. It allows users to map physical button presses from controllers (e.g., IKEA E2002) to complex actions on devices like lights, media players, and covers. The library provides a core framework (cx_core) with base classes for custom controllers, support for multiple click detection, action execution modes (single, restart, queued, parallel), and specialized controllers for lights and covers.

Tokens
43.1K
Snippets
103
Records
176
Agent score
60%

What's inside controllerx

  1. Available action types in ControllerX

    main

    Action types are reduced versions of Home Assistant Script Syntax. They define what happens when a specific <event> is fired from a controller or integration.

    Supported action types include:

    • Predefined actions: Shortcuts for common tasks (e.g., toggle).
    • Call services: Executing any Home Assistant service.
    • Scene activation: Activating a specific HA Scene.
    • Delay: Pausing execution for a specified number of seconds.

    Execution Behavior:

    • Sequential Execution: Actions are executed one after another. Note that some actions (like hold) are blocking and will not finish until a corresponding release event occurs. Using a list of hold actions is not recommended as they will execute sequentially.
    • Restart Mode: If a new event of the same type is fired while an action is still executing (e.g., during a delay), the previous execution is cancelled and a new one starts. This behaves like mode: restart in Home Assistant.
  2. Use HA templating in controllerx configurations

    main

    Controllerx supports dynamic property resolution using the Home Assistant (HA) templating system. This allows you to use the same Jinja2-style syntax used in Home Assistant to determine parameter values at runtime based on the current state of your devices or sensors.

    You can use templates for the following parameter types:

    • Device types: e.g., light, media_player, switch, cover.
    • Predefined actions.
    • Scene activation.
    • Call services (within the mapping section).

    To use a template, wrap the expression in double quotes and use the standard HA template syntax (e.g., "{{ states('sensor.name') }}").

    example_app:
      module: controllerx
      class: E1810MediaPlayerController
      controller: my_controller
      integration:
        name: z2m
        listen_to: mqtt
      media_player: "{{ states('sensor.current_media_player') }}"
  3. Use Entity Groups with Entity Controllers

    main

    Since ControllerX v4.14.0, Entity Controllers (such as LightController, MediaPlayerController, CoverController, etc.) can operate on grouped entities.

    To use this feature, you must provide an entity that contains an entity_id attribute holding a list of the entities within the group (e.g., a Home Assistant Group Integration or Light Group Integration entity).

    How it works:

    1. ControllerX reads attributes (like brightness or state) from the first entity in the group's list (the 'main' entity).
    2. ControllerX performs actions (like turn_on or set_brightness) on the grouped entity itself.

    Important Constraint: The first entity in the group's list must support all attributes required by the controller. For example, if you are using a LightController and the first entity in the group does not support the brightness attribute, the controller will fail to function even if other entities in the group do support it.

    # Example Home Assistant Light Group configuration
    light:
      - platform: group
        name: livingroom
        entities:
          - light.livingroom_1
          - light.livingroom_2
          - light.livingroom_3
    
    # Example ControllerX apps.yaml configuration
    example_app:
      module: controllerx
      class: E2002LightController
      controller: livingroom_controller
      integration:
        name: z2m
        listen_to: mqtt
      light: light.livingroom
  4. Simulate multiple clicks using the `$` token

    main

    For controllers that only support single-click events, you can virtually manage multiple clicks (double, triple, etc.) by using the $ token in your mapping or merge_mapping configuration.

    How it works

    • Append $ followed by the number of clicks to the event name (e.g., toggle$2 for a double click).
    • If a base event (e.g., toggle) and a multi-click version (e.g., toggle$1) are both defined, the version with the $ token takes precedence.
    • Important: All multi-clickable events are subject to a delay. When a multi-clickable event is detected, ControllerX waits for the duration specified in multiple_click_delay to see if subsequent clicks occur before triggering the action.

    Configuration Keys

    • multiple_click_delay: The delay in milliseconds to wait between clicks to detect a sequence. Defaults to 500.
    example_app:
      module: controllerx
      class: E1810Controller
      controller: my_controller
      integration:
        name: z2m
        listen_to: mqtt
      light: light.my_light
      multiple_click_delay: 500
      mapping:
        brightness_up_click: "on"
        toggle: click_color_down
        toggle$1: click_color_up
        toggle$2: "off"
  5. Implement Stateful Controllers using Input Select

    main

    Stateful Controllers allow a single physical controller to manage different devices or different modes of operation by switching between configurations based on a Home Assistant input_select (Dropdown) entity.

    This is achieved by using the constrain_input_select key to bind a specific ControllerX configuration to a specific state of an input_select. When the state of the input_select changes, ControllerX activates the configuration corresponding to that state.

    Implementation Patterns

    1. Explicit Mapping (High Flexibility): Define multiple ControllerX configurations. Use constrain_input_select: <entity_id>,<state_name> in each to specify which state activates that configuration. This is best when different states require different merge_mapping or different target devices.

    2. Dynamic Templating (High Simplicity): If the states of your input_select match the entity IDs of your target devices, you can use a single ControllerX configuration. Use a template for the light (or other device) key to dynamically resolve the entity based on the current state of the input_select.

    # Pattern 1: Explicit Mapping
    example_app_0:
      module: controllerx
      class: E1810Controller
      light: light.my_light_1
      constrain_input_select: input_select.controller_state,state_0
    
    example_app_1:
      module: controllerx
      class: E1810Controller
      light: light.my_light_2
      constrain_input_select: input_select.controller_state,state_1
  6. Understand Controller types and functionality

    main

    In controllerx, a device's functionality is determined by its assigned Controller type rather than just its entity type. The controller type defines the specific capabilities and parameters available to the device.

    Common controller types include:

    • Light controller
    • Zigbee2MQTT Light controller
    • Media player controller

    Each controller type requires specific parameters to function correctly. While generic parameters apply to all controllers, you must provide the specific parameters required by the chosen controller type.

  7. Override supported_features for controllers

    main

    The supported_features field allows you to manually override the supported_features attribute from a Home Assistant entity (light, media player, cover, etc.).

    By default, ControllerX reads this value from Home Assistant. However, if the entity's attribute does not accurately reflect its capabilities, you can provide a bit field value to ensure ControllerX selects the correct actions. This is defined as a bit field where the binary representation determines which features are supported.

  8. Configure E1810 with Hue Bridge light groups

    main

    When using Hue Bridge light groups, you have two strategies depending on whether you use Home Assistant (HA) groups or Hue Bridge groups:

    1. HA Groups (group.xxx): Use smooth_power_on: true. ControllerX will sync values from the first group entity to the remaining entities. This is recommended for dimming and color/color temp changes.
    2. Hue Bridge Groups (light.xxx): Use this for synchronized on/off functions. Zigbee group commands used by the Hue bridge ensure lights act in unison.

    You can also use the transition attribute for Hue bridge support.

    # Strategy 1: HA Group for dimming/color
    hallway_light_group_no_toggle:
      module: controllerx
      class: E1810Controller
      controller: "x90fd9ffffe17d796"
      integration:
        name: z2m
        listen_to: mqtt
      smooth_power_on: true
      light: group.hallway
      actions:
        - arrow_left_hold
        - arrow_left_release
        - arrow_right_hold
        - arrow_right_release
        - arrow_right_click
        - arrow_left_click
        - brightness_up_click
        - brightness_down_click
        - brightness_up_release
        - brightness_down_release
        - brightness_up_hold
        - brightness_down_hold
    
    # Strategy 2: Hue Group for sync on/off
    hallway_light_group_toggle:
      module: controllerx
      class: E1810Controller
      controller: "x90fd9ffffe17d796"
      integration:
        name: z2m
        listen_to: mqtt
      light: light.hallway
      actions:
        - toggle
        - toggle_hold
  9. How Hold/Click modes relate to predefined actions

    main

    ControllerX supports two ways to define click and hold behaviors. The new structured configuration is a more flexible version of the legacy predefined actions.

    Predefined Actions (Legacy/Simple): Uses a single string format: {hold,click}_{attribute}_{direction} (e.g., hold_brightness_up). These always use stop as the default mode.

    Structured Configuration (Advanced): Uses a mapping object within merge_mapping. This allows for custom mode (like loop or bounce) and custom steps counts.

    Equivalency Example:

    The following two configurations are functionally identical:

    Structured:

    merge_mapping:
      2001:
        action: hold
        attribute: brightness
        direction: up

    Predefined:

    merge_mapping:
      2001: hold_brightness_up
  10. How ControllerX works

    main

    ControllerX provides advanced behaviors for smart home controllers (like IKEA or Xiaomi remotes) that are often lost when using generic integrations like Zigbee2MQTT or ZHA.

    Key capabilities include:

    • Device Control: Turn on/off lights, switches, media players, and covers.
    • Parameter Adjustment: Manual or smooth (on button hold) increase/decrease of brightness, color temperature, volume, etc.
    • Color Management: Color loop changing for lights supporting xy color.
    • Media Control: Play/pause music.

    Technical Model: ControllerX uses an async loop to make periodic Home Assistant service calls. For example, when a button is held, ControllerX continuously calls HA services (like light.turn_on with increased brightness) until a release action is detected.

  11. How to configure the `controller` attribute for MQTT

    main

    The controller attribute must contain the specific MQTT topic that ControllerX should listen to.

    • For non-JSON payloads: The topic should point directly to the value (e.g., zigbee2mqtt/<friendly name>/action).
    • For JSON payloads: The topic should point to the parent object containing the data, and you must use the key parameter in the integration configuration to specify which field within that JSON object to monitor.
  12. Override controller behavior with mapping and merge_mapping

    main

    You can customize what happens when a button is pressed using mapping or merge_mapping.

    • mapping: Completely overrides the default controller behavior. Only the actions you define will work.
    • merge_mapping: Keeps the default behaviors but allows you to add new ones or modify existing ones.

    Supported values in a mapping include predefined actions, Home Assistant service calls, or scripts triggered by multiple clicks (e.g., toggle$2 for a double click).

    Example: Merging custom behaviors

    merge_mapping:
      # Use a predefined action
      brightness_up_click: toggle_full_brightness
      
      # Use a Home Assistant service call
      toggle:
        service: scene.turn_on
        data:
          entity_id: scene.my_scene
          
      # Handle a double click (triggered within multiple_click_delay)
      toggle$2:
        - service: script.my_script
        - service: script.my_script_with_arguments
          data:
            my_attr: test
    merge_mapping:
      brightness_up_click: toggle_full_brightness
      toggle:
        service: scene.turn_on
        data:
          entity_id: scene.my_scene
      toggle$2:
        - service: script.my_script
        - service: script.my_script_with_arguments
          data:
            my_attr: test