docs: def process(self, config, grains):
          '''
          Process the configured beacons
  
          The config must be a list and looks like this in yaml
  
          .. code_block:: yaml
              beacons:
                inotify:
                  - files:
                      - /etc/fstab: {}
                      - /var/cache/foo: {}
          '''
          ret = []
          b_config = copy.deepcopy(config)
          if 'enabled' in b_config and not b_config['enabled']:
              return
          for mod in config:
              if mod == 'enabled':
                  continue
  
              # Convert beacons that are lists to a dict to make processing easier
              current_beacon_config = None
              if isinstance(config[mod], list):
                  current_beacon_config = {}
                  list(map(current_beacon_config.update, config[mod]))
              elif isinstance(config[mod], dict):
                  current_beacon_config = config[mod]
  
              if 'enabled' in current_beacon_config:
                  if not current_beacon_config['enabled']:
                      log.trace('Beacon %s disabled', mod)
                      continue
                  else:
                      # remove 'enabled' item before processing the beacon
                      if isinstance(config[mod], dict):
                          del config[mod]['enabled']
                      else:
                          self._remove_list_item(config[mod], 'enabled')
  
              log.trace('Beacon processing: %s', mod)
              beacon_name = None
              if self._determine_beacon_config(current_beacon_config, 'beacon_module'):
                  beacon_name = current_beacon_config['beacon_module']
              else:
                  beacon_name = mod
              fun_str = '{0}.beacon'.format(beacon_name)
              validate_str = '{0}.validate'.format(beacon_name)
              if fun_str in self.beacons:
                  runonce = self._determine_beacon_config(current_beacon_config, 'run_once')
                  interval = self._determine_beacon_config(current_beacon_config, 'interval')
                  if interval:
                      b_config = self._trim_config(b_config, mod, 'interval')
                      if not self._process_interval(mod, interval):
                          log.trace('Skipping beacon %s. Interval not reached.', mod)
                          continue
                  if self._determine_beacon_config(current_beacon_config, 'disable_during_state_run'):
                      log.trace('Evaluting if beacon %s should be skipped due to a state run.', mod)
                      b_config = self._trim_config(b_config, mod, 'disable_during_state_run')
                      is_running = False
                      running_jobs = salt.utils.minion.running(self.opts)
                      for job in running_jobs:
                          if re.match('state.*', job['fun']):
                              is_running = True
                      if is_running:
                          close_str = '{0}.close'.format(beacon_name)
                          if close_str in self.beacons:
                              log.info('Closing beacon %s. State run in progress.', mod)
                              self.beacons[close_str](b_config[mod])
                          else:
                              log.info('Skipping beacon %s. State run in progress.', mod)
                          continue
                  # Update __grains__ on the beacon
                  self.beacons[fun_str].__globals__['__grains__'] = grains
  
                  # Run the validate function if it's available,
                  # otherwise there is a warning about it being missing
                  if validate_str in self.beacons:
                      valid, vcomment = self.beacons[validate_str](b_config[mod])
  
                      if not valid:
                          log.info('Beacon %s configuration invalid, '
                                   'not running.\n%s', mod, vcomment)
                          continue
  
                  # Fire the beacon!
                  raw = self.beacons[fun_str](b_config[mod])
                  for data in raw:
                      tag = 'salt/beacon/{0}/{1}/'.format(self.opts['id'], mod)
                      if 'tag' in data:
                          tag += data.pop('tag')
                      if 'id' not in data:
                          data['id'] = self.opts['id']
                      ret.append({'tag': tag,
                                  'data': data,
                                  'beacon_name': beacon_name})
                  if runonce:
                      self.disable_beacon(mod)
              else:
                  log.warning('Unable to process beacon %s', mod)
          return ret