docs: def wait(self, condition_or_value, timeout=None):
          """Wait for the sensor to satisfy a condition.
  
          Parameters
          ----------
          condition_or_value : obj or callable, or seq of objs or callables
              If obj, sensor.value is compared with obj. If callable,
              condition_or_value(reading) is called, and must return True if its
              condition is satisfied. Since the reading is passed in, the value,
              status, timestamp or received_timestamp attributes can all be used
              in the check.
              TODO: Sequences of conditions (use SensorTransitionWaiter thingum?)
          timeout : float or None
              The timeout in seconds (None means wait forever)
  
          Returns
          -------
          This command returns a tornado Future that resolves with True when the
          sensor value satisfies the condition. It will never resolve with False;
          if a timeout is given a TimeoutError happens instead.
  
          Raises
          ------
          :class:`KATCPSensorError`
              If the sensor does not have a strategy set
          :class:`tornado.gen.TimeoutError`
              If the sensor condition still fails after a stated timeout period
  
          """
          if (isinstance(condition_or_value, collections.Sequence) and not
                  isinstance(condition_or_value, basestring)):
              raise NotImplementedError(
                  'Currently only single conditions are supported')
          condition_test = (condition_or_value if callable(condition_or_value)
                            else lambda s: s.value == condition_or_value)
  
          ioloop = tornado.ioloop.IOLoop.current()
          f = Future()
          if self.sampling_strategy == ('none', ):
              raise KATCPSensorError(
                  'Cannot wait on a sensor that does not have a strategy set')
  
          def handle_update(sensor, reading):
              # This handler is called whenever a sensor update is received
              try:
                  assert sensor is self
                  if condition_test(reading):
                      self.unregister_listener(handle_update)
                      # Try and be idempotent if called multiple times after the
                      # condition is matched. This should not happen unless the
                      # sensor object is being updated in a thread outside of the
                      # ioloop.
                      if not f.done():
                          ioloop.add_callback(f.set_result, True)
              except Exception:
                  f.set_exc_info(sys.exc_info())
                  self.unregister_listener(handle_update)
  
          self.register_listener(handle_update, reading=True)
          # Handle case where sensor is already at the desired value
          ioloop.add_callback(handle_update, self, self._reading)
  
          if timeout:
              to = ioloop.time() + timeout
              timeout_f = with_timeout(to, f)
              # Make sure we stop listening if the wait times out to prevent a
              # buildup of listeners
              timeout_f.add_done_callback(
                  lambda f: self.unregister_listener(handle_update))
              return timeout_f
          else:
              return f