Reusable primitives for IP-camera clip tools (Tesla, Wyze, Reolink, UniFi, Ring, Nest).
Project description
tesla-clip-tools
Reusable primitives for building tools that read Tesla TeslaCam, SentryClips, and SEI data — plus the same Source/Event/sampler/vlm/notify pipeline applied to Wyze, Reolink, UniFi Protect, Ring, and Nest.
Extracted from sentrytriage v0.2 → v0.3 so that future projects (planned: an FSD-Disengagement Studio, a Wyze/Reolink/UniFi port of sentrytriage) can share the same primitives without forking.
Install
pip install tesla-clip-tools # base
pip install 'tesla-clip-tools[sei]' # adds protobuf+pandas for sei_dataframe()
Or with uv:
uv add tesla-clip-tools
uv add 'tesla-clip-tools[sei]'
Until the first PyPI release lands, install directly from GitHub:
uv add git+https://github.com/Raymondriter/tesla-clip-tools
What's inside
tesla_clip_tools/
├── sources/
│ ├── base.py Abstract Source + Event dataclass
│ ├── tesla.py SentryClips/<YYYY-MM-DD_HH-MM-SS>/{cam}.mp4 (HW3 4-cam + HW4 6-cam)
│ ├── wyze.py Wyze SD-card / RTSP folder layout
│ ├── reolink.py Reolink NVR folder layout
│ ├── unifi_protect.py UniFi Protect export layout
│ ├── ring.py Ring downloads layout
│ └── nest.py Nest / Google Home downloads layout
├── sampler.py Frame extraction via imageio (bundled ffmpeg, no system dep)
├── vlm/
│ ├── base.py Generic VLMBackend protocol parameterised on a Pydantic response_format
│ ├── openai.py gpt-4o-mini default, structured outputs via beta.chat.completions.parse
│ └── ollama.py Local Qwen2.5-VL etc. via the Ollama HTTP API + JSON-schema format
├── notify/
│ ├── base.py Notifier protocol
│ ├── pushover.py
│ └── telegram.py
├── sei.py SEI metadata extraction from Dashcam (Saved/Recent) clips
└── dashcam.proto Tesla's published proto schema (vendored)
Generating the SEI protobuf module
For the SEI dataframe convenience function, you also need to generate the protobuf module once:
protoc --python_out=src/tesla_clip_tools src/tesla_clip_tools/dashcam.proto
iter_sei_payloads() works without protobuf — it just yields raw protobuf-encoded byte payloads.
Minimal example
from pathlib import Path
from tesla_clip_tools.sources.tesla import TeslaSource
from tesla_clip_tools.sampler import sample_keyframes
from tesla_clip_tools.vlm.openai import OpenAIBackend
from pydantic import BaseModel
class MyVerdict(BaseModel):
is_interesting: bool
why: str
source = TeslaSource(Path("~/Tesla/SentryClips"))
vlm = OpenAIBackend(model="gpt-4o-mini")
for event in source.discover():
samples = sample_keyframes(event.cams, n_per_cam=4)
captions = [f"[{s.cam} t={s.timestamp_seconds:.1f}s]" for s in samples]
verdict = vlm.classify(
images=[s.image for s in samples],
captions=captions,
system_prompt="Decide if this Sentry event deserves attention. Default to false.",
response_format=MyVerdict,
)
print(event.id, verdict.is_interesting, verdict.why)
Design choices
- Generic VLM API. Every backend takes a
response_format: type[BaseModel]so different consumers (sentrytriage, FSD-Disengagement Studio, future tools) define their own verdict schema without forking the backend. - No state. No SQLite, no daemon, no notifications-orchestration. Those are application concerns; the library is just primitives. Use
notify/if you want one of the included notifiers, but it's optional. - No system ffmpeg required for the read path.
sampler.pyusesimageio[ffmpeg]which bundles its own ffmpeg binary. (Tools that build filter graphs — the highlight reel in sentrytriage, e.g. — still need system ffmpeg.) - Source-pluggable.
tesla.pyimplements the canonical TeslaCam folder layout;wyze.py,reolink.py,unifi_protect.py,ring.py, andnest.pyship in 0.3. Add a new vendor by subclassingSource— the rest of the pipeline doesn't care.
Status
v0.3 — alpha, API may still change. Used in production by sentrytriage v0.3+ and fsd-disengagement-studio.
Changelog
See CHANGELOG.md for the version history. Releases are cut following the steps in RELEASE.md.
License
MIT.
CI
GitHub Actions runs ruff + pytest on Python 3.12 and 3.13 against every push and PR. See .github/workflows/ci.yml. The same tests also run as part of the workspace-level monorepo CI at C:\Dev\tesla\.github\workflows\ci.yml.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tesla_clip_tools-0.3.0.tar.gz.
File metadata
- Download URL: tesla_clip_tools-0.3.0.tar.gz
- Upload date:
- Size: 20.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
18c44bf3dd9542d267f62319b6154468f180afed4f38a05d619ad465d10e6b70
|
|
| MD5 |
0d81b4acc7647f1bf080848f6cdd77a4
|
|
| BLAKE2b-256 |
99f7493ab9da0771d33e3c5b0e6701743dc269490e20a6b9a593a3e550bce7fb
|
File details
Details for the file tesla_clip_tools-0.3.0-py3-none-any.whl.
File metadata
- Download URL: tesla_clip_tools-0.3.0-py3-none-any.whl
- Upload date:
- Size: 24.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7bf75f99287e3e74f532decb2b811b77d2bed4d0dec7daf2f2b5a043beeea97c
|
|
| MD5 |
f84f620271d2109eda677678985205c6
|
|
| BLAKE2b-256 |
ac31d2301f3ce6d993b41f5c8e62f8f6b2542d266e6f253a73e87fa9827e539c
|