Tuya Recordings: SD-card playback for Tuya / Smart Life cameras

Hi everyone,

I’ve released a first public beta of Tuya Recordings, a Home Assistant custom integration for viewing and caching Tuya / Smart Life camera SD-card recordings.

Tuya Recordings

This is meant for cameras that already work through the official Home Assistant Tuya integration. Tuya Recordings uses the official Tuya integration as the camera inventory, reuses Tuya Cloud credentials from LocalTuya, and then talks to the Tuya IPC recording path to discover SD-card clips.

Current features:

  • Browse Tuya / Smart Life SD-card recordings in Home Assistant
  • Cached MP4 playback through Media Browser
  • Custom recordings panel with thumbnails, cache status, and storage usage
  • Optional background pre-cache mode for faster playback
  • On-demand playback mode when pre-cache is disabled
  • Private storage under /media
  • Bundled Linux helpers for amd64, arm64, and armv7

Requirements:

  • Official Home Assistant tuya integration
  • localtuya with Tuya Cloud credentials saved
  • Tuya Developer project linked to the same account
  • Required Tuya video/IPC APIs enabled
  • ffmpeg available on the Home Assistant system

This is an early beta, so camera support may vary by model, firmware, account region, and enabled Tuya APIs. If you test it, useful feedback would include your camera model, HA version, region, logs, and whether the same recording plays in the Tuya or Smart Life app.

Install through HACS as a custom integration repository:

https://github.com/Wheemer/tuya-recordings

I’d love testing from other Tuya camera owners.

This integration sounds like what I’ve been looking for, and I’d love to give it a try but I’m falling down at the first hurdle.

I’ve got a Tuya-made camera that was originally configured in the phone app. Within Home Assistant v2026.7.1 I’ve installed the ONVIF integration to get a live webcam feed and the official Tuya integration to give me access to a few feature switches to turn motion tracking, floodlight, etc. on and off.

When it comes to the prerequisites for your integration, I’ve created and configured a Tuya IOT account (with appropriate API access) and installed and configured LocalTuya to use the same account.

Now I’ve installed TuyaRecordings (version 6f42123) through HACS, but when I try to add the integration I get an error dialog:

X Error
Config flow could not be loaded: 500 Internal Server Error Server got itself in trouble

The only new message in the HASS logs is:

Logger: aiohttp.server
Source: /usr/local/lib/python3.14/site-packages/aiohttp/web_protocol.py:546
First occurred: 9:30:41 PM (3 occurrences)
Last logged: 9:34:36 PM

Error handling request from 10.10.1.14
Traceback (most recent call last):
  File "/usr/local/lib/python3.14/site-packages/aiohttp/web_protocol.py", line 575, in _handle_request
    resp = await request_handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/site-packages/aiohttp/web_app.py", line 559, in _handle
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/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 90, in security_filter_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/forwarded.py", line 86, in forwarded_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/request_context.py", line 24, in request_context_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/ban.py", line 88, in ban_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/auth.py", line 261, in auth_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/headers.py", line 39, in headers_middleware
    response = await handler(request)
               ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/http.py", line 88, in handle
    result = await handler(request, **request.match_info)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/decorators.py", line 81, in with_admin
    return await func(self, request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/data_validator.py", line 72, in wrapper
    return await method(view, request, data, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/config/config_entries.py", line 186, in post
    return await self._post_impl(request, data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/config/config_entries.py", line 194, in _post_impl
    return await super()._post_impl(request, data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/data_entry_flow.py", line 89, in _post_impl
    result = self._prepare_result_json(result)
  File "/usr/src/homeassistant/homeassistant/components/config/config_entries.py", line 216, in _prepare_result_json
    return _prepare_config_flow_result_json(result, super()._prepare_result_json)
  File "/usr/src/homeassistant/homeassistant/components/config/config_entries.py", line 152, in _prepare_config_flow_result_json
    return prepare_result_json(result)
  File "/usr/src/homeassistant/homeassistant/helpers/data_entry_flow.py", line 50, in _prepare_result_json
    data["data_schema"] = voluptuous_serialize.convert(
                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        schema, custom_serializer=cv.custom_serializer
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/usr/local/lib/python3.14/site-packages/voluptuous_serialize/__init__.py", line 59, in convert
    pval = convert(value, custom_serializer=custom_serializer)
  File "/usr/local/lib/python3.14/site-packages/voluptuous_serialize/__init__.py", line 85, in convert
    pval = convert(validator, custom_serializer=custom_serializer)
  File "/usr/local/lib/python3.14/site-packages/voluptuous_serialize/__init__.py", line 164, in convert
    raise ValueError(f"Unable to convert schema: {schema}")
ValueError: Unable to convert schema: <function _validate_media_storage_path at 0x7fda951d8d50>

Which implies that there’s something wrong with the definition of the data to be collected by the config flow. Since the error message mentioned “media storage path”, I tried pre-creating the /media/tuya_recordings folder mentioned in your README.md as the default storage location, but it didn’t change the outcome. I also tried going back to version 0.3.0-beta-3 but it was no different.

Do you have any suggestions what to try next?

Thanks for the detailed traceback. That was very helpful.

You were right: this was a bug in my config flow schema. The media storage path field was using a custom Python validator directly inside the form schema, and Home Assistant 2026.7.x could not serialize that for the frontend. Pre-creating /media/tuya_recordings would not have helped because the crash happened before the form could even render.

I’ve fixed this in v0.3.0-beta.4:

The storage path validation is still there, but it now runs after submit and reports a normal field error instead of breaking the config flow.

Please update through HACS, restart Home Assistant, and try adding the integration again. If it still fails, please open an issue on GitHub with the new traceback:

I’ll respond much faster there because I don’t receive email notifications from the Home Assistant forum.