<s> """<STR_LIT>""" <EOL> import logging <EOL> import threading <EOL> from itertools import islice <EOL> import homeassistant . util . dt as date_util <EOL> from homeassistant . const import EVENT_TIME_CHANGED , CONF_CONDITION <EOL> from homeassistant . helpers . event import track_point_in_utc_time <EOL> from homeassistant . helpers import service , condition <EOL> import homeassistant . helpers . config_validation as cv <EOL> _LOGGER = logging . getLogger ( __name__ ) <EOL> CONF_ALIAS = "<STR_LIT>" <EOL> CONF_SERVICE = "<STR_LIT>" <EOL> CONF_SERVICE_DATA = "<STR_LIT:data>" <EOL> CONF_SEQUENCE = "<STR_LIT>" <EOL> CONF_EVENT = "<STR_LIT>" <EOL> CONF_EVENT_DATA = "<STR_LIT>" <EOL> CONF_DELAY = "<STR_LIT>" <EOL> def call_from_config ( hass , config , variables = None ) : <EOL> """<STR_LIT>""" <EOL> Script ( hass , config ) . run ( variables ) <EOL> class Script ( ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , hass , sequence , name = None , change_listener = None ) : <EOL> """<STR_LIT>""" <EOL> self . hass = hass <EOL> self . sequence = cv . SCRIPT_SCHEMA ( sequence ) <EOL> self . name = name <EOL> self . _change_listener = change_listener <EOL> self . _cur = - <NUM_LIT:1> <EOL> self . last_action = None <EOL> self . can_cancel = any ( CONF_DELAY in action for action <EOL> in self . sequence ) <EOL> self . _lock = threading . Lock ( ) <EOL> self . _delay_listener = None <EOL> @ property <EOL> def is_running ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _cur != - <NUM_LIT:1> <EOL> def run ( self , variables = None ) : <EOL> """<STR_LIT>""" <EOL> with self . _lock : <EOL> if self . _cur == - <NUM_LIT:1> : <EOL> self . _log ( '<STR_LIT>' ) <EOL> self . _cur = <NUM_LIT:0> <EOL> self . _remove_listener ( ) <EOL> for cur , action in islice ( enumerate ( self . sequence ) , self . _cur , <EOL> None ) : <EOL> if CONF_DELAY in action : <EOL> def script_delay ( now ) : <EOL> """<STR_LIT>""" <EOL> self . _delay_listener = None <EOL> self . run ( variables ) <EOL> self . _delay_listener = track_point_in_utc_time ( <EOL> self . hass , script_delay , <EOL> date_util . utcnow ( ) + action [ CONF_DELAY ] ) <EOL> self . _cur = cur + <NUM_LIT:1> <EOL> if self . _change_listener : <EOL> self . _change_listener ( ) <EOL> return <EOL> elif CONF_CONDITION in action : <EOL> if not self . _check_condition ( action , variables ) : <EOL> break <EOL> elif CONF_EVENT in action : <EOL> self . _fire_event ( action ) <EOL> else : <EOL> self . _call_service ( action , variables ) <EOL> self . _cur = - <NUM_LIT:1> <EOL> self . last_action = None <EOL> if self . _change_listener : <EOL> self . _change_listener ( ) <EOL> def stop ( self ) : <EOL> """<STR_LIT>""" <EOL> with self . _lock : <EOL> if self . _cur == - <NUM_LIT:1> : <EOL> return <EOL> self . _cur = - <NUM_LIT:1> <EOL> self . _remove_listener ( ) <EOL> if self . _change_listener : <EOL> self . _change_listener ( ) <EOL> def _call_service ( self , action , variables ) : <EOL> """<STR_LIT>""" <EOL> self . last_action = action . get ( CONF_ALIAS , '<STR_LIT>' ) <EOL> self . _log ( "<STR_LIT>" % self . last_action ) <EOL> service . call_from_config ( self . hass , action , True , variables , <EOL> validate_config = False ) <EOL> def _fire_event ( self , action ) : <EOL> """<STR_LIT>""" <EOL> self . last_action = action . get ( CONF_ALIAS , action [ CONF_EVENT ] ) <EOL> self . _log ( "<STR_LIT>" % self . last_action ) <EOL> self . hass . bus . fire ( action [ CONF_EVENT ] , action . get ( CONF_EVENT_DATA ) ) <EOL> def _check_condition ( self , action , variables ) : <EOL> """<STR_LIT>""" <EOL> self . last_action = action . get ( CONF_ALIAS , action [ CONF_CONDITION ] ) <EOL> check = condition . from_config ( action ) ( self . hass , False ) <EOL> self . _log ( "<STR_LIT>" . format ( self . last_action , check ) ) <EOL> return check <EOL> def _remove_listener ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _delay_listener : <EOL> self . hass . bus . remove_listener ( EVENT_TIME_CHANGED , <EOL> self . _delay_listener ) <EOL> self . _delay_listener = None <EOL> def _log ( self , msg ) : <EOL> """<STR_LIT>""" <EOL> if self . name is not None : <EOL> msg = "<STR_LIT>" . format ( self . name , msg ) <EOL> _LOGGER . info ( msg ) </s>
