Skip to content

Instantly share code, notes, and snippets.

@ismell
Created March 21, 2025 02:41
Show Gist options
  • Select an option

  • Save ismell/d432a311ae1371cdae251e979c0594e0 to your computer and use it in GitHub Desktop.

Select an option

Save ismell/d432a311ae1371cdae251e979c0594e0 to your computer and use it in GitHub Desktop.

Revisions

  1. ismell created this gist Mar 21, 2025.
    71 changes: 71 additions & 0 deletions distinct_random.yaml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,71 @@
    blueprint:
    name: Distinct Random
    description: >
    Creates a sensor which holds a random value from the referenced
    input_select. When the sensor receives the DISTINCT_UPDATE event, a new
    random value will be chosen. The random value will be distinct, meaning that
    a duplicate will not be returned until all options are exhaused.
    For Example if an Input Select has items: a, b, c
    On creation the template might contain `a`, then after a refresh it might
    contain `b`, and then finally `c`. Once the list has been exhausted, the
    "seen" values will be reset and it will be possible to return a, b, c again.
    The DISTINCT_UPDATE event must contain `name: "<sensor name>"` for the event
    to match.
    domain: template
    input:
    reference_entity:
    name: Input select
    description: The input_select to use as the source of options.
    selector:
    entity:
    domain: input_select
    sensor_name:
    name: Sensor Name
    description: The name of the new distinct random sensor to create.
    variables:
    reference_entity: !input reference_entity
    sensor_name: !input sensor_name
    trigger:
    # Recalculate the state if an option was removed.
    - trigger: state
    entity_id: "{{ reference_entity }}"
    attribute: options
    # Ideally we would use homeassistant.update_entity
    # but it's not available for trigger templates.
    # So we define a new event that needs to be fired.
    - trigger: event
    event_type: DISTINCT_UPDATE
    event_data:
    name: "{{ sensor_name }}"
    # Causes the template to render when first created.
    - trigger: event
    event_type: event_template_reloaded
    sensor:
    - name: "{{ sensor_name }}"
    state: >
    {% set seen = (state_attr(this.entity_id, 'seen') | default([], true)) %}
    {% if trigger.platform == "event" and trigger.event.type == "DISTINCT_UPDATE" %}
    {% set seen = seen + ([states(this.entity_id)] | reject('eq', 'unknown') | list ) %}
    {% endif %}
    {% set available = (state_attr(reference_entity, "options") | reject("in", seen) | list) %}
    {% if available %}
    {{ available | random }}
    {% else %}
    {{ state_attr(this.entity_id, 'seen') | random }}
    {% endif %}
    attributes:
    trigger: >
    {{ trigger | pprint}}
    seen: >
    {% set seen = (state_attr(this.entity_id, 'seen') | default([], true)) %}
    {% if trigger.platform == "event" and trigger.event.type == "DISTINCT_UPDATE" %}
    {% set seen = seen + ([states(this.entity_id)] | reject('eq', 'unknown') | list ) %}
    {% endif %}
    {% set available = (state_attr(reference_entity, "options") | reject("in", seen) | list) %}
    {% if available %}
    {{ seen }}
    {% else %}
    {{ [] }}
    {% endif %}