    def update_advertisement(self, scandata: BluetoothScannerDevice):
        """
        Update gets called every time we see a new packet or
        every time we do a polled update.

        This method needs to update all the history and tracking data for this
        device+scanner combination. This method only gets called when a given scanner
        claims to have data.
        """
        # In case the scanner has changed it's details since startup:
        # FIXME: This should probably be a separate function that the refresh_scanners
        # calls if necessary, rather than re-doing it every cycle.
        scanner = scandata.scanner
        self.name = scanner.name
        self.area_id = self.scanner_device.area_id
        self.area_name = self.scanner_device.area_name
        new_stamp: float | None = None

        if self.scanner_sends_stamps:
            # Found a remote scanner which has timestamp history...
            # There's no API for this, so we somewhat sneakily are accessing
            # what is intended to be a protected dict.
            # pylint: disable-next=protected-access
            stamps = scanner._discovered_device_timestamps  # type: ignore #noqa

            # In this dict all MAC address keys are upper-cased
            uppermac = self.parent_device_address.upper()
            if uppermac in stamps:
                if self.stamp is None or (stamps[uppermac] is not None and stamps[uppermac] > self.stamp):
                    new_stamp = stamps[uppermac]
                else:
                    # We have no updated advert in this run.
                    new_stamp = None
                    self.stale_update_count += 1
            else:
                # This shouldn't happen, as we shouldn't have got a record
                # of this scanner if it hadn't seen this device.
                _LOGGER.error(
                    "Scanner %s has no stamp for %s - very odd.",
                    scanner.source,
                    self.parent_device_address,
                )
                new_stamp = None
        else:
            # Not a bluetooth_proxy device / remote scanner, but probably a USB Bluetooth adaptor.
            # We don't get advertisement timestamps from bluez, so the stamps in our history
            # won't be terribly accurate, and the advert might actually be rather old.
            # All we can do is check if it has changed and assume it's fresh from that.

            self.scanner_sends_stamps = False
            # If the rssi has changed from last time, consider it "new"
            if self.rssi != scandata.advertisement.rssi:
                # 2024-03-16: We're going to treat it as fresh for now and see how that goes.
                # We can do that because we smooth distances now every update_interval, regardless
                # of when the last advertisement was received, so we shouldn't see bluez trumping
                # proxies with stale adverts. Hopefully.
                # new_stamp = MONOTONIC_TIME() - (ADVERT_FRESHTIME * 4)
                new_stamp = MONOTONIC_TIME()
            else:
                new_stamp = None

        if len(self.hist_stamp) == 0 or new_stamp is not None:
            # this is the first entry or a new one, bring in the new reading
            # and calculate the distance.

            self.rssi = scandata.advertisement.rssi
            self.hist_rssi.insert(0, self.rssi)

            self._update_raw_distance(reading_is_new=True)

            # Note: this is not actually the interval between adverts,
            # but rather a function of our UPDATE_INTERVAL plus the packet
            # interval. The bluetooth integration does not currently store
            # interval data, only stamps of the most recent packet.
            # So it more accurately reflects "How much time passed between
            # the two last packets we observed" - which should be a multiple
            # of the true inter-packet interval. For stamps from local bluetooth
            # adaptors (usb dongles) it reflects "Which update cycle last saw a
            # different rssi", which will be a multiple of our update interval.
            if new_stamp is not None and self.stamp is not None:
                _interval = new_stamp - self.stamp
            else:
                _interval = None
            self.hist_interval.insert(0, _interval)

            self.stamp = new_stamp
            self.hist_stamp.insert(0, self.stamp)

        # if self.tx_power is not None and scandata.advertisement.tx_power != self.tx_power:
        #     # Not really an erorr, we just don't account for this happening -
        #     # I want to know if it does.
        #     # AJG 2024-01-11: This does happen. Looks like maybe apple devices?
        #     # Changing from warning to debug to quiet users' logs.
        #     # Also happens with esphome set with long beacon interval tx, as it alternates
        #     # between sending some generic advert and the iBeacon advert. ie, it's bogus for that
        #     # case.
        #     _LOGGER.debug(
        #         "Device changed TX-POWER! That was unexpected: %s %sdB",
        #         self.parent_device_address,
        #         scandata.advertisement.tx_power,
        #     )
        self.tx_power = scandata.advertisement.tx_power

        # Track each advertisement element as or if they change.
        for key, data in self.adverts.items():
            new_data = getattr(scandata.advertisement, key, {})
            if len(new_data) > 0:
                if len(data) == 0 or data[0] != new_data:
                    data.insert(0, new_data)
                    # trim to keep size in check
                    del data[HIST_KEEP_COUNT:]

        self.new_stamp = new_stamp
Update gets called every time we see a new packet or
every time we do a polled update.

This method needs to update all the history and tracking data for this
device+scanner combination. This method only gets called when a given scanner
claims to have data.
custom_components/bermuda/bermuda_device_scanner.py