    async def async_step_calibration2_scanners(self, user_input=None):
        """
        Per-scanner calibration of rssi_offset.

        Prompts the user to select a configured device, then adjust the offset
        so that the estimated distance to each proxy is correct (typically by
        placing device at 1m from each proxy in turn).

        Distances are recalculated and displayed each time the user presses
        Submit, and they check "Save and Close" to save the config.
        """
        if user_input is not None:
            if user_input[CONF_SAVE_AND_CLOSE]:
                # Convert the name-based dict to use MAC addresses
                rssi_offset_by_address = {}
                for address in self.coordinator.scanner_list:
                    scanner_name = self.coordinator.devices[address].name
                    rssi_offset_by_address[address] = user_input[CONF_SCANNER_INFO][scanner_name]

                self.options.update({CONF_RSSI_OFFSETS: rssi_offset_by_address})
                # Per previous step, returning elsewhere in the flow after updating the entry doesn't
                # seem to work, so we'll just save and close the flow.
                # # Let's update the options - but we don't want to call create entry as that will close the flow.
                # self.hass.config_entries.async_update_entry(self.config_entry, options=self.options)
                # # Reset last device so that the next step doesn't think it exists.
                # self._last_device = None
                # self._last_scanner_info = None
                # return await self.async_step_init()

                # Save the config entry and close the flow.
                return await self._update_options()

            # It's a refresh, basically...
            self._last_scanner_info = user_input[CONF_SCANNER_INFO]
            self._last_device = user_input[CONF_DEVICES]

        saved_rssi_offsets = self.options.get(CONF_RSSI_OFFSETS, {})
        rssi_offset_dict = {}

        for scanner in self.coordinator.scanner_list:
            scanner_name = self.coordinator.devices[scanner].name
            rssi_offset_dict[scanner_name] = saved_rssi_offsets.get(scanner, 0)
        data_schema = {
            vol.Required(
                CONF_DEVICES,
                default=self._last_device if self._last_device is not None else vol.UNDEFINED,
            ): DeviceSelector(DeviceSelectorConfig(integration=DOMAIN)),
            vol.Required(
                CONF_SCANNER_INFO,
                default=rssi_offset_dict if not self._last_scanner_info else self._last_scanner_info,
            ): ObjectSelector(),
            vol.Optional(CONF_SAVE_AND_CLOSE, default=False): vol.Coerce(bool),
        }
        if user_input is None:
            return self.async_show_form(
                step_id="calibration2_scanners",
                data_schema=vol.Schema(data_schema),
                description_placeholders={"suffix": "After you click Submit, the new distances will be shown here."},
            )
        if isinstance(self._last_device, str):
            device = self._get_bermuda_device_from_registry(self._last_device)
        results_str = ""
        if device is not None and isinstance(self._last_scanner_info, dict):
            results = {}
            # Gather new estimates for distances using rssi hist and the new offset.
            for scanner in self.coordinator.scanner_list:
                scanner_name = self.coordinator.devices[scanner].name
                cur_offset = self._last_scanner_info.get(scanner_name, 0)
                if scanner in device.scanners:
                    results[scanner_name] = [
                        rssi_to_metres(
                            historical_rssi + cur_offset,
                            self.options.get(CONF_REF_POWER, DEFAULT_REF_POWER),
                            self.options.get(CONF_ATTENUATION, DEFAULT_ATTENUATION),
                        )
                        for historical_rssi in device.scanners[scanner].hist_rssi
                    ]
            # Format the results for display (HA has full markdown support!)
            results_str = "| Scanner | 0 | 1 | 2 | 3 | 4 |\n|---|---:|---:|---:|---:|---:|"
            for scanner_name, distances in results.items():
                results_str += f"\n|{scanner_name}|"
                for i in range(5):
                    # We round to 2 places (1cm) and pad to fit nn.nn
                    try:
                        results_str += f" `{distances[i]:>6.2f}`|"
                    except IndexError:
                        results_str += "`-`|"
            results_str += "\n\n"

        return self.async_show_form(
            step_id="calibration2_scanners",
            data_schema=vol.Schema(data_schema),
            description_placeholders={"suffix": results_str},
        )
Per-scanner calibration of rssi_offset.

Prompts the user to select a configured device, then adjust the offset
so that the estimated distance to each proxy is correct (typically by
placing device at 1m from each proxy in turn).

Distances are recalculated and displayed each time the user presses
Submit, and they check "Save and Close" to save the config.
custom_components/bermuda/config_flow.py