docs: def scan_devices(self, devnames, timeout=DEF_TIMEOUT, interval=DEF_SCAN_INTERVAL, window=DEF_SCAN_WINDOW):
          """Run a BLE scan for a defined interval and return results.
          
          Alternative to :meth:`begin_scan/:meth:`end_scan`. 
  
          Args:
              timeout (float): time in seconds to run the scanning process for
              interval (int): BLE scan interval, in units of 625us
              window (int): BLE scan window, in units of 625us
  
          Returns:
              a :class:`ScanResults` object containing the scan results.
          """
  
          # TODO validate params and state
          logger.debug('configuring scan parameters') 
          self.api.ble_cmd_gap_set_scan_parameters(interval, window, 1)
          self._set_state(self._STATE_CONFIGURE_SCAN)
          self.api.ble_cmd_gap_discover(1) # any discoverable devices
          self._wait_for_state(self._STATE_CONFIGURE_SCAN)
  
          logger.debug('starting scan for devices {}'.format(devnames))
          self.scan_targets = devnames
          self._set_state(self._STATE_SCANNING)
          self._wait_for_state(self._STATE_SCANNING, timeout)
  
          self._set_state(self._STATE_GAP_END)
          self.api.ble_cmd_gap_end_procedure()
          self._wait_for_state(self._STATE_GAP_END)
  
          logger.debug('scanning completed')
  
          return self.scan_responses