docs: def update(self, message):
          """
          Update zone statuses based on the current message.
  
          :param message: message to use to update the zone tracking
          :type message: :py:class:`~alarmdecoder.messages.Message` or :py:class:`~alarmdecoder.messages.ExpanderMessage`
          """
          if isinstance(message, ExpanderMessage):
              zone = -1
  
              if message.type == ExpanderMessage.ZONE:
                  zone = self.expander_to_zone(message.address, message.channel, self.alarmdecoder_object.mode)
  
              if zone != -1:
                  status = Zone.CLEAR
                  if message.value == 1:
                      status = Zone.FAULT
                  elif message.value == 2:
                      status = Zone.CHECK
  
                  # NOTE: Expander zone faults are handled differently than
                  #       regular messages.  We don't include them in
                  #       self._zones_faulted because they are not reported
                  #       by the panel in it's rolling list of faults.
                  try:
                      self._update_zone(zone, status=status)
  
                  except IndexError:
                      self._add_zone(zone, status=status, expander=True)
  
          else:
              # Panel is ready, restore all zones.
              #
              # NOTE: This will need to be updated to support panels with
              #       multiple partitions.  In it's current state a ready on
              #       partition #1 will end up clearing all zones, even if they
              #       exist elsewhere and it shouldn't.
              #
              # NOTE: SYSTEM messages provide inconsistent ready statuses.  This
              #       may need to be extended later for other panels.
              if message.ready and not message.text.startswith("SYSTEM"):
                  for zone in self._zones_faulted:
                      self._update_zone(zone, Zone.CLEAR)
  
                  self._last_zone_fault = 0
  
              # Process fault
              elif self.alarmdecoder_object.mode != DSC and (message.check_zone or message.text.startswith("FAULT") or message.text.startswith("ALARM")):
                  zone = message.parse_numeric_code()
  
                  # NOTE: Odd case for ECP failures.  Apparently they report as
                  #       zone 191 (0xBF) regardless of whether or not the
                  #       3-digit mode is enabled... so we have to pull it out
                  #       of the alpha message.
                  if zone == 191:
                      zone_regex = re.compile('^CHECK (\d+).*$')
  
                      match = zone_regex.match(message.text)
                      if match is None:
                          return
  
                      zone = match.group(1)
  
                  # Add new zones and clear expired ones.
                  if zone in self._zones_faulted:
                      self._update_zone(zone)
                      self._clear_zones(zone)
  
                  else:
                      status = Zone.FAULT
                      if message.check_zone:
                          status = Zone.CHECK
  
                      self._add_zone(zone, status=status)
                      self._zones_faulted.append(zone)
                      self._zones_faulted.sort()
  
                  # Save our spot for the next message.
                  self._last_zone_fault = zone
  
              self._clear_expired_zones()