raulgbcr / lednetwf_ble

Home Assistant custom integration for LEDnetWF devices
MIT License
23 stars 1 forks source link

Adding devices from the config screen results in error `KeyError: 'title_placeholders'` #14

Closed 8none1 closed 6 months ago

8none1 commented 6 months ago

Background

I got a bug report from a user of the BJ_LED integration that I've seen with this one too so I spent some time investigating. The bad news is that the same bug is present here. The good news is that I know how to fix it (I think).

The bug happens when you try to add a device that you might have already added and then removed:

When you click this button: image

and choose the device: image

You get this error: image

The error in the logs is:

  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 501, in _async_handle_step
    result: FlowResult = await getattr(flow, method)(user_input)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/lednetwf_ble/config_flow.py", line 98, in async_step_user
    self.name = self.context["title_placeholders"]["name"]
                ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
KeyError: 'title_placeholders'

Why

This happens because the device name is not being set correctly. If you add the device from the main integration screen some additional information about the device is passed in to config_flow.py which includes the device name. When you add the device as above the only information that is passed in is the MAC address and a list of discovered devices.

I don't know if this is because we are supposed to pass in more information somehow, or if that's just how it is.

How to fix

I fixed this in another integration like this:

    async def async_step_user(
        self, user_input: dict[str, Any] | None = None
    ) -> FlowResult:
        """Handle the user step to pick discovered device."""
        LOGGER.debug(f"step_user context: {self.context}")
        if user_input is not None:
            self.mac = user_input[CONF_MAC]
            LOGGER.debug(f"MAC address: {self.mac}")
            if "title_placeholders" in self.context.keys() :
                self.name = self.context["title_placeholders"]["name"]
            if 'source' in self.context.keys() and self.context['source'] == 'user':
                LOGGER.debug(f"User context.  discovered devices: {self._discovered_devices}")
                for each in self._discovered_devices:
                  LOGGER.debug(f"Address: {each.address()}")
                  if each.address() == self.mac:
                    self.name = each.get_device_name()
            if self.name is None: self.name = "BJ_LEDx"
            await self.async_set_unique_id(self.mac, raise_on_progress=False)
            self._abort_if_unique_id_configured()
            return await self.async_step_validate()

So it itterates the list of devices looking for a MAC address match. Then uses that match to pull out the name and set it.

This seems to work, and probably fixes other latent bugs which would have cropped up when people have multiple devices.

This should more or less copy & paste over.

Creating this bug to remind me to do something about it some time, unless anyone else picks it up first. ;)

8none1 commented 6 months ago

Meh, it was a 3 minute job, so I did it :) I should have just made a branch to start with.

https://github.com/raulgbcr/lednetwf_ble/pull/15

raulgbcr commented 6 months ago

Thanks again for this, feel free to bump the version on the manifest.json and merge!

8none1 commented 6 months ago

Oh! I forgot the manifest last time, thanks for the pointer :+1:

New release published.