Skip to content
HN On Hacker News ↗

GitHub - gmrandazzo/CheapSecurity

▲ 140 points 37 comments by zeldone 4w ago HN discussion ↗

Pangram verdict · v3.3

We believe that this document is fully AI-generated

99 %

AI likelihood · overall

AI
0% human-written 100% AI-generated
SEGMENTS · HUMAN 0 of 5
SEGMENTS · AI 5 of 5
WORD COUNT 1,215
PEAK AI % 99% · §5
Analyzed
Jul 26
backend: pangram/v3.3
Segments scanned
5 windows
avg 243 words each
Distribution
0 / 100%
human / AI fraction
Verdict
AI
Pangram v3.3

Article text · 1,215 words · 5 segments analyzed

Human AI-generated
§1 AI · 99%

This project provides a lightweight, self-hosted CCTV solution designed for Linux-based single-board computers (SBCs) and standard USB webcams. It offers an affordable, privacy-focused alternative for home monitoring by keeping your video data entirely under your control. Project Philosophy

Privacy-First: By storing all footage locally, this system eliminates the need for third-party cloud subscriptions and ensures your data never leaves your network. Cost-Effective: Leverage existing hardware—such as a spare Linux board and a USB webcam—to build a fully functional surveillance system without recurring fees. Minimalist Architecture: The software is optimized to run efficiently on low-power devices, ensuring high performance even on entry-level hardware.

Key Features

Hardware Agnostic: Highly compatible with a wide range of standard USB webcams. Resource Efficient: Optimized specifically for Linux-based boards (e.g., Raspberry Pi, Orange Pi, or similar SBCs). Data Sovereignty: Full control over your storage path, retention policies, and access methods. Simple Deployment: Designed for quick setup and easy maintenance.

Features

Live MJPEG stream with a web dashboard Motion detection with frame differencing Automatic recording with a pre-motion buffer Email alerts with a snapshot picture when motion starts Telegram integration:

Automatic video upload after motion is recorded Bot commands: /snapshot, /video <seconds>, /help

Night mode low-light enhancement (software CLAHE + brightness/contrast boost) Recordings bulk actions: select all, send to Telegram, download ZIP, delete Storage cleanup by age, total size, and emergency low-disk cleanup systemd autostart ready Licensed under GNU AGPLv3

Requirements

Python 3.10 or newer OpenCV with V4L2 support (see installation options below) A USB webcam (/dev/video0 by default) Optional: a Telegram bot token for Telegram notifications Optional: SMTP credentials for email alerts

Quick start

Verify OpenCV is available: python3 -c "import cv2; print(cv2.__version__)" If OpenCV is not installed, you have two options:

Option A — use a system OpenCV package (recommended on ARM boards such as the Odroid XU4, where a pre-built system package is usually optimized for the board).

§2 AI · 97%

Option B — install OpenCV via pip (convenient on x86/amd64 machines or when no system package is available). Use opencv-python-headless because the app does not need a GUI.

Create and activate the virtual environment and install the app: Option A: system OpenCV (recommended for ARM) This creates a venv that can see the system site-packages, so the system cv2 is available inside the venv. cd $HOME/CheapSecurity python3 -m venv venv --system-site-packages source venv/bin/activate pip install -e . Option B: install everything via pip Use this if you do not have a system OpenCV or prefer a self-contained venv. cd $HOME/CheapSecurity python3 -m venv venv source venv/bin/activate pip install opencv-python-headless pip install -e .

Note: On some older ARM boards the pip opencv-python-headless wheel may not be available or may be slow. If that happens, install OpenCV from your distribution’s package manager instead and use Option A.

Find your webcam device (usually /dev/video0): v4l2-ctl --list-devices

Copy config.json.example to config.json and edit it: cp config.json.example config.json nano config.json

Set camera device, resolution, and frame rate Fill in SMTP credentials if you want email alerts Fill in Telegram bot token and chat ID if you want Telegram uploads

Security: config.json is listed in .gitignore and must never be committed. It contains passwords and tokens. Always edit config.json, not config.json.example. If you add a new setting, update both files so the example stays in sync.

Run the app: ./venv/bin/python -m cheapsecurity.app

Open the dashboard in a browser: http://<odroid-ip>:5000

Configuration Edit config.json:

Section Key Description

camera device V4L2 device index (0 = /dev/video0)

camera width, height, fps Capture resolution and frame rate

camera night_mode

§3 AI · 99%

Enable low-light enhancement

camera night_mode_fps Target FPS in night mode (camera may ignore this)

camera night_mode_gain Target analog gain in night mode (camera may ignore this)

camera night_mode_brightness Brightness boost in night mode

camera night_mode_contrast Contrast boost in night mode

motion threshold Pixel difference threshold (0-255)

motion min_area Minimum contour area to trigger motion (full-res pixels)

motion cooldown_seconds Keep recording after motion stops

motion scale Downscale factor for motion detection (saves CPU)

recording dir Where videos are saved

recording max_duration_seconds Maximum length of one clip

recording pre_buffer_seconds Seconds before motion included in clip

recording codec Preferred FourCC codec (MJPG for low CPU, mp4v for smaller files)

notifications enabled Send email alerts on motion

notifications smtp SMTP server, port, username, password, TLS

notifications from, to, subject Email sender/recipients/subject (use ["a@...", "b@..."] for multiple recipients)

notifications min_interval_minutes Minimum time between alert emails

telegram enabled Send videos to Telegram after motion is recorded

telegram bot_token, chat_id Telegram Bot API token and destination chat

telegram send_video Whether to upload the video file automatically

telegram min_interval_minutes Minimum time between Telegram uploads

telegram poll_commands Enable /snapshot, /video, and /help bot commands

storage max_age_days Delete recordings older than this (default 3 days = 72h)

§4 AI · 99%

storage max_size_gb Delete oldest files if total exceeds this

storage cleanup_interval_minutes How often storage cleanup runs

storage delete_old_on_startup If false, old recordings are kept when the app restarts

storage emergency_free_space_gb If free disk space drops below this, delete old recordings before a new one

storage emergency_delete_count How many oldest recordings to delete in an emergency cleanup

web host, port Dashboard bind address and port

web stream_scale Downscale factor for live stream (saves bandwidth/CPU)

web.auth enabled, username, password Optional HTTP Basic Auth

Telegram setup 1. Create a bot

Open Telegram and message @BotFather. Send /newbot and follow the prompts to choose a display name and username. Copy the bot token (looks like 123456789:ABCdefGHIjklMNOpqrsTUVwxyz). Keep this token secret — anyone with it can control your bot.

2. Get your chat ID

Start a private chat with your new bot and send any message (for example, /start). Open this URL in a browser, replacing <YOUR_BOT_TOKEN> with the real token: https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates

Look for "chat":{"id":123456789. The number is your chat ID.

If getUpdates is empty, send another message to the bot and refresh. If you want to use a group chat, add the bot to the group first and send a message there; the chat ID will be negative for groups.

Copy the chat ID exactly, including the - sign if it is a group.

§5 AI · 99%

3. Configure the app Fill in the telegram section of config.json: "telegram": { "enabled": true, "bot_token": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz", "chat_id": "123456789", "send_video": true, "min_interval_minutes": 5, "poll_commands": true } Then restart the service: sudo systemctl restart cheapsecurity@$(whoami).service Automatic uploads After a motion clip is saved, the video is uploaded to your Telegram chat. Uploads are rate-limited by min_interval_minutes. Bot commands From your configured chat, send:

/snapshot — receive the current camera picture /video 10 — record and send a 10-second video (1–60 seconds, default 10) /help — list commands

The bot only responds to your configured chat_id. Motion has priority: if the system is already recording because motion was detected, a /video request will not interrupt it. The bot will reply that a motion video is in progress and will be uploaded automatically. Email alerts Configure the notifications section in config.json. A picture from the moment motion starts is attached. Alerts are rate-limited by min_interval_minutes. Gmail / Google Workspace setup Google no longer allows "less secure apps" to use your regular Gmail password. You must create an App Password.

Enable 2-Step Verification on your Google account:

https://myaccount.google.com/signinoptions/two-step-verification

Create an App Password:

Go to https://myaccount.google.com/apppasswords Select app: Mail Select device: Other (Custom name) — type "CheapSecurity" Click Generate and copy the 16-character password (for example, abcd efgh ijkl mnop).