Repository: home-assistant/core
Pull request: Screenlogic config: Filter unexpected host names
<!--
  You are amazing! Thanks for contributing to our project!
  Please, DO NOT DELETE ANY TEXT from this template! (unless instructed).
-->
## Proposed change
<!--
  Describe the big picture of your changes here to communicate to the
  maintainers why we should accept this pull request. If it fixes a bug
  or resolves a feature request, be sure to link to that issue in the
  additional information section.
-->
Filter out any discovered devices that don't have the expected hostname.

## Type of change
<!--
  What type of change does your PR introduce to Home Assistant?
  NOTE: Please, check only 1! box!
  If your PR requires multiple boxes to be checked, you'll most likely need to
  split it into multiple PRs. This makes things easier and faster to code review.
-->

- [ ] Dependency upgrade
- [x] Bugfix (non-breaking change which fixes an issue)
- [ ] New integration (thank you!)
- [ ] New feature (which adds functionality to an existing integration)
- [ ] Breaking change (fix/feature causing existing functionality to break)
- [ ] Code quality improvements to existing code or addition of tests

## Additional information
<!--
  Details are important, and help maintainers processing your PR.
  Please be sure to fill out additional details, if applicable.
-->

- This PR fixes or closes issue: fixes #70026
- This PR is related to issue: 
- Link to documentation pull request: 

## Checklist
<!--
  Put an `x` in the boxes that apply. You can also fill these out after
  creating the PR. If you're unsure about any of them, don't hesitate to ask.
  We're here to help! This is simply a reminder of what we are going to look
  for before merging your code.
-->

- [x] The code change is tested and works locally.
- [x] Local tests pass. **Your PR cannot be merged unless tests pass**
- [ ] There is no commented out code in this PR.
- [ ] I have followed the [development checklist][dev-checklist]
- [ ] The code has been formatted using Black (`black --fast homeassistant tests`)
- [x] Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:

- [ ] Documentation added/updated for [www.home-assistant.io][docs-repository]

If the code communicates with devices, web services, or third-party tools:

- [ ] The [manifest file][manifest-docs] has all fields filled out correctly.  
      Updated and included derived files by running: `python3 -m script.hassfest`.
- [ ] New or updated dependencies have been added to `requirements_all.txt`.  
      Updated by running `python3 -m script.gen_requirements_all`.
- [ ] For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description.
- [ ] Untested files have been added to `.coveragerc`.

The integration reached or maintains the following [Integration Quality Scale][quality-scale]:
<!--
  The Integration Quality Scale scores an integration on the code quality
  and user experience. Each level of the quality scale consists of a list
  of requirements. We highly recommend getting your integration scored!
-->

- [ ] No score or internal
- [ ] 🥈 Silver
- [ ] 🥇 Gold
- [ ] 🏆 Platinum

<!--
  This project is very active and we have a high turnover of pull requests.

  Unfortunately, the number of incoming pull requests is higher than what our
  reviewers can review and merge so there is a long backlog of pull requests
  waiting for review. You can help here!
  
  By reviewing another pull request, you will help raise the code quality of
  that pull request and the final review will be faster. This way the general
  pace of pull request reviews will go up and your wait time will go down.
  
  When picking a pull request to review, try to choose one that hasn't yet
  been reviewed.

  Thanks for helping out!
-->

To help with the load of incoming pull requests:

- [ ] I have reviewed two other [open pull requests][prs] in this repository.

[prs]: https://github.com/home-assistant/core/pulls?q=is%3Aopen+is%3Apr+-author%3A%40me+-draft%3Atrue+-label%3Awaiting-for-upstream+sort%3Acreated-desc+review%3Anone+-status%3Afailure

<!--
  Thank you for contributing <3

  Below, some useful links you could explore:
-->
[dev-checklist]: https://developers.home-assistant.io/docs/en/development_checklist.html
[manifest-docs]: https://developers.home-assistant.io/docs/en/creating_integration_manifest.html
[quality-scale]: https://developers.home-assistant.io/docs/en/next/integration_quality_scale_index.html
[docs-repository]: https://github.com/home-assistant/home-assistant.io


Problem statement:
ScreenLogic Integration Fails to Load
### The problem

Under Integrations, I am attempting to add Pentair ScreenLogic from the UI.  It starts to process but then errors out with “Config flow could not be loaded: undefined”.  When I check the logs, I see the following error.

  File "/usr/local/lib/python3.9/site-packages/aiohttp/web_protocol.py", line 435, in _handle_request
    resp = await request_handler(request)
  File "/usr/local/lib/python3.9/site-packages/aiohttp/web_app.py", line 504, in _handle
    resp = await handler(request)
  File "/usr/local/lib/python3.9/site-packages/aiohttp/web_middlewares.py", line 117, in impl
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/security_filter.py", line 60, in security_filter_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/forwarded.py", line 94, in forwarded_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/request_context.py", line 28, in request_context_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/ban.py", line 79, in ban_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/auth.py", line 219, in auth_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/view.py", line 137, in handle
    result = await result
  File "/usr/src/homeassistant/homeassistant/components/config/config_entries.py", line 174, in post
    return await super().post(request)
  File "/usr/src/homeassistant/homeassistant/components/http/data_validator.py", line 62, in wrapper
    result = await method(view, request, *args, **kwargs)
  File "/usr/src/homeassistant/homeassistant/helpers/data_entry_flow.py", line 71, in post
    result = await self._flow_mgr.async_init(
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 205, in async_init
    flow, result = await task
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 232, in _async_init
    result = await self._async_handle_step(flow, flow.init_step, data, init_done)
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 335, in _async_handle_step
    result: FlowResult = await getattr(flow, method)(user_input)
  File "/usr/src/homeassistant/homeassistant/components/screenlogic/config_flow.py", line 77, in async_step_user
    self.discovered_gateways = await async_discover_gateways_by_unique_id(self.hass)
  File "/usr/src/homeassistant/homeassistant/components/screenlogic/config_flow.py", line 38, in async_discover_gateways_by_unique_id
    mac = _extract_mac_from_name(host[SL_GATEWAY_NAME])
  File "/usr/src/homeassistant/homeassistant/components/screenlogic/config_flow.py", line 46, in _extract_mac_from_name
    return format_mac(f"{PENTAIR_OUI}-{name.split(':')[1].strip()}")
IndexError: list index out of range

### What version of Home Assistant Core has the issue?

Core-2022.4.2

### What was the last working version of Home Assistant Core?

_No response_

### What type of installation are you running?

Home Assistant OS

### Integration causing the issue

ScreenLogic

### Link to integration documentation on our website

_No response_

### Diagnostics information

  File "/usr/local/lib/python3.9/site-packages/aiohttp/web_protocol.py", line 435, in _handle_request
    resp = await request_handler(request)
  File "/usr/local/lib/python3.9/site-packages/aiohttp/web_app.py", line 504, in _handle
    resp = await handler(request)
  File "/usr/local/lib/python3.9/site-packages/aiohttp/web_middlewares.py", line 117, in impl
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/security_filter.py", line 60, in security_filter_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/forwarded.py", line 94, in forwarded_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/request_context.py", line 28, in request_context_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/ban.py", line 79, in ban_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/auth.py", line 219, in auth_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/view.py", line 137, in handle
    result = await result
  File "/usr/src/homeassistant/homeassistant/components/config/config_entries.py", line 174, in post
    return await super().post(request)
  File "/usr/src/homeassistant/homeassistant/components/http/data_validator.py", line 62, in wrapper
    result = await method(view, request, *args, **kwargs)
  File "/usr/src/homeassistant/homeassistant/helpers/data_entry_flow.py", line 71, in post
    result = await self._flow_mgr.async_init(
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 205, in async_init
    flow, result = await task
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 232, in _async_init
    result = await self._async_handle_step(flow, flow.init_step, data, init_done)
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 335, in _async_handle_step
    result: FlowResult = await getattr(flow, method)(user_input)
  File "/usr/src/homeassistant/homeassistant/components/screenlogic/config_flow.py", line 77, in async_step_user
    self.discovered_gateways = await async_discover_gateways_by_unique_id(self.hass)
  File "/usr/src/homeassistant/homeassistant/components/screenlogic/config_flow.py", line 38, in async_discover_gateways_by_unique_id
    mac = _extract_mac_from_name(host[SL_GATEWAY_NAME])
  File "/usr/src/homeassistant/homeassistant/components/screenlogic/config_flow.py", line 46, in _extract_mac_from_name
    return format_mac(f"{PENTAIR_OUI}-{name.split(':')[1].strip()}")
IndexError: list index out of range

### Example YAML snippet

_No response_

### Anything in the logs that might be useful for us?

```txt
File "/usr/local/lib/python3.9/site-packages/aiohttp/web_protocol.py", line 435, in _handle_request
    resp = await request_handler(request)
  File "/usr/local/lib/python3.9/site-packages/aiohttp/web_app.py", line 504, in _handle
    resp = await handler(request)
  File "/usr/local/lib/python3.9/site-packages/aiohttp/web_middlewares.py", line 117, in impl
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/security_filter.py", line 60, in security_filter_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/forwarded.py", line 94, in forwarded_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/request_context.py", line 28, in request_context_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/ban.py", line 79, in ban_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/auth.py", line 219, in auth_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/view.py", line 137, in handle
    result = await result
  File "/usr/src/homeassistant/homeassistant/components/config/config_entries.py", line 174, in post
    return await super().post(request)
  File "/usr/src/homeassistant/homeassistant/components/http/data_validator.py", line 62, in wrapper
    result = await method(view, request, *args, **kwargs)
  File "/usr/src/homeassistant/homeassistant/helpers/data_entry_flow.py", line 71, in post
    result = await self._flow_mgr.async_init(
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 205, in async_init
    flow, result = await task
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 232, in _async_init
    result = await self._async_handle_step(flow, flow.init_step, data, init_done)
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 335, in _async_handle_step
    result: FlowResult = await getattr(flow, method)(user_input)
  File "/usr/src/homeassistant/homeassistant/components/screenlogic/config_flow.py", line 77, in async_step_user
    self.discovered_gateways = await async_discover_gateways_by_unique_id(self.hass)
  File "/usr/src/homeassistant/homeassistant/components/screenlogic/config_flow.py", line 38, in async_discover_gateways_by_unique_id
    mac = _extract_mac_from_name(host[SL_GATEWAY_NAME])
  File "/usr/src/homeassistant/homeassistant/components/screenlogic/config_flow.py", line 46, in _extract_mac_from_name
    return format_mac(f"{PENTAIR_OUI}-{name.split(':')[1].strip()}")
IndexError: list index out of range
```


### Additional information

_No response_

Hints from issue discussion:
@bdraco - would you mind taking a look at this.  You seemed to fix a similar issue the other day.
[screenlogic documentation](https://www.home-assistant.io/integrations/screenlogic)
[screenlogic source](https://github.com/home-assistant/core/tree/dev/homeassistant/components/screenlogic)
<sub><sup>(message by IssueLinks)</sup></sub>
Hey there @dieselrabbit, @bdraco, mind taking a look at this issue as it has been labeled with an integration (`screenlogic`) you are listed as a [code owner](https://github.com/home-assistant/core/blob/dev/CODEOWNERS#L866) for? Thanks!
<sub><sup>(message by CodeOwnersMention)</sup></sub>
@sdonoghu75 Does your protocol adapter not follow the standard naming of `Pentair: XX-XX-XX`?
It does follow that format.  However its not a static lease on my router - does that matter?  It is not auto discovering it in homeassistant either.  
@sdonoghu75 Please turn on debug logging for `homeassistant.components.screenlogic`

Hopefully the debug log with `        _LOGGER.debug("Discovered hosts: %s", hosts)` will tell us whats happening
Ok, I turned on logger for the ScreenLogic component and re-ran the "Add Integration" step through the UI.  Interestingly, it is pulling back two entries.  The first is the IP address of the ScreenLogic module and it has the Pentair: XX-XX-XX as the name.  It has a gtype of 2 and a gsubtype of 12.  However, it also pulls back another IP address which has nothing to do with Pentair and therefore the host name doesnt include "Pentair: XX-XX-XX".  This has a gtype of 1 and a gsubtype of 2.  I am guessing that since there are multiple entries pulling back its choking on the one that does have Pentair in the name.  
Please paste the output in
2022-04-18 16:20:19 DEBUG (MainThread) [homeassistant.components.screenlogic.config_flow] Discovered hosts: [{'ip': '192.168.1.XXX', 'port': 2198, 'gtype': 1, 'gsubtype': 2, 'name': 'XXXXXXXXX'}, {'ip': '192.168.1.XXX', 'port': 80, 'gtype': 2, 'gsubtype': 12, 'name': 'Pentair: XX-XX-XX'}]


Note:  I removed the actual IP address and MAC address and replaced with XXX.
Interesting.  Is the device with port 2198 something else entirely that happens to respond to the same discovery request?

Commit message: Check for "Pentair:" and poll for mac

Patch to review:
diff --git a/homeassistant/components/screenlogic/config_flow.py b/homeassistant/components/screenlogic/config_flow.py
index 260317dca11900..e34597c3ae9334 100644
--- a/homeassistant/components/screenlogic/config_flow.py
+++ b/homeassistant/components/screenlogic/config_flow.py
@@ -35,17 +35,22 @@ async def async_discover_gateways_by_unique_id(hass):
         return discovered_gateways
 
     for host in hosts:
-        mac = _extract_mac_from_name(host[SL_GATEWAY_NAME])
-        discovered_gateways[mac] = host
+        if host[SL_GATEWAY_NAME].startswith("Pentair:"):
+            try:
+                mac = format_mac(
+                    await login.async_get_mac_address(
+                        host[SL_GATEWAY_IP], host[SL_GATEWAY_PORT]
+                    )
+                )
+                discovered_gateways[mac] = host
+            except ScreenLogicError as ex:
+                _LOGGER.debug(ex)
+                continue
 
     _LOGGER.debug("Discovered gateways: %s", discovered_gateways)
     return discovered_gateways
 
 
-def _extract_mac_from_name(name):
-    return format_mac(f"{PENTAIR_OUI}-{name.split(':')[1].strip()}")
-
-
 def short_mac(mac):
     """Short version of the mac as seen in the app."""
     return "-".join(mac.split(":")[3:]).upper()
diff --git a/tests/components/screenlogic/test_config_flow.py b/tests/components/screenlogic/test_config_flow.py
index 1bb441f145c521..8e6125a519c791 100644
--- a/tests/components/screenlogic/test_config_flow.py
+++ b/tests/components/screenlogic/test_config_flow.py
@@ -40,6 +40,9 @@ async def test_flow_discovery(hass):
                 SL_GATEWAY_NAME: "Pentair: 01-01-01",
             },
         ],
+    ), patch(
+        "homeassistant.components.screenlogic.config_flow.login.async_get_mac_address",
+        return_value="00-C0-33-01-01-01",
     ):
         result = await hass.config_entries.flow.async_init(
             DOMAIN, context={"source": config_entries.SOURCE_USER}
@@ -178,6 +181,9 @@ async def test_form_manual_entry(hass):
                 SL_GATEWAY_NAME: "Pentair: 01-01-01",
             },
         ],
+    ), patch(
+        "homeassistant.components.screenlogic.config_flow.login.async_get_mac_address",
+        return_value="00-C0-33-01-01-01",
     ):
         result = await hass.config_entries.flow.async_init(
             DOMAIN, context={"source": config_entries.SOURCE_USER}


Code review comments:
diff_hunk: @@ -35,17 +35,22 @@ async def async_discover_gateways_by_unique_id(hass):
         return discovered_gateways
 
     for host in hosts:
-        mac = _extract_mac_from_name(host[SL_GATEWAY_NAME])
-        discovered_gateways[mac] = host
+        if host[SL_GATEWAY_NAME].startswith("Pentair:"):
path: homeassistant/components/screenlogic/config_flow.py
text: @user1:
I think it would probably be enough to reject anything that doesn't start with `Pentair` as we want to try to be as passive as possible to devices we aren't going to setup 

@author:
Roger