docs: def add_roast_event(self, event):
          """Add an event to the roast log.
  
          This method should be used for registering events that may be worth
          tracking like first crack, second crack and the dropping of coffee.
          Similar to the standard reading output from the roaster, manually
          created events will include the current configuration reading, time and
          metadata passed in.
  
          :param event: Details describing what happened
          :type event: dict
          :returns: dict
          """
          event_time = self.get_roast_time()
  
          def get_valid_config():
              """Keep grabbing configs until we have a valid one.
  
              In rare cases, the configuration will be invalid when the user
              registers an event. This malformation can occur across several
              events, so we use this helper to find a valid config to associate
              to the event while preserving the original time. Due to fast
              interval checking, this is not liable to skew data that much and
              it's better than extreme false data.
              """
              config = self.get_roast_properties()['last']['config']
              if not config['valid']:
                  self._log.debug("Invalid config at event time, retrying...")
                  self.get_valid_config()
              return config
  
          event.update({'time': event_time,
                        'config': get_valid_config()})
          self._roast['events'].append(event)
          return self.get_roast_properties()