original_docstring: Listen for state changes and calls action.
docstring: Listen for state changes and calls action.
docstring_tokens: Listen for state changes and calls action .
code: def state_automation_listener(event: Event):
          """Listen for state changes and calls action."""
          entity: str = event.data["entity_id"]
          from_s: Optional[State] = event.data.get("old_state")
          to_s: Optional[State] = event.data.get("new_state")
  
          if from_s is None:
              old_value = None
          elif attribute is None:
              old_value = from_s.state
          else:
              old_value = from_s.attributes.get(attribute)
  
          if to_s is None:
              new_value = None
          elif attribute is None:
              new_value = to_s.state
          else:
              new_value = to_s.attributes.get(attribute)
  
          if (
              not match_from_state(old_value)
              or not match_to_state(new_value)
              or (not match_all and old_value == new_value)
          ):
              return
  
          @callback
          def call_action():
              """Call action with right context."""
              hass.async_run_job(
                  action,
                  {
                      "trigger": {
                          "platform": platform_type,
                          "entity_id": entity,
                          "from_state": from_s,
                          "to_state": to_s,
                          "for": time_delta if not time_delta else period[entity],
                          "attribute": attribute,
                      }
                  },
                  event.context,
              )
  
          if not time_delta:
              call_action()
              return
  
          variables = {
              "trigger": {
                  "platform": "state",
                  "entity_id": entity,
                  "from_state": from_s,
                  "to_state": to_s,
              }
          }
  
          try:
              period[entity] = cv.positive_time_period(
                  template.render_complex(time_delta, variables)
              )
          except (exceptions.TemplateError, vol.Invalid) as ex:
              _LOGGER.error(
                  "Error rendering '%s' for template: %s", automation_info["name"], ex
              )
              return
  
          def _check_same_state(_, _2, new_st: State):
              if new_st is None:
                  return False
  
              if attribute is None:
                  cur_value = new_st.state
              else:
                  cur_value = new_st.attributes.get(attribute)
  
              return cur_value == new_value
  
          unsub_track_same[entity] = async_track_same_state(
              hass, period[entity], call_action, _check_same_state, entity_ids=entity,
          )
code_tokens: def state_automation_listener ( event : Event ) : entity : str = event . data [ "entity_id" ] from_s : Optional [ State ] = event . data . get ( "old_state" ) to_s : Optional [ State ] = event . data . get ( "new_state" ) if from_s is None : old_value = None elif attribute is None : old_value = from_s . state else : old_value = from_s . attributes . get ( attribute ) if to_s is None : new_value = None elif attribute is None : new_value = to_s . state else : new_value = to_s . attributes . get ( attribute ) if ( not match_from_state ( old_value ) or not match_to_state ( new_value ) or ( not match_all and old_value == new_value ) ) : return @ callback def call_action ( ) : """Call action with right context.""" hass . async_run_job ( action , { "trigger" : { "platform" : platform_type , "entity_id" : entity , "from_state" : from_s , "to_state" : to_s , "for" : time_delta if not time_delta else period [ entity ] , "attribute" : attribute , } } , event . context , ) if not time_delta : call_action ( ) return variables = { "trigger" : { "platform" : "state" , "entity_id" : entity , "from_state" : from_s , "to_state" : to_s , } } try : period [ entity ] = cv . positive_time_period ( template . render_complex ( time_delta , variables ) ) except ( exceptions . TemplateError , vol . Invalid ) as ex : _LOGGER . error ( "Error rendering '%s' for template: %s" , automation_info [ "name" ] , ex ) return def _check_same_state ( _ , _2 , new_st : State ) : if new_st is None : return False if attribute is None : cur_value = new_st . state else : cur_value = new_st . attributes . get ( attribute ) return cur_value == new_value unsub_track_same [ entity ] = async_track_same_state ( hass , period [ entity ] , call_action , _check_same_state , entity_ids = entity , )
short_docstring: Listen for state changes and calls action.
short_docstring_tokens: Listen for state changes and calls action .
comment: """Listen for state changes and calls action."""$SEP$"""Call action with right context."""