{"id":50216087,"url":"https://github.com/mrazza/cctv-home-occupancy","last_synced_at":"2026-05-26T09:03:38.123Z","repository":{"id":359917157,"uuid":"1247182918","full_name":"mrazza/cctv-home-occupancy","owner":"mrazza","description":"A CPU-optimized local Linux pipeline using OpenAI CV and YOLOv8/ByteTrack to monitor home occupancy via RTSP streams, featuring directional tripwire tracking and a FastAPI query endpoint.","archived":false,"fork":false,"pushed_at":"2026-05-24T04:47:47.000Z","size":83,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-24T06:20:52.151Z","etag":null,"topics":["bytetrack","computer-vision","fastapi","home-automation","motion-detection","object-tracking","opencv","rtsp","sqlite","yolov8"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mrazza.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-23T02:01:52.000Z","updated_at":"2026-05-24T04:47:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mrazza/cctv-home-occupancy","commit_stats":null,"previous_names":["mrazza/cctv-home-occupancy"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/mrazza/cctv-home-occupancy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrazza%2Fcctv-home-occupancy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrazza%2Fcctv-home-occupancy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrazza%2Fcctv-home-occupancy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrazza%2Fcctv-home-occupancy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrazza","download_url":"https://codeload.github.com/mrazza/cctv-home-occupancy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrazza%2Fcctv-home-occupancy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33512335,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T03:12:49.672Z","status":"ssl_error","status_checked_at":"2026-05-26T03:12:47.976Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bytetrack","computer-vision","fastapi","home-automation","motion-detection","object-tracking","opencv","rtsp","sqlite","yolov8"],"created_at":"2026-05-26T09:03:32.732Z","updated_at":"2026-05-26T09:03:38.106Z","avatar_url":"https://github.com/mrazza.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# House Presence Monitoring System (cctv-home-occupancy)\n\nA private, high-performance local Linux pipeline to monitor presence in your home using realtime video streams (e.g. Nest cameras). It operates in a **\"Fast \u0026 Slow\"** fashion to optimize CPU utilization:\n1. **Fast Stage (0% CPU idle)**: Continuous, ultra-lightweight pixel differencing with OpenCV.\n2. **Slow Stage (Active AI)**: Activates YOLOv8 and ByteTrack to track people crossing virtual tripwires only when motion is detected.\n\nExposes a FastAPI endpoint that can be directly queried or hooked into a Mattermost Chatbot Slash Command.\n\n---\n\n## 🛠 Features\n- **RTSP Input**: Integrated with local WebRTC-to-RTSP bridges (e.g. Scrypted or go2rtc).\n- **CPU Optimized**: Uses background subtraction to wake/sleep the deep learning tracking logic.\n- **Directional Crossing Math**: Uses geometric intersection and vector cross-product to detect entering vs. leaving.\n- **Self-Correcting State Engine**: Maintains transactional SQLite DB representing household occupancy.\n- **Queryable API**: FastAPI allows Mattermost bots to query \"Is anyone home?\" or fetch snapshots of recent entry/exit events.\n- **Facial Crop Support**: Automatically isolates crops of faces/bodies for future facial identification.\n\n---\n\n## 📐 Configuring Your Tripwire (Line-Crossing)\n\nEvery camera has a unique angle, so you must define the doorway boundary in `src/config.py` using normalized coordinates from `0.0` (top/left) to `1.0` (bottom/right).\n\n### The \"Left-Hand Rule\" for Directed Vectors\nThe tripwire is represented as a directed vector starting at Point A $(x_1, y_1)$ and ending at Point B $(x_2, y_2)$. \n\nTo determine which side of the line is **Inside** (incrementing occupancy) vs. **Outside** (decrementing occupancy), use the **Left-Hand Rule**:\n\u003e **Imagine standing at Point A and looking down the line towards Point B:**\n\u003e * Any crossing onto your **Left-hand side** is classified as **Inside (+1 / ENTER)**.\n\u003e * Any crossing onto your **Right-hand side** is classified as **Outside (-1 / LEAVE)**.\n\n---\n\n### Concrete Visual Examples (Screen Space)\nIn screen coordinates, the top-left corner is `(0.0, 0.0)` and the bottom-right corner is `(1.0, 1.0)`. Here is how the line direction maps visually:\n\n#### 1. Horizontal Doorways\n* **Drawing from Left to Right:** Point A is Left, Point B is Right.\n  * Stand at A, look at B: Your Left hand points **downward**.\n  * 🟢 **Inside (+1 / ENTER)** is visually **below** the line (higher Y values, closer to the bottom of the screen).\n  * 🔴 **Outside (-1 / LEAVE)** is visually **above** the line (lower Y values, closer to the top of the screen).\n* **Drawing from Right to Left:** Point A is Right, Point B is Left.\n  * Stand at A, look at B: Your Left hand points **upward**.\n  * 🟢 **Inside (+1 / ENTER)** is visually **above** the line (closer to the top of the screen).\n  * 🔴 **Outside (-1 / LEAVE)** is visually **below** the line (closer to the bottom of the screen).\n\n#### 2. Vertical Doorways\n* **Drawing from Bottom to Top:** Point A is Bottom, Point B is Top.\n  * Stand at A, look at B: Your Left hand points to the **left**.\n  * 🟢 **Inside (+1 / ENTER)** is visually to the **Left** of the line (lower X values).\n  * 🔴 **Outside (-1 / LEAVE)** is visually to the **Right** of the line (higher X values).\n* **Drawing from Top to Bottom:** Point A is Top, Point B is Bottom.\n  * Stand at A, look at B: Your Left hand points to the **right**.\n  * 🟢 **Inside (+1 / ENTER)** is visually to the **Right** of the line (higher X values).\n  * 🔴 **Outside (-1 / LEAVE)** is visually to the **Left** of the line (lower X values).\n\n---\n\n## 🚀 Installation \u0026 Setup\n\n### 1. Prerequisites\n- Linux Server with Python 3.10+ and Docker.\n- A local RTSP stream from your Nest Camera using a WebRTC-to-RTSP bridge (e.g., **Scrypted** or **go2rtc**).\n\n### 2. Install Dependencies\n```bash\ncd sources/mrazza/cctv-home-occupancy\npython3 -m venv venv\nsource venv/bin/activate\npip install -r requirements.txt\n```\n\n### 3. Run Unit and Integration Tests\nTo make sure all tracking math, state engines, and API endpoints function perfectly:\n```bash\nPYTHONPATH=src pytest\n```\n\n---\n\n## ⚙️ Environment Variables Config\n\nYou can customize runtime parameters using environment variables without editing the source code:\n\n| Env Variable | Default Value | Description |\n| :--- | :--- | :--- |\n| `CCTV_RTSP_URL` | `rtsp://localhost:8554/nest-cam` | The local camera stream URL. |\n| `CCTV_FPS_LIMIT` | `10` | Target frames per second to process. |\n| `CCTV_MOTION_THRESHOLD` | `0.005` | Percent of changed pixels (0.0 to 1.0) to trigger motion state. |\n| `CCTV_MIN_CONTOUR_AREA` | `500` | Minimum pixel area of a moving object. |\n| `CCTV_MOTION_COOLDOWN` | `150` | How many frames of silence before shutting off YOLO. |\n| `CCTV_DB_PATH` | `db/presence.db` | Path to the SQLite presence database. |\n| `CCTV_SNAPSHOT_DIR` | `snapshots` | Folder path where face/body crops are stored. |\n\n---\n\n## 🏃 Running the Application\n\nTo start both the API server and the background camera-monitoring pipeline:\n```bash\nsource venv/bin/activate\npython run.py --rtsp \"rtsp://localhost:8554/nest-cam\"\n```\n\n### API Endpoints\n* **Get Current Status**: `GET http://localhost:8000/status`\n  * Returns: `{\"is_someone_home\": true, \"current_occupancy\": 1, \"last_updated\": \"...\"}`\n* **Fetch Recent Events**: `GET http://localhost:8000/events?limit=10`\n* **Manual Override/Reset**: `POST http://localhost:8000/reset`\n  * Body: `{\"is_someone_home\": false, \"current_occupancy\": 0}`\n* **Fetch Event Snapshots**: Files can be served directly from `/snapshots/...` (e.g., `http://localhost:8000/snapshots/enter_id9_20260522_210145_390123.jpg`).\n\n---\n\n## 💬 Mattermost Integration\n\nTo let users ask *\"Is there anyone in the house?\"* inside Mattermost:\n\n1. Go to **Mattermost System Console \u003e Integrations \u003e Slash Commands**.\n2. Create a new command (e.g. `/whoshome`).\n3. Set the **Request URL** to `http://\u003cyour-linux-server-ip\u003e:8000/status` (or use a reverse proxy like Nginx with Auth).\n4. Implement a lightweight middleware/webhook handler or configure your command to parse the FastAPI response and output a friendly markdown message:\n   ```markdown\n   🟢 **Someone is home.**\n   * **Current occupancy:** 1 occupant(s)\n   * **Last transition:** Detected at 2026-05-22 21:01\n   ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrazza%2Fcctv-home-occupancy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrazza%2Fcctv-home-occupancy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrazza%2Fcctv-home-occupancy/lists"}