reolink-ha-bridge
Standalone Python script to download Reolink camera recordings filtered by AI detection type (person, vehicle, pet, motion). Designed for Home Assistant integration via shell_command.
No dependencies — uses only Python 3.9+ stdlib.
Why?
The native Reolink HA integration doesn't support downloading recordings filtered by AI detection type. This script talks directly to cameras via their HTTPS API.
Install
With uvx (no install needed):
uvx reolink-download --host 192.168.1.100 --password SECRET --type person --since 2h
Or install globally:
uv tool install reolink-download
Or just run the script directly — it has no dependencies:
python3 reolink_download.py --host 192.168.1.100 --password SECRET --type person --since 2h
Usage
reolink-download \
--host 192.168.1.100 \
--password SECRET \
--type person \
--since 2h \
--max 3 \
--stream sub \
--output /tmp/downloads \
--manifest
Arguments
| Argument | Default | Description |
|---|---|---|
--host |
required | Camera IP address |
--password |
env REOLINK_PASSWORD |
Camera password (or REOLINK_PASSWORD env var) |
--user |
admin |
Camera username |
--channel |
0 |
Camera channel |
--type |
all |
Comma-separated: person, vehicle, pet, motion, all |
--since |
2h |
Time period: 30m, 2h, 1d, etc. |
--max |
3 |
Max files to download |
--stream |
sub |
Stream quality: main (full HD) or sub (smaller, good for Telegram) |
--output |
. |
Output directory |
--manifest |
off | Write manifest.json with file list |
--cleanup |
0 |
Remove files older than N minutes before downloading |
Examples
# Person detections from last 2 hours
python3 reolink_download.py --host 192.168.1.100 --password PASS --type person --since 2h
# Person + vehicle from last 4 hours, max 5 files
python3 reolink_download.py --host 192.168.1.100 --password PASS --type person,vehicle --since 4h --max 5
# All recordings from last day, sub stream for Telegram
python3 reolink_download.py --host 192.168.1.100 --password PASS --type all --since 1d --stream sub
# With manifest and cleanup (for HA integration)
python3 reolink_download.py --host 192.168.1.100 --password PASS --type person --since 2h \
--output /config/www/reolink_downloads --manifest --cleanup 60
Output
- Downloaded
.mp4files:{trigger}_{YYYYMMDD}_{HHMMSS}_{HHMMSS}.mp4(e.g.person_20250219_143000_143500.mp4) - File paths printed to stdout (one per line) for script consumption
- Status messages printed to stderr
- Exit code 0 on success, 1 on error
- With
--manifest: writesmanifest.json:
{
"camera": "192.168.1.100",
"type": "person",
"files": ["/path/to/person_20250219_143000_143500.mp4"],
"count": 1
}
Testing
E2E tests require a real camera. Set env vars (e.g. via .envrc):
export REOLINK_HOST=192.168.1.100
export REOLINK_PASSWORD=SECRET
Run tests:
python3 -m unittest test_e2e -v
Tests skip automatically when env vars are missing. CLI validation tests always run (no camera needed).
How it works
- Login to camera via
POST /cgi-bin/api.cgi?cmd=Login - Search recordings via
POST /cgi-bin/api.cgi?cmd=Search - Filter by AI type using hex flags in filenames (bit 4:2=person, 4:0=vehicle, 5:3=pet, 6:3=motion)
- Download files via
GET /cgi-bin/api.cgi?cmd=Download - Logout via
POST /cgi-bin/api.cgi?cmd=Logout
Filename hex flag parsing
Reolink encodes detection types in recording filenames:
RecS07_20250219_111146_111238_0_A714C0A000_21E67C.mp4
^^^^---
hex flags field (second-to-last underscore part)
Nibble at offset 4: bit 2 = Person, bit 0 = Vehicle
Nibble at offset 5: bit 3 = Pet
Nibble at offset 6: bit 3 = Motion
Home Assistant Integration
Setup
- Copy
reolink_download.pyto/config/scripts/on your HA instance - Add
reolink_passwordtosecrets.yaml - Add a
shell_commandand automation (see below) - Restart HA
Example shell_command
shell_command:
reolink_download: >
python3 /config/scripts/reolink_download.py
--host 192.168.1.100
--password '{{ states("input_text.reolink_password") }}'
--type {{ type }}
--since {{ since | default("2h") }}
--max {{ max | default("3") }}
--stream sub
--output /config/www/reolink_downloads
--manifest
--cleanup 60
Metadata
Release files for reolink-download 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| reolink_download-0.1.0.tar.gz | 11.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| reolink_download-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 20.1 kB
Release files / reolink_download-0.1.0.tar.gz
| Download URL | reolink_download-0.1.0.tar.gz |
|---|---|
| Size | 11.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
13bf8fed706709b27c818150cf3b17b87ac87ba4e0f812802f9211fdc86419bc
|
|
BLAKE2b-256 checksum How to use checksums |
45b807f1bcedfc89ec257f5c5a380b250e82ab5f178385014b268ea12e384ba8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.6.13
|
Release files / reolink_download-0.1.0-py3-none-any.whl
| Download URL | reolink_download-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6120f603b359c8f9c2d34fcf0d583750b5dd532270067c57f85a52a4ae3e9a93
|
|
BLAKE2b-256 checksum How to use checksums |
654a3854504a38152ecc5bb1b5d45c8c9ebd17073c3c9742a865a6bb5ab3fdb8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.6.13
|