Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unifi integration devices become unavailable periodically #114196

Closed
Gazoonky opened this issue Mar 25, 2024 · 32 comments · Fixed by #114278
Closed

Unifi integration devices become unavailable periodically #114196

Gazoonky opened this issue Mar 25, 2024 · 32 comments · Fixed by #114278
Assignees

Comments

@Gazoonky
Copy link

Gazoonky commented Mar 25, 2024

The problem

Unifi integration usually rock solid but in last few days, possibly longer and I haven't noticed, all devices become unavailable and remain so until Unifi integration is reloaded

What version of Home Assistant Core has the issue?

core-2024.3.3

What was the last working version of Home Assistant Core?

No response

What type of installation are you running?

Home Assistant Supervised

Integration causing the issue

Unifi

Link to integration documentation on our website

No response

Diagnostics information

config_entry-unifi-8cb5385598408770151668677b786035.json

Example YAML snippet

No response

Anything in the logs that might be useful for us?

Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/unifi/hub/websocket.py", line 104, in _reconnect
await self.api.login()
File "/usr/local/lib/python3.12/site-packages/aiounifi/controller.py", line 74, in login
await self.connectivity.check_unifi_os()
File "/usr/local/lib/python3.12/site-packages/aiounifi/interfaces/connectivity.py", line 51, in check_unifi_os
response, _ = await self._request("get", self.config.url, allow_redirects=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/aiounifi/interfaces/connectivity.py", line 122, in _request
async with self.config.session.request(
File "/usr/local/lib/python3.12/site-packages/aiohttp/client.py", line 1194, in aenter
self._resp = await self._coro
^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/aiohttp/client.py", line 425, in _request
raise RuntimeError("Session is closed")
RuntimeError: Session is closed

Logger: aiounifi.interfaces.connectivity
Source: components/unifi/hub/websocket.py:80
First occurred: 21:36:08 (4 occurrences)
Last logged: 21:45:20

Server handshake error connecting to UniFi websocket: '200, message='Invalid response status', url=URL('wss://192.168.2.23:8443/proxy/network/wss/s/default/events')'

Logger: homeassistant.components.unifi
Source: components/unifi/hub/websocket.py:82
integration: UniFi Network (documentation, issues)
First occurred: 21:36:08 (4 occurrences)
Last logged: 21:45:20

Websocket setup failed

Additional information

Unifi Network application 3.0.4

@Kane610
Copy link
Member

Kane610 commented Mar 25, 2024

If it started to show up in the last few days it's something in your system either unifi or home assistant. Try restarting everything.

@Gazoonky
Copy link
Author

It has probably been going on longer than a few days, just not noticed I think.
System has been restarted several times.

@xconverge
Copy link

@Kane610 I started looking into this yesterday because I have been noticing something similar the past few days, maybe since I switched to unifi network application 8.1.113

If I have everything (HA and unifi) up and running, and then restart just the unifi network application, I get an unexpected response (in HA unifi integration) after authentication in aiounifi and the websocket crashes and doesnt seem to recover

If I then "restart" the unifi integration, it all comes up perfectly

This is reproducible for me everytime

2024-03-24 16:10:19.949 DEBUG (MainThread) [aiounifi.interfaces.connectivity] Talking to UniFi OS device: True
2024-03-24 16:10:19.949 DEBUG (MainThread) [aiounifi.interfaces.connectivity] sending (to https://xxx:8443/api/auth/login) post, {'username': 'xxx', 'password': 'xxx', 'remember': True}, {}
2024-03-24 16:10:19.958 DEBUG (MainThread) [aiounifi.interfaces.connectivity] received (from https://xxx:8443/api/auth/login) 200 text/html <ClientResponse(https://xxx:8443/api/auth/login) [200 None]>
<CIMultiDictProxy('Cache-Control': 'private', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/html', 'Content-Length': '3838', 'Date': 'Sun, 24 Mar 2024 23:10:19 GMT')>
2024-03-24 16:10:19.958 DEBUG (MainThread) [aiounifi.interfaces.connectivity] data (from https://xxx:8443/api/auth/login) b'<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>UniFi Network - Server status</title><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><base href="/manage/"><link href="angular/gca760d32f/fonts/aura/fonts.css" rel="stylesheet"><link href="angular/gca760d32f/fonts/ubnt-icon/style.css" rel="stylesheet"><link href="angular/gca760d32f/css/app.css" rel="stylesheet"><link rel="apple-touch-icon-precomposed" href="angular/gca760d32f/images/favicons/favicon-192.png?v=2"><meta name="msapplication-TileColor" content="#0193d7"><meta name="msapplication-TileImage" content="angular/gca760d32f/images/favicons/favicon-192.png?v=2"><link rel="apple-touch-icon-precomposed" sizes="192x192" href="angular/gca760d32f/images/favicons/favicon-192.png?v=2"><link rel="apple-touch-icon-precomposed" href="angular/gca760d32f/images/favicons/favicon-64.png?v=2" sizes="64x64"><link rel="icon" href="angular/gca760d32f/images/favicons/favicon-32.png?v=2" sizes="32x32"><link rel="icon" href="angular/gca760d32f/images/favicons/favicon-16.png?v=2" sizes="16x16"></head><body><script type="text/javascript">function checkStatus () {\n var xhr = new XMLHttpRequest();\n xhr.addEventListener(\'load\', function (event) {\n try {\n var response = JSON.parse(event.currentTarget.response);\n if (response.meta && response.meta.up) {\n window.location.reload();\n } else if (response.meta && response.meta.app_context_status) {\n document.getElementById("appContextStatus").innerHTML = response.meta.app_context_status\n\n var messageElement = document.getElementById("appContextMessage");\n if (response.meta.app_context_message) {\n messageElement.innerHTML = response.meta.app_context_message;\n messageElement.style.display = \'\';\n } else {\n messageElement.style.innerHTML = \'\';\n messageElement.style.display = \'none\';\n }\n } else if (response.meta && response.meta.app_context_error) {\n showError(response.meta.app_context_error);\n } else {\n document.getElementById("appContextStatus").innerHTML = \'Network application is starting up...\';\n var serverElement = document.getElementById("appContextMessage");\n serverElement.innerHTML = \'Please wait a moment\';\n serverElement.display = \'\';\n }\n }\n catch (e) {\n console.log(e);\n }\n }, false);\n xhr.addEventListener(\'error\', function (jqXHR, status, error) {\n showError(\'Connection error. Please check your Network application process state.\', error);\n }, false);\n\n var url = location.protocol + \'//\' + location.host + \'/status\';\n xhr.open(\'GET\', url);\n xhr.send();\n}\n\nfunction showError(msg, error) {\n document.getElementById("appContextStatus").innerHTML = \'<p>\' + msg + \'</p>\';;\n document.getElementById("appInfoBox").className += \' appInfoBox--danger\';\n document.getElementById("appInfoBoxIcon").className = document.getElementById("appInfoBoxIcon").className.replace(/ubnt-icon--info/ , \'ubnt-icon--alert\');\n var messageElement = document.getElementById("appContextMessage");\n messageElement.style.display = \'none\';\n messageElement.style.innerHTML = \'\';\n console.log(error);\n clearInterval(checkInterval);\n}\n\nvar checkInterval = setInterval(function(){\n checkStatus();\n}, 500);\n</script><div class="appContainer appContainer--responsive appContainer--centered verticalRhythmTop"><div class="appRow--comfy"><div class="col--xs12"><div class="appInfoBox appInfoBox--responsive" id="appInfoBox"><div class="appInfoBox__icon icon ubnt-icon--info" id="appInfoBoxIcon"></div><div class="appInfoBox__content"><div class="appInfoBox__header"><p id="appContextStatus">Network application is starting up...</p><p><span id="appContextMessage"></span></p></div></div></div></div></div></div></body></html>'
2024-03-24 16:10:19.958 DEBUG (MainThread) [aiounifi.interfaces.connectivity] Logged in to UniFi https://xxx:8443/api/auth/login
2024-03-24 16:10:19.980 ERROR (MainThread) [aiounifi.interfaces.connectivity] Server handshake error connecting to UniFi websocket: '200, message='Invalid response status', url=URL('wss://xxx:8443/proxy/network/wss/s/default/events')'
2024-03-24 16:10:19.980 ERROR (MainThread) [homeassistant.components.unifi] Websocket setup failed
2024-03-24 16:13:35.510 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/unifi/hub/websocket.py", line 104, in _reconnect
await self.api.login()
File "/usr/local/lib/python3.12/site-packages/aiounifi/controller.py", line 74, in login
await self.connectivity.check_unifi_os()
File "/usr/local/lib/python3.12/site-packages/aiounifi/interfaces/connectivity.py", line 51, in check_unifi_os
response, _ = await self._request("get", self.config.url, allow_redirects=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/aiounifi/interfaces/connectivity.py", line 122, in _request
async with self.config.session.request(
File "/usr/local/lib/python3.12/site-packages/aiohttp/client.py", line 1194, in __aenter__
self._resp = await self._coro
^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/aiohttp/client.py", line 425, in _request
raise RuntimeError("Session is closed")
RuntimeError: Session is closed

I can do some more testing and try and get you a clean debug log, but I did want to echo that this seems to be an actual issue to me

@Gazoonky what version of unifi are you running?

@Gazoonky
Copy link
Author

Gazoonky commented Mar 25, 2024

Exactly the same version as yours @xconverge . I can also reproduce the issue by restarting UniFi application, just as you have. I've added some log entries in my original post.

@cmgestevao
Copy link

I also had lags in several devices/entities updates.
Had to restore to core-2024.3.1

@home-assistant
Copy link

@Kane610
Copy link
Member

Kane610 commented Mar 26, 2024

Exactly the same version as yours @xconverge . I can also reproduce the issue by restarting UniFi application, just as you have. I've added some log entries in my original post.

How do you only restart the network app?

@xconverge
Copy link

Exactly the same version as yours @xconverge . I can also reproduce the issue by restarting UniFi application, just as you have. I've added some log entries in my original post.

How do you only restart the network app?

I run it self hosted with this container https://github.com/linuxserver/docker-unifi-network-application

So I just restart the container running the network application in docker

If you are on a UDM I would try something like this https://community.ui.com/questions/Restarting-Network-Controller-Via-SSH/584f72c6-c37e-4e8c-abfc-7f3b826eaf33

@Gazoonky
Copy link
Author

Exactly the same version as yours @xconverge . I can also reproduce the issue by restarting UniFi application, just as you have. I've added some log entries in my original post.

How do you only restart the network app?

In HA, Settings, Add-ons, UniFi then restart.

@Kane610
Copy link
Member

Kane610 commented Mar 26, 2024

Running UDMP, I can't reproduce it by just restarting the controller. I do get something similar but not exactly the same when restarting the controller.

@Gazoonky
Copy link
Author

Gazoonky commented Mar 26, 2024

Running UDMP, I can't reproduce it by just restarting the controller. I do get something similar but not exactly the same when restarting the controller.

So are you suggesting it's the UniFi Network application add-on that is causing the problem?

@Kane610
Copy link
Member

Kane610 commented Mar 26, 2024

Running UDMP, I can't reproduce it by just restarting the controller. I do get something similar but not exactly the same when restarting the controller.

So are you suggesting it's the UniFi Network application add-on that is causing the problem?

No, only that its not trivial to recreate

@Kane610
Copy link
Member

Kane610 commented Mar 26, 2024

Seeing this error in your provided logs is something new raise RuntimeError("Session is closed")

@xconverge
Copy link

Running UDMP, I can't reproduce it by just restarting the controller. I do get something similar but not exactly the same when restarting the controller.

Does it recover and reconnect for you or stay disconnected until you reload the integration?

@Kane610
Copy link
Member

Kane610 commented Mar 26, 2024

It reconnects properly after

@xconverge
Copy link

It reconnects properly after

Here I generated a fresh log set for you since I can reproduce the problem every single time I restart my unifi network application:


reloaded integration with unifi running:
2024-03-26 12:08:21.466 DEBUG (MainThread) [aiounifi.interfaces.connectivity] sending (to https://xxx:8443) get, None, {'allow_redirects': False}
2024-03-26 12:08:21.493 DEBUG (MainThread) [aiounifi.interfaces.connectivity] received (from https://xxx:8443) 302 application/octet-stream <ClientResponse(https://xxx:8443) [302 None]>
<CIMultiDictProxy('Location': '/manage', 'Content-Length': '0', 'Date': 'Tue, 26 Mar 2024 19:08:21 GMT')>
2024-03-26 12:08:21.493 DEBUG (MainThread) [aiounifi.interfaces.connectivity] data (from https://xxx:8443) b''
2024-03-26 12:08:21.493 DEBUG (MainThread) [aiounifi.interfaces.connectivity] Talking to UniFi OS device: False
2024-03-26 12:08:21.493 DEBUG (MainThread) [aiounifi.interfaces.connectivity] sending (to https://xxx:8443/api/login) post, {'username': 'xxx', 'password': 'xxx', 'remember': True}, {}
2024-03-26 12:08:21.773 DEBUG (MainThread) [aiounifi.interfaces.connectivity] received (from https://xxx:8443/api/login) 200 application/json <ClientResponse(https://xxx:8443/api/login) [200 None]>
<CIMultiDictProxy('Vary': 'Origin', 'Set-Cookie': 'unifises=PupogBxcGgsl4pYXxEyk2aQm3bQ04upx; Path=/; Secure; HttpOnly', 'Set-Cookie': 'csrf_token=YkLC4MGnBdgPImOgFmRDNA6yFPXbXNvE; Path=/; Secure', 'X-Frame-Options': 'DENY', 'Content-Type': 'application/json;charset=UTF-8', 'Content-Length': '30', 'Date': 'Tue, 26 Mar 2024 19:08:21 GMT')>
2024-03-26 12:08:21.773 DEBUG (MainThread) [aiounifi.interfaces.connectivity] data (from https://xxx:8443/api/login) b'{"meta":{"rc":"ok"},"data":[]}'
2024-03-26 12:08:21.773 DEBUG (MainThread) [aiounifi.interfaces.connectivity] Logged in to UniFi https://xxx:8443/api/login


restarted unifi controller:
2024-03-26 12:09:21.904 DEBUG (MainThread) [homeassistant.components.unifi] Last received websocket timestamp: 2024-03-26 19:09:20.771599+00:00
2024-03-26 12:09:44.593 INFO (MainThread) [homeassistant.components.unifi] Will try to reconnect to UniFi Network
2024-03-26 12:09:44.593 DEBUG (MainThread) [aiounifi.interfaces.connectivity] sending (to https://xxx:8443) get, None, {'allow_redirects': False}
2024-03-26 12:09:44.652 DEBUG (MainThread) [aiounifi.interfaces.connectivity] received (from https://xxx:8443) 200 text/html <ClientResponse(https://xxx:8443) [200 None]>
<CIMultiDictProxy('Cache-Control': 'private', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/html', 'Content-Length': '3838', 'Date': 'Tue, 26 Mar 2024 19:09:44 GMT')>
2024-03-26 12:09:44.652 DEBUG (MainThread) [aiounifi.interfaces.connectivity] data (from https://xxx:8443) b'<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>UniFi Network - Server status</title><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><base href="/manage/"><link href="angular/gca760d32f/fonts/aura/fonts.css" rel="stylesheet"><link href="angular/gca760d32f/fonts/ubnt-icon/style.css" rel="stylesheet"><link href="angular/gca760d32f/css/app.css" rel="stylesheet"><link rel="apple-touch-icon-precomposed" href="angular/gca760d32f/images/favicons/favicon-192.png?v=2"><meta name="msapplication-TileColor" content="#0193d7"><meta name="msapplication-TileImage" content="angular/gca760d32f/images/favicons/favicon-192.png?v=2"><link rel="apple-touch-icon-precomposed" sizes="192x192" href="angular/gca760d32f/images/favicons/favicon-192.png?v=2"><link rel="apple-touch-icon-precomposed" href="angular/gca760d32f/images/favicons/favicon-64.png?v=2" sizes="64x64"><link rel="icon" href="angular/gca760d32f/images/favicons/favicon-32.png?v=2" sizes="32x32"><link rel="icon" href="angular/gca760d32f/images/favicons/favicon-16.png?v=2" sizes="16x16"></head><body><script type="text/javascript">function checkStatus () {\n var xhr = new XMLHttpRequest();\n xhr.addEventListener(\'load\', function (event) {\n try {\n var response = JSON.parse(event.currentTarget.response);\n if (response.meta && response.meta.up) {\n window.location.reload();\n } else if (response.meta && response.meta.app_context_status) {\n document.getElementById("appContextStatus").innerHTML = response.meta.app_context_status\n\n var messageElement = document.getElementById("appContextMessage");\n if (response.meta.app_context_message) {\n messageElement.innerHTML = response.meta.app_context_message;\n messageElement.style.display = \'\';\n } else {\n messageElement.style.innerHTML = \'\';\n messageElement.style.display = \'none\';\n }\n } else if (response.meta && response.meta.app_context_error) {\n showError(response.meta.app_context_error);\n } else {\n document.getElementById("appContextStatus").innerHTML = \'Network application is starting up...\';\n var serverElement = document.getElementById("appContextMessage");\n serverElement.innerHTML = \'Please wait a moment\';\n serverElement.display = \'\';\n }\n }\n catch (e) {\n console.log(e);\n }\n }, false);\n xhr.addEventListener(\'error\', function (jqXHR, status, error) {\n showError(\'Connection error. Please check your Network application process state.\', error);\n }, false);\n\n var url = location.protocol + \'//\' + location.host + \'/status\';\n xhr.open(\'GET\', url);\n xhr.send();\n}\n\nfunction showError(msg, error) {\n document.getElementById("appContextStatus").innerHTML = \'<p>\' + msg + \'</p>\';;\n document.getElementById("appInfoBox").className += \' appInfoBox--danger\';\n document.getElementById("appInfoBoxIcon").className = document.getElementById("appInfoBoxIcon").className.replace(/ubnt-icon--info/ , \'ubnt-icon--alert\');\n var messageElement = document.getElementById("appContextMessage");\n messageElement.style.display = \'none\';\n messageElement.style.innerHTML = \'\';\n console.log(error);\n clearInterval(checkInterval);\n}\n\nvar checkInterval = setInterval(function(){\n checkStatus();\n}, 500);\n</script><div class="appContainer appContainer--responsive appContainer--centered verticalRhythmTop"><div class="appRow--comfy"><div class="col--xs12"><div class="appInfoBox appInfoBox--responsive" id="appInfoBox"><div class="appInfoBox__icon icon ubnt-icon--info" id="appInfoBoxIcon"></div><div class="appInfoBox__content"><div class="appInfoBox__header"><p id="appContextStatus">Network application is starting up...</p><p><span id="appContextMessage"></span></p></div></div></div></div></div></div></body></html>'
2024-03-26 12:09:44.652 DEBUG (MainThread) [aiounifi.interfaces.connectivity] Talking to UniFi OS device: True
2024-03-26 12:09:44.652 DEBUG (MainThread) [aiounifi.interfaces.connectivity] sending (to https://xxx:8443/api/auth/login) post, {'username': 'xxx', 'password': 'xxx', 'remember': True}, {}
2024-03-26 12:09:44.656 DEBUG (MainThread) [aiounifi.interfaces.connectivity] received (from https://xxx:8443/api/auth/login) 200 text/html <ClientResponse(https://xxx:8443/api/auth/login) [200 None]>
<CIMultiDictProxy('Cache-Control': 'private', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/html', 'Content-Length': '3838', 'Date': 'Tue, 26 Mar 2024 19:09:44 GMT')>
2024-03-26 12:09:44.657 DEBUG (MainThread) [aiounifi.interfaces.connectivity] data (from https://xxx:8443/api/auth/login) b'<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>UniFi Network - Server status</title><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><base href="/manage/"><link href="angular/gca760d32f/fonts/aura/fonts.css" rel="stylesheet"><link href="angular/gca760d32f/fonts/ubnt-icon/style.css" rel="stylesheet"><link href="angular/gca760d32f/css/app.css" rel="stylesheet"><link rel="apple-touch-icon-precomposed" href="angular/gca760d32f/images/favicons/favicon-192.png?v=2"><meta name="msapplication-TileColor" content="#0193d7"><meta name="msapplication-TileImage" content="angular/gca760d32f/images/favicons/favicon-192.png?v=2"><link rel="apple-touch-icon-precomposed" sizes="192x192" href="angular/gca760d32f/images/favicons/favicon-192.png?v=2"><link rel="apple-touch-icon-precomposed" href="angular/gca760d32f/images/favicons/favicon-64.png?v=2" sizes="64x64"><link rel="icon" href="angular/gca760d32f/images/favicons/favicon-32.png?v=2" sizes="32x32"><link rel="icon" href="angular/gca760d32f/images/favicons/favicon-16.png?v=2" sizes="16x16"></head><body><script type="text/javascript">function checkStatus () {\n var xhr = new XMLHttpRequest();\n xhr.addEventListener(\'load\', function (event) {\n try {\n var response = JSON.parse(event.currentTarget.response);\n if (response.meta && response.meta.up) {\n window.location.reload();\n } else if (response.meta && response.meta.app_context_status) {\n document.getElementById("appContextStatus").innerHTML = response.meta.app_context_status\n\n var messageElement = document.getElementById("appContextMessage");\n if (response.meta.app_context_message) {\n messageElement.innerHTML = response.meta.app_context_message;\n messageElement.style.display = \'\';\n } else {\n messageElement.style.innerHTML = \'\';\n messageElement.style.display = \'none\';\n }\n } else if (response.meta && response.meta.app_context_error) {\n showError(response.meta.app_context_error);\n } else {\n document.getElementById("appContextStatus").innerHTML = \'Network application is starting up...\';\n var serverElement = document.getElementById("appContextMessage");\n serverElement.innerHTML = \'Please wait a moment\';\n serverElement.display = \'\';\n }\n }\n catch (e) {\n console.log(e);\n }\n }, false);\n xhr.addEventListener(\'error\', function (jqXHR, status, error) {\n showError(\'Connection error. Please check your Network application process state.\', error);\n }, false);\n\n var url = location.protocol + \'//\' + location.host + \'/status\';\n xhr.open(\'GET\', url);\n xhr.send();\n}\n\nfunction showError(msg, error) {\n document.getElementById("appContextStatus").innerHTML = \'<p>\' + msg + \'</p>\';;\n document.getElementById("appInfoBox").className += \' appInfoBox--danger\';\n document.getElementById("appInfoBoxIcon").className = document.getElementById("appInfoBoxIcon").className.replace(/ubnt-icon--info/ , \'ubnt-icon--alert\');\n var messageElement = document.getElementById("appContextMessage");\n messageElement.style.display = \'none\';\n messageElement.style.innerHTML = \'\';\n console.log(error);\n clearInterval(checkInterval);\n}\n\nvar checkInterval = setInterval(function(){\n checkStatus();\n}, 500);\n</script><div class="appContainer appContainer--responsive appContainer--centered verticalRhythmTop"><div class="appRow--comfy"><div class="col--xs12"><div class="appInfoBox appInfoBox--responsive" id="appInfoBox"><div class="appInfoBox__icon icon ubnt-icon--info" id="appInfoBoxIcon"></div><div class="appInfoBox__content"><div class="appInfoBox__header"><p id="appContextStatus">Network application is starting up...</p><p><span id="appContextMessage"></span></p></div></div></div></div></div></div></body></html>'
2024-03-26 12:09:44.657 DEBUG (MainThread) [aiounifi.interfaces.connectivity] Logged in to UniFi https://xxx:8443/api/auth/login
2024-03-26 12:09:44.674 ERROR (MainThread) [aiounifi.interfaces.connectivity] Server handshake error connecting to UniFi websocket: '200, message='Invalid response status', url=URL('wss://xxx:8443/proxy/network/wss/s/default/events')'
2024-03-26 12:09:44.674 ERROR (MainThread) [homeassistant.components.unifi] Websocket setup failed
2024-03-26 12:09:59.678 INFO (MainThread) [homeassistant.components.unifi] Will try to reconnect to UniFi Network
2024-03-26 12:09:59.678 DEBUG (MainThread) [aiounifi.interfaces.connectivity] sending (to https://xxx:8443) get, None, {'allow_redirects': False}
2024-03-26 12:09:59.711 DEBUG (MainThread) [aiounifi.interfaces.connectivity] received (from https://xxx:8443) 302 application/octet-stream <ClientResponse(https://xxx:8443) [302 None]>
<CIMultiDictProxy('Location': '/manage', 'Content-Length': '0', 'Date': 'Tue, 26 Mar 2024 19:09:59 GMT')>
2024-03-26 12:09:59.711 DEBUG (MainThread) [aiounifi.interfaces.connectivity] data (from https://xxx:8443) b''
2024-03-26 12:09:59.711 DEBUG (MainThread) [aiounifi.interfaces.connectivity] Talking to UniFi OS device: True
2024-03-26 12:09:59.712 DEBUG (MainThread) [aiounifi.interfaces.connectivity] sending (to https://xxx:8443/api/auth/login) post, {'username': 'xxx', 'password': 'xxx', 'remember': True}, {}
2024-03-26 12:09:59.716 DEBUG (MainThread) [aiounifi.interfaces.connectivity] received (from https://xxx:8443/api/auth/login) 401 application/json <ClientResponse(https://xxx:8443/api/auth/login) [401 None]>
<CIMultiDictProxy('Vary': 'Origin', 'X-Frame-Options': 'DENY', 'Content-Type': 'application/json;charset=UTF-8', 'Content-Length': '63', 'Date': 'Tue, 26 Mar 2024 19:09:59 GMT')>
2024-03-26 12:09:59.716 DEBUG (MainThread) [homeassistant.components.unifi] Schedule reconnect to UniFi Network 'Call https://xxx:8443/api/auth/login received 401 Unauthorized'
2024-03-26 12:10:14.718 DEBUG (MainThread) [aiounifi.interfaces.connectivity] sending (to https://xxx:8443) get, None, {'allow_redirects': False}
2024-03-26 12:10:14.763 DEBUG (MainThread) [aiounifi.interfaces.connectivity] received (from https://xxx:8443) 302 application/octet-stream <ClientResponse(https://xxx:8443) [302 None]>
<CIMultiDictProxy('Location': '/manage', 'Content-Length': '0', 'Date': 'Tue, 26 Mar 2024 19:10:14 GMT')>
2024-03-26 12:10:14.763 DEBUG (MainThread) [aiounifi.interfaces.connectivity] data (from https://xxx:8443) b''
2024-03-26 12:10:14.763 DEBUG (MainThread) [aiounifi.interfaces.connectivity] Talking to UniFi OS device: True
2024-03-26 12:10:14.763 DEBUG (MainThread) [aiounifi.interfaces.connectivity] sending (to https://xxx:8443/api/auth/login) post, {'username': 'xxx', 'password': 'xxx', 'remember': True}, {}
2024-03-26 12:10:14.770 DEBUG (MainThread) [aiounifi.interfaces.connectivity] received (from https://xxx:8443/api/auth/login) 401 application/json <ClientResponse(https://xxx:8443/api/auth/login) [401 None]>
<CIMultiDictProxy('Vary': 'Origin', 'X-Frame-Options': 'DENY', 'Content-Type': 'application/json;charset=UTF-8', 'Content-Length': '63', 'Date': 'Tue, 26 Mar 2024 19:10:14 GMT')>
2024-03-26 12:10:14.770 DEBUG (MainThread) [homeassistant.components.unifi] Schedule reconnect to UniFi Network 'Call https://xxx:8443/api/auth/login received 401 Unauthorized'

...repeats over and over every 15 seconds never successfully...
2024-03-26 12:12:15.087 DEBUG (MainThread) [homeassistant.components.unifi] Schedule reconnect to UniFi Network 'Call https://xxx:8443/api/auth/login received 401 Unauthorized'
2024-03-26 12:12:21.908 DEBUG (MainThread) [homeassistant.components.unifi] Last received websocket timestamp: 2024-03-26 19:09:20.771599+00:00
2024-03-26 12:12:30.087 DEBUG (MainThread) [aiounifi.interfaces.connectivity] sending (to https://xxx:8443) get, None, {'allow_redirects': False}
2024-03-26 12:12:30.107 DEBUG (MainThread) [aiounifi.interfaces.connectivity] received (from https://xxx:8443) 302 application/octet-stream <ClientResponse(https://xxx:8443) [302 None]>
<CIMultiDictProxy('Location': '/manage', 'Content-Length': '0', 'Date': 'Tue, 26 Mar 2024 19:12:30 GMT')>
2024-03-26 12:12:30.107 DEBUG (MainThread) [aiounifi.interfaces.connectivity] data (from https://xxx:8443) b''
2024-03-26 12:12:30.107 DEBUG (MainThread) [aiounifi.interfaces.connectivity] Talking to UniFi OS device: True
2024-03-26 12:12:30.107 DEBUG (MainThread) [aiounifi.interfaces.connectivity] sending (to https://xxx:8443/api/auth/login) post, {'username': 'xxx', 'password': 'xxx', 'remember': True}, {}
2024-03-26 12:12:30.110 DEBUG (MainThread) [aiounifi.interfaces.connectivity] received (from https://xxx:8443/api/auth/login) 401 application/json <ClientResponse(https://xxx:8443/api/auth/login) [401 None]>
<CIMultiDictProxy('Vary': 'Origin', 'X-Frame-Options': 'DENY', 'Content-Type': 'application/json;charset=UTF-8', 'Content-Length': '63', 'Date': 'Tue, 26 Mar 2024 19:12:30 GMT')>
2024-03-26 12:12:30.110 DEBUG (MainThread) [homeassistant.components.unifi] Schedule reconnect to UniFi Network 'Call https://xxx:8443/api/auth/login received 401 Unauthorized'
2024-03-26 12:12:45.112 DEBUG (MainThread) [aiounifi.interfaces.connectivity] sending (to https://xxx:8443) get, None, {'allow_redirects': False}
2024-03-26 12:12:45.156 DEBUG (MainThread) [aiounifi.interfaces.connectivity] received (from https://xxx:8443) 302 application/octet-stream <ClientResponse(https://xxx:8443) [302 None]>
<CIMultiDictProxy('Location': '/manage', 'Content-Length': '0', 'Date': 'Tue, 26 Mar 2024 19:12:45 GMT')>
2024-03-26 12:12:45.156 DEBUG (MainThread) [aiounifi.interfaces.connectivity] data (from https://xxx:8443) b''
2024-03-26 12:12:45.156 DEBUG (MainThread) [aiounifi.interfaces.connectivity] Talking to UniFi OS device: True
2024-03-26 12:12:45.156 DEBUG (MainThread) [aiounifi.interfaces.connectivity] sending (to https://xxx:8443/api/auth/login) post, {'username': 'xxx', 'password': 'xxx', 'remember': True}, {}
2024-03-26 12:12:45.161 DEBUG (MainThread) [aiounifi.interfaces.connectivity] received (from https://xxx:8443/api/auth/login) 401 application/json <ClientResponse(https://xxx:8443/api/auth/login) [401 None]>
<CIMultiDictProxy('Vary': 'Origin', 'X-Frame-Options': 'DENY', 'Content-Type': 'application/json;charset=UTF-8', 'Content-Length': '63', 'Date': 'Tue, 26 Mar 2024 19:12:45 GMT')>
2024-03-26 12:12:45.162 DEBUG (MainThread) [homeassistant.components.unifi] Schedule reconnect to UniFi Network 'Call https://xxx:8443/api/auth/login received 401 Unauthorized'
2024-03-26 12:12:45.599 DEBUG (MainThread) [aiounifi.interfaces.connectivity] sending (to https://xxx:8443) get, None, {'allow_redirects': False}
2024-03-26 12:12:45.602 DEBUG (MainThread) [aiounifi.interfaces.connectivity] received (from https://xxx:8443) 302 application/octet-stream <ClientResponse(https://xxx:8443) [302 None]>
<CIMultiDictProxy('Location': '/manage', 'Content-Length': '0', 'Date': 'Tue, 26 Mar 2024 19:12:45 GMT')>
2024-03-26 12:12:45.603 DEBUG (MainThread) [aiounifi.interfaces.connectivity] data (from https://xxx:8443) b''

reloaded integration with unifi running somewhere around here:

2024-03-26 12:12:45.603 DEBUG (MainThread) [aiounifi.interfaces.connectivity] Talking to UniFi OS device: False
2024-03-26 12:12:45.603 DEBUG (MainThread) [aiounifi.interfaces.connectivity] sending (to https://xxx:8443/api/login) post, {'username': 'xxx', 'password': 'xxx', 'remember': True}, {}
2024-03-26 12:12:45.934 DEBUG (MainThread) [aiounifi.interfaces.connectivity] received (from https://xxx:8443/api/login) 200 application/json <ClientResponse(https://xxx:8443/api/login) [200 None]>
<CIMultiDictProxy('Vary': 'Origin', 'Set-Cookie': 'unifises=mv6hT6LlzkjgsYzfqC2c5Ezdt9r3xWHl; Path=/; Secure; HttpOnly', 'Set-Cookie': 'csrf_token=HkLHhHsFGgOGtqHyc5KeVF82qpfmfpch; Path=/; Secure', 'X-Frame-Options': 'DENY', 'Content-Type': 'application/json;charset=UTF-8', 'Content-Length': '30', 'Date': 'Tue, 26 Mar 2024 19:12:45 GMT')>
2024-03-26 12:12:45.934 DEBUG (MainThread) [aiounifi.interfaces.connectivity] data (from https://xxx:8443/api/login) b'{"meta":{"rc":"ok"},"data":[]}'
2024-03-26 12:12:45.935 DEBUG (MainThread) [aiounifi.interfaces.connectivity] Logged in to UniFi https://xxx:8443/api/login

What is that "Talking to UniFi OS device:" log statement, it changes state between the retries and the reload

@Kane610
Copy link
Member

Kane610 commented Mar 26, 2024

What is that "Talking to UniFi OS device:" log statement, it changes state between the retries and the reload

It is just a log to show what the hosting way of the network app, it performs a get request towards the direct url and if it receives a http OK then it is determined to be a Unifi OS system

@xconverge
Copy link

xconverge commented Mar 26, 2024

What is that "Talking to UniFi OS device:" log statement, it changes state between the retries and the reload

It is just a log to show what the hosting way of the network app, it performs a get request towards the direct url and if it receives a http OK then it is determined to be a Unifi OS system

Assuming you mean Unifi OS as in what runs on a UDM, in my case it should ALWAYS be false because I do not run unifi OS.

The fact that the retries all show it as true seems strange to me, and the reloads show it as false (And work)

I will look at the code but is there any behavior difference or is it just a log?

@xconverge
Copy link

xconverge commented Mar 26, 2024

Aha there is a functional difference, so I think this check needs to be tweaked a bit, if 8.1.XX branch of unifi controller maybe started returning OK for this even in the case of a self hosted controller?


    async def check_unifi_os(self) -> None:
        """Check if controller is running UniFi OS."""
        response, _ = await self._request("get", self.config.url, allow_redirects=False)
        if response.status == HTTPStatus.OK:
            self.is_unifi_os = True
            self.config.session.cookie_jar.clear_domain(self.config.host)
        LOGGER.debug("Talking to UniFi OS device: %s", self.is_unifi_os)
 url = f"{self.config.url}/api{'/auth/login' if self.is_unifi_os else '/login'}"

let me figure out if I can tweak this code a bit to just always return false and see if my problems go away

@Kane610
Copy link
Member

Kane610 commented Mar 26, 2024

Assuming you mean Unifi OS as in what runs on a UDM, in my case it should ALWAYS be false because I do not run unifi OS.

It should be False yes

The fact that the retries all show it as true seems strange to me, and the reloads show it as false (And work)

It is unknown to me if this is something that has changed recently, I would guess that it is 200 text/html response that throws the check off

I will look at the code but is there any behavior difference or is it just a log?

It adjusts the url paths as they are different between Unifi OS hosted apps and self hosted, one example https://github.com/Kane610/aiounifi/blob/145e60e4239964b5f99e91e6cb5c6fcda0dd5817/aiounifi/interfaces/connectivity.py#L60

@xconverge
Copy link

Is there a way for me to edit the code for the HA integration without forking it to a custom_component?

Otherwise I can move over to the aiounifi repo instead and try to run some tests from that side instead

@Kane610
Copy link
Member

Kane610 commented Mar 26, 2024

Is there a way for me to edit the code for the HA integration without forking it to a custom_component?

Otherwise I can move over to the aiounifi repo instead and try to run some tests from that side instead

Depend on how you run your Home Assistant instance, it's a bit more cumbersome to edit files in a container environment as it gets reset on restart. There is no reconnection logic in the aiounifi library but would be quite easy to just doa loop somewhere in the main.py if you run it from the CLI which shouldn't really be far away from how the integration handles reconnects

@xconverge
Copy link

Is there a way for me to edit the code for the HA integration without forking it to a custom_component?
Otherwise I can move over to the aiounifi repo instead and try to run some tests from that side instead

Depend on how you run your Home Assistant instance, it's a bit more cumbersome to edit files in a container environment as it gets reset on restart. There is no reconnection logic in the aiounifi library but would be quite easy to just doa loop somewhere in the main.py if you run it from the CLI which shouldn't really be far away from how the integration handles reconnects

Ok, I will just pull the unifi integration into a custom component for now so I can continue to help/test effectively

@xconverge
Copy link

Ok having a bad time trying to get it done, so I will just move over to the aiounifi repo later tonight and see if I can come up with a reproducible test file and example and maybe a solution

I think any code change would be there anyways

@xconverge
Copy link

xconverge commented Mar 27, 2024

@Kane610 I am able to see the similar behavior with aiounifi.

Restart unifi, then try to connect:

fails
❯ python __main__.py xx xx xx
Starting aioUniFi
Server handshake error connecting to UniFi websocket: '200, message='Invalid response status', url=URL('wss://192.168.1.180:8443/proxy/network/wss/s/default/events')'
^C⏎       
fails     
❯ python __main__.py xx xx xx
Starting aioUniFi
Server handshake error connecting to UniFi websocket: '200, message='Invalid response status', url=URL('wss://192.168.1.180:8443/proxy/network/wss/s/default/events')'
^C⏎    
fails  
❯ python __main__.py xx xx xx
Starting aioUniFi
Server handshake error connecting to UniFi websocket: '200, message='Invalid response status', url=URL('wss://192.168.1.180:8443/proxy/network/wss/s/default/events')'
^C⏎           

after ~30 seconds have elapsed since the controller restarted it connects fine with no issues                                                                                                                  
❯ python __main__.py xx xx xx
Starting aioUniFi
^C⏎            

It is also detecting it as unifi OS on these fail attempts, but changing the code to always return false for that made no difference to behavior for me.

So to me, the library seems like it is working pretty well or at least throws manageable errors, which brings me back to why does reloading work when reconnecting does not...

I pulled the integration out to a custom_component now and it is running, so I can test any ideas I come up with, not really sure what's going on yet

@xconverge
Copy link

Got it!

this is the proper fix Kane610/aiounifi#625

This is the hack that I used to test it from this integration

diff --git a/homeassistant/components/unifi/hub/api.py b/homeassistant/components/unifi/hub/api.py
index 8a1be0427b..1fd846b735 100644
--- a/homeassistant/components/unifi/hub/api.py
+++ b/homeassistant/components/unifi/hub/api.py
@@ -55,6 +55,7 @@ async def get_unifi_api(

     try:
         async with asyncio.timeout(10):
+            api.connectivity.is_unifi_os = False
             await api.login()
         return api

diff --git a/homeassistant/components/unifi/hub/websocket.py b/homeassistant/components/unifi/hub/websocket.py
index 614d9a03e9..ce3c85d6f5 100644
--- a/homeassistant/components/unifi/hub/websocket.py
+++ b/homeassistant/components/unifi/hub/websocket.py
@@ -100,7 +100,8 @@ class UnifiWebsocket:
         async def _reconnect() -> None:
             """Try to reconnect UniFi Network session."""
             try:
-                async with asyncio.timeout(5):
+                async with asyncio.timeout(10):
+                    self.api.connectivity.is_unifi_os = False
                     await self.api.login()

             except (

@Kane610
Copy link
Member

Kane610 commented Mar 27, 2024

Fix is merged and will be part of 2024.4 release. Try out the beta if you want it early

@Loic691
Copy link

Loic691 commented Mar 28, 2024

Hi
Same issue for me each morning at 6 o'clock...
Since march. I done update of HA, update of last unifi Add'on
I must each morning restart unifi intégration to get back my unifi entity

@Kane610
Copy link
Member

Kane610 commented Mar 28, 2024

Hi Same issue for me each morning at 6 o'clock... Since march. I done update of HA, update of last unifi Add'on

This has been communicated as fixed, try out the beta and see if that resolves your problem

@Gazoonky
Copy link
Author

Gazoonky commented Apr 3, 2024

2024.4 has indeed fixed the issue for me. Thanks

@xconverge
Copy link

👍 glad my comments/fix made sense here, I was starting to feel crazy

@Kane610
Copy link
Member

Kane610 commented Apr 7, 2024

👍 glad my comments/fix made sense here, I was starting to feel crazy

Thanks for contributing ❤️

@github-actions github-actions bot locked and limited conversation to collaborators May 7, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants