Automatically manage your HDHomeRun DVR recordings by keeping only the newest N episodes per show. Perfect for keeping your DVR storage under control without manually deleting old recordings.
- Per-Show Retention Policies: Set different episode limits for each show
- Automatic Cleanup: Run continuously or on-demand
- Discord Notifications: Get real-time status updates via Discord webhooks (NEW in v2.0)
- Flexible Configuration: JSON config file with environment variable support
- Multiple Execution Modes: One-time, targeted, or continuous monitoring
- Safe Deletion: Only deletes oldest episodes, always keeps the newest
- Detailed Logging: Track what's being deleted and why
The easiest way to run this tool is with Docker. See the docker/README.md for full instructions.
# Clone and setup
git clone https://github.com/rb9999/hdhr_cleanup.git
cd hdhr_cleanup
cp .env.example .env
cp config.json.example config.json
# Edit config files
nano .env # Set your DVR_IP
nano config.json # Set your show retention
# Run with Docker
cd docker
./run.sh once # One-time cleanup
./run.sh continuous # Continuous monitoring
./run.sh list # List shows# Clone the repository
git clone https://github.com/rb9999/hdhr_cleanup
cd hdhr_cleanup
# Install dependencies (system-wide)
pip install -r requirements.txtNote: This installs requests and python-dotenv to your system Python. If you prefer to isolate dependencies, see the optional virtual environment setup below.
Optional: Use a Virtual Environment (Recommended for Development)
A virtual environment isolates dependencies from your system Python. This is recommended for developers but not required for end users:
# Create virtual environment
python -m venv .venv
# Activate virtual environment
# Windows (Git Bash)
source .venv/Scripts/activate
# Windows (PowerShell)
.venv\Scripts\activate.ps1
# Linux/Mac
source .venv/bin/activate
# Install dependencies
pip install -r requirements.txtCreate config files from templates:
cp .env.example .env
cp config.json.example config.jsonEdit .env and set your DVR IP (and optionally Discord webhook):
DVR_IP=192.168.1.100:59090
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN
Edit config.json to set your retention policies:
{
"default_episodes": 5,
"poll_interval_minutes": 60,
"show_overrides": {
"Gilligans Island": 1,
"Star Trek": 3,
"Jeopardy!": 7,
"The Price is Right": 4
}
}Note:
DVR_IPcomes from.env(keeps your IP private)config.jsoncontains your show retention policies- Both files are in
.gitignoreand won't be committed
# One-time cleanup using config.json settings
python hdhr_cleanup.py --once
# Continuous monitoring (runs forever)
python hdhr_cleanup.py
# List all shows and their recording counts
python hdhr_cleanup.py --listRun cleanup once according to your config, then exit:
# Use config.json settings
python hdhr_cleanup.py --once
# Override all shows to keep 10 episodes
python hdhr_cleanup.py --once -max 10Perfect for:
- Scheduled tasks (cron, Windows Task Scheduler)
- Manual cleanups
- Testing your configuration
Target a specific show for one-time cleanup:
# Keep only 2 episodes of "The Price is Right"
python hdhr_cleanup.py -show "The Price is Right" -max 2
# Partial matching works (case-insensitive)
python hdhr_cleanup.py -show "price" -max 2See all your recorded shows and counts:
python hdhr_cleanup.py --listOutput:
Found 5 shows:
Jeopardy!: 10 recordings
NBC Nightly News With Tom Llamas: 2 recordings
New York Homicide: 1 recordings
The Price is Right: 5 recordings
Wheel of Fortune: 8 recordings
Run in the background and automatically clean up at intervals:
# Use config.json settings (polls every poll_interval_minutes)
python hdhr_cleanup.py
# Override to keep 10 episodes of all shows
python hdhr_cleanup.py -max 10This mode runs forever until stopped (Ctrl+C).
{
"dvr_ip": "192.168.1.100:59090",
"default_episodes": 5,
"poll_interval_minutes": 60,
"show_overrides": {
"Show Name": episodes_to_keep
},
"discord": {
"enabled": false,
"notify_on_cleanup": true,
"notify_on_startup": true,
"notify_on_error": true
}
}Options:
dvr_ip: Your HDHomeRun DVR IP and port (optional if using.env)default_episodes: Default number of episodes to keep for all showspoll_interval_minutes: How often to check for cleanup in continuous modeshow_overrides: Per-show episode limits (must match exact show name)discord: Discord notification settings (see Discord Notifications section below)
Special Values:
- Set a show to
0to delete ALL recordings of that show - Shows not in
show_overridesusedefault_episodes
Store sensitive information like your DVR IP and Discord webhook in .env:
DVR_IP=192.168.1.100:59090
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN
Priority order:
DVR_IPenvironment variable (.envfile)dvr_ipinconfig.json- Built-in default
Get real-time status updates sent to your Discord channel via webhooks.
Setup:
-
Create a Discord webhook:
- Open your Discord server
- Go to Server Settings → Integrations → Webhooks
- Click "New Webhook" or "Create Webhook"
- Customize the name and channel
- Copy the webhook URL
-
Add webhook URL to
.envfile:DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN -
Enable in
config.json:"discord": { "enabled": true, "notify_on_cleanup": true, "notify_on_startup": true, "notify_on_error": true }
Discord Configuration Options:
enabled: Master switch for all Discord notifications (default: false)notify_on_cleanup: Send notifications when recordings are deleted (default: true)notify_on_startup: Send notification when script starts in continuous mode (default: true)notify_on_error: Send notifications when errors occur (default: true)
Notification Types:
- Startup (purple): Script start with configuration summary
- Cleanup (green): Per-show deletion details with episode list
- Summary (blue): Total statistics after each cleanup cycle
- Error (red): Connection failures, API errors, etc.
For show_overrides in config.json, you must use the exact show name as it appears on your DVR.
Use --list to see exact names:
python hdhr_cleanup.py --listpython hdhr_cleanup.py [OPTIONS]
Options:
-show SHOW, --show SHOW
Target a specific show (case-insensitive partial match), then exit
-max N, --max-episodes N
Number of episodes to keep (overrides config for all shows)
--config PATH Path to config file (default: config.json)
--list List all shows and their recording counts, then exit
--once Run cleanup once for all shows according to config, then exit
--continuous Run continuously in monitoring mode (default when no flags specified)
--debug Enable debug logging to see detailed API requests and responses
-v, --version Show version number and exit
-h, --help Show help message and exit
Linux/Mac (cron):
# Run cleanup every day at 3 AM
0 3 * * * cd /path/to/hdhr_cleanup && python hdhr_cleanup.py --once
# Or if using virtual environment:
0 3 * * * cd /path/to/hdhr_cleanup && .venv/bin/python hdhr_cleanup.py --onceWindows (Task Scheduler):
- Action: Start a program
- Program:
python(orC:\path\to\hdhr_cleanup\.venv\Scripts\python.exeif using venv) - Arguments:
hdhr_cleanup.py --once - Start in:
C:\path\to\hdhr_cleanup
{
"default_episodes": 5,
"show_overrides": {
"Daily News Show": 1,
"Weekly Drama": 4,
"Limited Series": 0,
"Favorite Show": 20
}
}# Emergency cleanup - keep only 1 episode of everything
python hdhr_cleanup.py --once -max 1- Connects to your HDHomeRun DVR via HTTP API
- Fetches list of all recorded shows and episodes
- For each show:
- Determines retention limit (config override → default → 5)
- Sorts recordings by date (oldest first)
- Deletes oldest recordings until only N newest remain
- Logs all actions with timestamps
Safety Features:
- Only deletes when recording count exceeds limit
- Always keeps the newest episodes
- Never deletes the only recording unless explicitly set to 0
- Reports success/failure for each deletion
- Check your
DVR_IPis correct - Ensure HDHomeRun DVR is powered on and accessible
- Try accessing
http://YOUR_DVR_IP/recorded_files.jsonin browser
- Use
--listto see exact show names - Show names in
show_overridesmust be exact matches - Use
-showwith partial matching for command-line targeting
- Run with
--debugto see detailed API responses - Check if recordings are actually on the DVR
- Verify you have network access to the DVR
Run with --debug for detailed logging:
python hdhr_cleanup.py --once --debugContributions welcome! Please feel free to submit a Pull Request.
MIT License - feel free to use and modify as needed.
Works with SiliconDust HDHomeRun DVR devices and their HTTP API.
This tool deletes recordings permanently. Test with --list and small retention numbers first. Always maintain backups of important recordings.