Listen_if listener

How do you like this as a concept? Where I think this differs from what we have today is that we can include the comparison for something other than equals into the listener. So for a temperature, listen for when the temperature is over 70 degrees F. Or in a device tracker, listen for when the person being tracked is “in” a list of locations.

self.listen_if(self.li_handle,“sensor.office_sensor_temperature_11_1”,“state”,">=",70)
self.listen_if(self.li_handle,“device_tracker.turboc1208_cc1208”,“state”,“in”,[“home”,“house”])

Standard callback format for a listener

  def li_handle(self,target,state,old,new,**kwargs):
    self.log("target={},state={},old={},new={}".format(target,state,old,new))

It still fires evertime an event happens, but the handler just checks for true or false as to whether to continue. Or it could easily be modified to only call the handler if the result is True so we never hear about False results.

  def listen_if(self,callback,target,attrib,opr,right,**kwargs):
    self.listen_state(self.handle_listen_if,target,attribute=attrib,opr=opr,right=right,callback=callback,**kwargs)

  def handle_listen_if(self,target,state,old,new,kwargs):
    try:
      l=int(new)
    except:
      try:
        l=float(new)
      except:
        if isinstance(new,list):
          l=new
        elif isinstance(new,dict):
          l=new
        else:
          l="'"+new+"'"
    left=str(l)
    try:
      r=int(kwargs["right"])
    except:
      try:
        r=float(kwargs["right"])
      except:
        if isinstance(kwargs["right"],list):
          r=kwargs["right"]
        elif isinstance(kwargs["right"],dict):
          r=kwargs["right"]
        else:
          r="'"+str(kwargs["right"])+"'"
    right=str(r)
    expression=left + kwargs["opr"] + right
    self.log("expression={}".format(expression))
    if eval(expression):
      kwargs["callback"](target,True,old,new)
    else:
      kwargs["callback"](target,False,old,new)    # remove this else block if you don't want to know about false events.

i dont have a problem with these extra lines:

if new < 70:
  return

at the top of a callback

but if Andrew thinks its helpfull then i think there is no need for a new function, just add this option to listen_state
and even if there is a new function, i would prefer the same callback as with listen_state.