Performer and Protocols
A Performer is the entity that binds together an Appliance, its protocol commands and its protocol triggers.
Protocol commands create protocol messages for one or more physical devices realizing the Appliance. Protocol triggers map protocol messages from one or more physical devices to events for the realized Appliance.
Performers translate received protocol messages to events for an Appliance through protocol triggers. When an Appliance has changed its State, Performers translate the transaction from an old Appliance State to a new Appliance State in a list of protocol messages through protocol commands.
Tip
Many commands and triggers can be grouped together inside the same Performer.
When a trigger inside a Performer is triggered then the commands belonging to the same Performer are executed:
- !Performer
name: "sonos relative volume command up"
for appliance: "a sound player"
triggers:
- !knx_plugin.trigger.dpt_control_dimming.step.up.Trigger {addresses: [0x0C09]}
commands:
- !soco_plugin.command.volume.relative.Command {addresses: ["Bath"], fields: {"delta": 10}}
- !Performer
name: "sonos relative volume command down"
for appliance: "a sound player"
triggers:
- !knx_plugin.trigger.dpt_control_dimming.step.down.Trigger {addresses: [0x0C09]}
commands:
- !soco_plugin.command.volume.relative.Command {addresses: ["Bath"], fields: {"delta": -10}}
The above yaml syntax groups together an appliance named a sound player with some KNX protocol triggers and some Sonos protocol commands (using the soco library).
When a KNX push button, with address 0x0C09, is pressed to send a DPT_Control_Dimming step up then the Performer named sonos relative volume command up will create a message to increase volume by 10 for a Sonos device named Bath.
When a KNX push button, with address 0x0C09, is pressed to send a DPT_Control_Dimming step down message then the Performer named sonos relative volume command down will create a message to decrease volume by 10 for a Sonos device named Bath.
Tip
Yaml syntax uses Performers to define Scheduler triggers it is easier to use and re-use a Performer when it has few triggers or commands.
Use multiple Performers instead of grouping together many commands and triggers when the Performers are thought to be used by Scheduler Triggers.
Note
The home package has only an abstract definition for every entity in the home.protocol package.
Implementations are found in external packages, one for every protocol.
Right now, available protocol plugins are:
knx_plugin
lifx_plugin
sonos_plugin
home_assistant_plugin
Performer (Class Diagram)
Protocol Triggers
Every time the system receives a message through one of its Protocol Gateways the message is checked against compatible Protocol Triggers.
When a Protocol Trigger is triggered all the Performers which own it will potentially notify related events to their Appliances.
Protocol Triggers can be triggered for many different reasons:
a defined kind of protocol message is arrived
a number of defined kinds of protocol messages are arrived
a mean value for some protocol messages values has been reached
a protocol message value is greater than, smaller than or in between some other given value
a mix of the above conditions is met
and so on
A Protocol Trigger owns a list of Events which are used when it has been triggered.
Returned Events can be obtained applying functions to data collected in the trigger: values in the payload, a mean of multiple messages values, a count of messages and so on.
Performers and Protocol Triggers
Update an Appliance state when a protocol message is received
Lux value changed example
A really simple trigger, which is triggered by any knx received message on address 0xAAAA containing a lux value, can be used to always update the measured value inside an Appliance representing a lux sensor:
- !Performer
name: "sun lux sensor trigger"
for appliance: "sun lux sensor"
commands: []
triggers:
- !knx_plugin.trigger.dpt_value_lux.Always {addresses: [0xAAAA]}
The following is a simple, always updating, KNX Trigger:
>>> knx_plugin.trigger.dpt_value_lux.Always.make([0xAAAA, ])
Sun brightness is high example
A slightly more complex trigger that can be used to notify a sun is bright event to some Appliance sensible to a home.event.sun.Bright event:
>>> knx_plugin.trigger.dpt_value_lux.Bright.make([0xAAAA, ])
Light is forced on example
When a button is pressed by the user to turn on the light then the user is saying to the system:
hei, I want the light to stay turned on, do not touch it.
The following is a simple KNX Trigger with a forcing on event notified every time a on message on address 0xBBBB through the knx protocol is received:
>>> knx_plugin.trigger.dpt_switch.On.make([0xBBBB, ], [home.appliance.light.event.forced.Event.On,])
Protocol Commands
The Protocol Commands are those entities which translate the Abstract Appliance State in a protocol message which is able, for example, to turn on or off a device.
A Performer asks to its Protocol Commands to create, if needed, the protocol messages suited to be sent through the Protocol Gateways every time the Appliance state is changed by the system.
Performer and Protocol Commands
Adjust lifx bulb color when knx switch is turned on example
Protocol Commands inside a Performer are always executed when the Appliance State is changed by a Protocol Trigger in the same Performer:
- !Performer
name: "adjust lifx bulb color when turned on"
for appliance: "a lifx bulb"
triggers:
- !knx_plugin.trigger.dpt_switch.On.make([0xBBBB, ], [home.appliance.light.event.forced.Event.On,])
commands:
- !lifx_plugin.command.SetColor {addresses: [["172.31.10.245", 56700]]}
Adjust lifx bulb color a few seconds later the knx switch is turned on example
A Performer Command will send a message to bus few seconds later a Protocol Trigger is triggered if a Scheduler Trigger owning the Performer Trigger has been scheduled with the Performer Command as a target:
- !Performer
name: "force on a lifx bulb"
for appliance: "a lifx bulb"
triggers:
- !knx_plugin.trigger.dpt_switch.On.make([0xBBBB, ], [home.appliance.light.event.forced.Event.On,])
commands: []
- !Performer
name: "set color for a lifx bulb"
for appliance: "a lifx bulb"
triggers: []
commands:
- !lifx_plugin.command.SetColor {addresses: [["172.31.10.245", 56700]]}
- !protocol.delay.Trigger
name: "adjust lifx bulb color"
notify more events: []
when triggered performers: "force on a lifx bulb"
and timeout expires: 3
- !schedule
trigger: "adjust lifx bulb color"
for performers: "set color for a lifx bulb"
Appliances and Performers reusability
When an Appliance model has been defined together with the Performers that can change its state then both the Appliance and the Performers can be easily reused simply changing Protocol Triggers and Protocol Commands and, if needed, customizing Appliance and Performers names.
Performer Class
- class home.Performer(name: str, appliance: home.Appliance, commands: Iterable[home.protocol.Command], triggers: Iterable[home.protocol.Trigger])
The entity which links together an Appliance, its protocol commands and its protocol triggers.
Through a Performer the physical devices are linked with their abstract Appliance. A Performer keep synchronized physical devices states and Appliance states.
- has(description: home.protocol.Description) bool
The Performer has a trigger or command for the given protocol message description?
- Parameters
description – A protocol message description
- Returns
bool
- is_for(appliance: home.Appliance) bool
The Performer is for the given Appliance?
- Parameters
appliance – An Appliance to look for
- Returns
bool
- execute(old_state: home.appliance.State, new_state: home.appliance.State) Iterable[Any]
For every command in Performer make them create messages given old and new Appliance State.
- Parameters
old_state – the old Appliance State
new_state – the new Appliance State
- Returns
a list of protocol messages to be send through the Gateway
- notify(events: Iterable[home.Event]) Tuple[Iterable[Any], home.appliance.State, home.appliance.State]
Notify to the contained Appliance the given Events. Create the protocol messages with old and new Appliance state.
- Parameters
events – Events to be notified to the Appliance
- Returns
protocol messages to be sent through the Gateway, old Appliance State and new Appliance State
- is_notified(event: home.Event) bool
The given Event is already inside the Appliance State?
- Parameters
event – an Event to look for
- Returns
bool
- update_by(description: home.protocol.Description) Tuple[home.appliance.State, home.appliance.State]
Update the contained Appliance State through the given protocol message description.
- Parameters
description – a protocol message description
- Returns
(old Appliance State, new Appliance State)
protocol.Description Class
- class home.protocol.Description(description)
An abstract Description for a protocol message
- property type: str
- Returns
a protocol identifier
- property label: str
- Returns
the label attached to this protocol description
- classmethod make(*args, **kwargs) home.protocol.Description
Make a protocol message Description given the arguments.
- Parameters
args –
kwargs –
- Returns
a protocol message Description
- classmethod make_from_yaml(*args, **kwargs) home.protocol.Description
Make a protocol message Description given the yaml arguments.
- Parameters
args –
kwargs –
- Returns
a protocol message Description
- classmethod make_from(msg: Any) home.protocol.Description
Make a protocol message Description given the protocol message
- Parameters
msg – a protocol message
- Returns
a protocol message Description
protocol.Trigger Class
- class home.protocol.Trigger(description: Any, events: List[home.Event] = None)
An abstract Trigger for a protocol message.
- abstract is_triggered(another_description: home.protocol.Description) bool
This trigger is triggered by the given protocol message Description?
- Parameters
another_description – a protocol message description
- Returns
bool
- property events: List[home.Event]
Events to be notified when this Trigger is triggered.
- Returns
a list of Events to be notified
- make_new_state_from(another_description: home.protocol.Description, old_state: home.appliance.State) home.appliance.State
Given the protocol message Description, if this Trigger is triggered, notify Trigger’s Events to the given state and return new state.
- Parameters
another_description – a protocol message Description
old_state – an Appliance State to be updated
- Returns
an updated Appliance State
protocol.Command Class
- class home.protocol.Command(description)
An abstract Command for a protocol.
- abstract execute()
Build one or more messages for the protocol Gateway, using the internal protocol message representation
- Returns
a list of protocol messages
- abstract make_msgs_from(old_state: home.appliance.State, new_state: home.appliance.State) List[Any]
Update the internal protocol message representation and call execute to build one or more messages for the protocol Gateway
- Parameters
old_state – the old Appliance State
new_state – the new Appliance State
- Returns
a list of protocol messages
protocol.Gateway Class
- class home.protocol.Gateway
An Abstract Protocol Gateway.
The entity which can send and receive protocol messages to/from the protocol bus.
- abstract associate_commands(descriptions: home.protocol.Description) Any
Connect the Protocol Commands with the Gateway, if needed.
Only connected commands should go through the Gateway to the bus.
- Parameters
descriptions – a protocol message description
- Returns
an association object, if any
- abstract associate_triggers(descriptions: home.protocol.Description)
Connect the Protocol Triggers with the Gateway, if needed.
Only connected triggers should go through the Gateway from the bus.
- Parameters
descriptions – a protocol message description
- Returns
an association object, if any
- abstract async run(tasks: Iterable[Callable])
Create an asynchronous task capable of receiving messages from the bus.
Every received message becomes a Protocol Trigger.
Every created Protocol Trigger goes through given tasks to be processed.
- Parameters
tasks – a function capable of process a Protocol Trigger
- abstract async writer(msgs: Iterable[Any], *args)
A function capable of sending protocol messages to the bus.
- Parameters
msgs – a protocol messages
args –
- static make_trigger(msg: Any) home.protocol.Trigger
Make a Protocol Trigger from a protocol message.
- Parameters
msg – a protocol message
- Returns
a Protocol Trigger