Custom Actor

Warning

This feature is experimental. When you’re using it, feedback is very welcome.

Note

This is a topic targeted at advanced users. It might be hard to understand for newcomers.

The custom actor can be used if maximum control and flexibility is required, as it allows you to write custom hooks (pieces of Python code) that link schedule results to entity states. In fact, you could even implement advanced types like Thermostat with this one.

While this actor is probably not for daily use, it gives you the power you need when implementing something really fancy.

Note

When you’re extensively using the custom actor type for something that could be interesting to other people as well, please consider filing your idea as an issue on GitHub to maybe get it included in Schedy natively. Thank you!

Understanding the Custom Actor

The purpose of every actor type is to provide a mapping between values generated by a schedule and states of entities. These two terms, value and state, are crucial for understanding how the custom actor works.

A value returned by a schedule may in fact be any Python object, be it a string, number, boolean or even a custom type. The work to be done by an implementation of the custom actor type is then to execute the Home Assistant services needed to reach the state you want a particular value to stand for. This work has to be acomplished in the so-called send hook, which is just normal Python code in which you can, for example, call services.

Note

You need to realize that values and states are two different things your custom actor implementation needs to link to each other..

However, the same work has to be done in the other direction as well. It needs to be possible to map a given entity state to the value that, when returned from a schedule, would cause that state to be achieved. This is handled by the state hook. It gets all state attributes of the watched entity and must return the value this state is caused by.

These two hooks, the send and the state hook, are executed similarly to the expressions used in schedules. Both simple expressions (single-line) and whole statements (multi-line) are possible. When using whole statements, the result has to be stored in the global result variable as usual.

Inside the hooks, the following variables are available for you to work with:

  • state or value: The input depending on the type of hook.

  • entity_id: The actor’s entity id.

  • config: The custom configuration dictionary as defined in the actor configuration.

  • app: The appdaemon.plugins.hass.hassapi.Hass object to be used for calling services etc.

  • actor: The CustomActor object. The only purpose I could imagine for using this object directly is for generating custom log messages, e.g. for debugging purposes. You could do:

    actor.log("I'm going to send the value {}."
              .format(repr(value)),
              level="DEBUG")
    

Configuration

This is a full actor configuration with comments on each available setting. The default values are provided as well. If you don’t need a particular setting, omit it or leave it commented out.

# This hook should perform all actions required for moving the actor
# to the state corresponding to the value given as "value". The result
# of the hook isn't respected. You'll probably use this for calling
# some services.
#send_hook: <required>

# This hook is executed when a state update is received from the
# watched entity. It has the dictionary with all received state attributes
# available in the variable "state". The result has to be the scheduling
# value corresponding to this state. If the result is None, the state
# change is ignored.
# When you don't define a state hook, the actor doesn't react to state
# changes at all. Inferring values from states is then impossible, which
# also disables change replication between actors in a room. Should you
# really decide to not map states back to values, make sure you set the
# "send_retries" setting to a low value, because the actor won't be able
# to notice when it has reached the desired state and always send until
# the configured number of retries is exceeded.
#state_hook: ...

# This hook is optional and may be used to preprocess a value generated
# by scheduling before it is stored and passed on to the send hook. The
# value is available under the name "value". The result of this hook
# has to be the updated value or None, in which case the value change
# is discarded and no send hook is executed.
#filter_value_hook: ...

# The config parameter is a dictionary which is available in all hooks
# under the name "config". It can be filled with anything you like and
# hence is useful for reusing a custom actor template, each time with
# different settings. You may want to store things like attribute names
# to be used by your custom hooks in the config dictionary.
# It's empty by default.
config: