Skip to content

Incorrect assumption about playback/hls crashes when just listening for events #1144

@KTibow

Description

@KTibow

Describe the bug
simplipy hardcodes "playback/hls" when constructing WebsocketEvent.media_urls, but SimpliSafe has started sending "playback/flv" instead for some camera events. This causes a KeyError that crashes the entire websocket loop, meaning no further events are received.

To Reproduce

  1. Have a SimpliSafe camera that returns playback/flv instead of playback/hls
  2. Trigger any camera event (motion detection, doorbell press, etc.)
  3. Observe the KeyError: 'playback/hls' in logs

Expected behavior
The websocket should gracefully handle video payloads with either playback/hls or playback/flv links (or neither), and the websocket loop should continue receiving events.

Screenshots

Logger: homeassistant.components.simplisafe
Source: components/simplisafe/__init__.py:492
Integration: SimpliSafe (documentation, issues)
First occurred: 11:01:56 AM (1 occurrence)
Last logged: 11:01:56 AM
Unexpected error in websocket loop: 'playback/hls'

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/simplisafe/__init__.py", line 492, in _async_websocket_loop
    await self._api.websocket.async_listen()
  File "/usr/local/lib/python3.14/site-packages/simplipy/websocket.py", line 457, in async_listen
    self._parse_payload(message)
    ~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/usr/local/lib/python3.14/site-packages/simplipy/websocket.py", line 352, in _parse_payload
    event = websocket_event_from_payload(payload)
  File "/usr/local/lib/python3.14/site-packages/simplipy/websocket.py", line 225, in websocket_event_from_payload
    return WebsocketEvent(
        payload["data"]["eventCid"],
    ...<8 lines>...
        sensor_type=payload["data"]["sensorType"],
    )
  File "/usr/local/lib/python3.14/site-packages/simplipy/websocket.py", line 207, in __post_init__
    "hls_url": self._video[self._vid]["_links"]["playback/hls"]["href"],
KeyError: 'playback/hls'

Additional context

SimpliSafe appears to have changed their video API for some camera models (confirmed on model SS001). The _links dict in the video payload now contains playback/flv instead of playback/hls. A sample payload _links:

{
  "_self": { "href": "https://[REDACTED].us-east-1.prd.cam.simplisafe.com/v1/recordings/[REDACTED]", "method": "GET" },
  "playback/flv": { "href": "https://media.simplisafe.com/v1/[REDACTED]/flv?ts=[REDACTED]&postroll=60", "method": "GET" },
  "preview/mjpg": { "href": "https://media.simplisafe.com/v1/[REDACTED]/mjpg?ts=[REDACTED]&duration=65", "method": "GET" },
  "snapshot/mjpg": { "href": "https://media.simplisafe.com/v1/[REDACTED]/mjpg?ts=[REDACTED]&duration=10", "method": "GET" },
  "snapshot/jpg": { "href": "https://media.simplisafe.com/v1/[REDACTED]/snapshot?ts=[REDACTED]", "method": "GET" },
  "download/mp4": { "href": "https://media.simplisafe.com/v1/[REDACTED]/mp4?ts=[REDACTED]&duration=65", "method": "GET" },
  "share": { "href": "https://media.simplisafe.com/v1/[REDACTED]/share?ts=[REDACTED]&duration=65", "method": "POST" }
}

Note the absence of playback/hls and presence of playback/flv. This causes the KeyError in __post_init__ at websocket.py:207. The error also kills the entire websocket loop since the KeyError propagates up and is caught by the broad except Exception handler.

Disclosure

Drafted by Kimi K2.6 with human oversight

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions