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.

Okay, I’ve found time to try again.

Your update fixed the config flow failure. TuyaRecordings now installs without complaint, but after 48 hours of runtime the “cached clips” sensor is still sitting at 0. The TuyaRecordings UI shows the camera as online but with ReadyToWatch 0, no NewestRecordings available, and StorageUsed 0 with the Date picker empty. The Refresh button flickers when clicked but nothing changes.

The only thing I can find in the logs is a “Could not find device for device_id XYZABC123” error from localtuya that occurred on boot, but (1) the device was discovered automatically when I installed localtuya, and (2) after booting, the localtuya integration does correctly show the device and its details (IP address, local key, DPID values).

When installing the device in localtuya, I left the protocol at version 3.4, with Scan interval, manual DPS and DPIDs blank. I could see about 25 or 30 attributes available on the locatuya device, but in the absence of any guidance I just picked one (#169 - viewport dimensions) to add as a sensor when installing. Is there something in particular that TuyaRecordings needs to find?

Environment:

  • Home Assistant v2026.7.2
  • LocalTuya v5.2.3
  • TuyaRecordings v0.3.0-beta.4
  • Tuya region: central europe

Hi — thanks for the details. We just published v0.3.0-beta.6 with fixes for the empty cache/discovery issue, so please update to that and restart HA.

Please report any remaining issues by opening a GitHub issue (we don’t get emails from the Home Assistant forum):

If it still fails, send the new post-update log snippet and we’ll keep it on the issue thread.

Tuya Recordings v0.4.1 is out

This release completes the move to Smart Life-style SD-card playback in Home Assistant.

  • Native camera timeline playback with video and audio, without transcoding
  • Smart Life QR authorization directly in the integration
  • No LocalTuya setup, Tuya Developer project, helper binary, or separate bridge required
  • Optional local MP4 caching, while the default remains direct SD-card playback
  • Motion and person binary sensors, plus a camera event entity for automations and history
  • Configurable detection reset time
  • Serialized camera work and playback priority to keep background activity bounded

Update through HACS, then restart Home Assistant.

Full details and installation instructions are on GitHub:

Please report bugs or compatibility issues on GitHub so I can track them properly. I do not receive email notifications from the forum: