Skip to content

Feature Request: use state_trigger with a passed function #43

Closed
@dlashua

Description

@dlashua

I find I use this pattern quite a bit (untested):

registered_triggers = []

class FollowMe:
    def __init__(self, config):
        self.config = self.validate_config(config)

        @state_trigger(f'True or {self.config["input"]}')
        def state_trigger_update():
            self.update()

        registered_triggers.append(state_trigger_update)

    def validate_config(self, config):
        # do better
        return config

    def update(self):
        if state.get(config["input"]) == 'on':
            homeassistant.turn_on(entity_id=self.config['output'])
        else:
            homeassistant.turn_off(entity_id=self.config['output'])

It would be cleaner if I could do this:

class FollowMe:
    def __init__(self, config):
        pyscript.state_trigger(f'True or {self.config["input"]}')(self.update)

The pyscript.state_trigger method could be named something else if that made more sense. It could also take the function as a parameter (named or positional) if that's better. And this same functionality would be useful on all the decorators.

I can implement something similar in code myself like this (untested):

registered_triggers = []

def make_state_trigger(trigger, cb):
    @state_trigger(trigger)
    def inner_state_trigger():
        cb()
    
    registered_triggers.append(inner_state_trigger)

class FollowMe:
    def __init__(self, config):
        self.config = self.validate_config(config)

        make_state_trigger(
          f'True or {self.config["input"]}',
          self.update
        )

... It's just more readable, useful, and documented if it's built-in.

It would also be amazing if these triggers were removable. Something like this:

registered_triggers = {}

def make_state_trigger(trigger, cb):
    # make some unique ID in a better way
    unique_id = time.time()

    @state_trigger(trigger)
    def inner_state_trigger():
        cb()
    
    registered_triggers[unique_id] = inner_state_trigger

    def cancel_trigger():
        del registered_triggers[unique_id]

    return cancel_trigger


# in some class
cancel = make_state_trigger('domain.entity == "on"', self.update)

# later
cancel()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions