Push inventory over server-sent events and log why the HA websocket closes (0.2.21)

/api/events streams the light inventory whenever the sync loop or a save
changes it (3 s check during firmware updates). The page stops polling
while the stream is open and falls back to the 10 s poll otherwise. The
websocket close is logged with duration, close code and exception.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Max Gramser
2026-09-13 11:30:46 +02:00
parent 8dc5e616f5
commit 359c289feb
5 changed files with 95 additions and 9 deletions
+10
View File
@@ -231,6 +231,16 @@ class UpdaterTests(unittest.IsolatedAsyncioTestCase):
self.assertTrue(inventory['screens'][0]['update']['available'])
self.assertIn('entities', inventory)
light = await (await client.get('/api/inventory?light=1')).json()
async with client.get('/api/events') as stream:
self.assertEqual(stream.headers['Content-Type'], 'text/event-stream')
line = await asyncio.wait_for(stream.content.readline(), 5)
pushed = json.loads(line.decode().removeprefix('data: '))
self.assertEqual([x['id'] for x in pushed['screens']], [x['id'] for x in light['screens']])
self.assertEqual(len(m.listeners), 1)
for _ in range(50): # the stream notices the closed client at its next write
if not m.listeners: break
await asyncio.sleep(0.1)
self.assertEqual(len(m.listeners), 0)
self.assertNotIn('entities', light)
self.assertNotIn('icons', light)
self.assertEqual([x['id'] for x in light['screens']], [x['id'] for x in inventory['screens']])