69 lines
2.9 KiB
Python
69 lines
2.9 KiB
Python
"""Forward HA events to conditional events and service calls.
|
|
|
|
Each forwarders entry contains events_to_listen (EventHandler format),
|
|
optional events_to_send and services_to_call mappings. Both action types
|
|
accept event_condition, evaluated on every incoming event. Payloads are
|
|
static YAML data, as in the original forwarder.
|
|
"""
|
|
import appdaemon.plugins.hass.hassapi as hass
|
|
import ad_toolbox.smartcondition as SmartCondition
|
|
from ad_toolbox.eventhandler import EventHandler
|
|
from ad_toolbox.expressionparser import ParsingException
|
|
from ad_toolbox.logger_interface import LoggerInterface
|
|
|
|
|
|
class ConditionalAction:
|
|
def __init__(self, owner, config):
|
|
self.owner = owner
|
|
self.config = config
|
|
self.condition = None
|
|
if 'event_condition' in config:
|
|
self.condition = SmartCondition.Evaluator(owner, config['event_condition'])
|
|
|
|
def is_allowed(self):
|
|
return (self.condition is None or
|
|
self.condition.evaluate(False) == SmartCondition.Result.Succeeded)
|
|
|
|
|
|
class EventSender(ConditionalAction):
|
|
def send_event(self, source_event, event_data):
|
|
if self.is_allowed():
|
|
data = self.config.get('event_data', {})
|
|
self.owner.log_info(f"{source_event} => {self.config['event_name']} data = {data}")
|
|
self.owner.fire_event(self.config['event_name'], **data)
|
|
|
|
|
|
class ServiceCaller(ConditionalAction):
|
|
def call_service(self, source_event, event_data):
|
|
if self.is_allowed():
|
|
data = self.config.get('data', {})
|
|
self.owner.log_info(f"{source_event} => Calling {self.config['service']} data = {data}")
|
|
self.owner.call_service(self.config['service'], **data)
|
|
|
|
|
|
class EventsForwarder(hass.Hass, LoggerInterface):
|
|
def initialize(self):
|
|
self.initialize_logger_interface(self.get_ad_api())
|
|
self.mute_logger(self.args.get('mute', False))
|
|
self.forwarders = {}
|
|
self.services_caller = {}
|
|
self.event_handlers = []
|
|
for key, block in self.args.get('forwarders', {}).items():
|
|
try:
|
|
senders = [EventSender(self, config)
|
|
for config in block.get('events_to_send', {}).values()]
|
|
callers = [ServiceCaller(self, config)
|
|
for config in block.get('services_to_call', {}).values()]
|
|
self.forwarders[key] = senders
|
|
self.services_caller[key] = callers
|
|
self.event_handlers.append(EventHandler(
|
|
self, block['events_to_listen'], self.on_event, key))
|
|
except ParsingException as error:
|
|
self.log_error(f"Invalid forwarder {key}: {error}")
|
|
|
|
def on_event(self, event_name, event_data, forwarder_key):
|
|
for sender in self.forwarders.get(forwarder_key, []):
|
|
sender.send_event(event_name, event_data)
|
|
for caller in self.services_caller.get(forwarder_key, []):
|
|
caller.call_service(event_name, event_data)
|