Skip to main content

Pluggable async home security camera pipeline with detection, VLM analysis, and alerts.

Project description

HomeSec

License: Apache 2.0 Python: 3.10+ Typing: Typed

HomeSec is a pluggable, async pipeline for home security cameras. It records short clips, runs object detection, optionally calls a vision-language model (VLM) for a structured summary, and sends alerts via MQTT or email. The design leans toward reliability: clips land on disk first, state/event writes are best-effort, and non-critical stages can fail without losing the alert.

Highlights

  • Bring your own input: RTSP motion detection, FTP uploads, or a watched folder
  • Parallel upload + filter (YOLOv8) with frame sampling and early exit
  • OpenAI-compatible VLM analysis with structured output
  • Policy-driven alerts with per-camera overrides
  • Fan-out notifiers (MQTT for Home Assistant, SendGrid email)
  • Postgres-backed state + events with graceful degradation
  • Health endpoint plus optional Postgres telemetry logging

Pipeline at a glance

ClipSource -> (Upload + Filter) -> VLM (optional) -> Alert Policy -> Notifier(s)
  • Upload and filter run in parallel; VLM runs only when trigger classes are detected.
  • Upload failures do not block alerts; filter failures stop processing.
  • State is stored in Postgres (clip_states + clip_events) when available.

Quickstart

Requirements

  • Python 3.10+ (newest available is best; 3.14 is fine if your deps support it)
  • ffmpeg in PATH (required for RTSP source)
  • Postgres for state/events (make db-up starts a local instance). The pipeline continues if the DB is down, but a DSN is still required.
  • Optional: MQTT broker, Dropbox credentials, OpenAI-compatible API key

Setup

  1. Install dependencies: uv sync
  2. Create a config file:
    • Start from config/example.yaml or config/sample.yaml
  3. Set environment variables (use .env.example as a template): cp .env.example .env
  4. Start Postgres: make db-up
  5. Validate config: uv run python -m homesec.cli validate --config config/example.yaml
  6. Run: uv run python -m homesec.cli run --config config/example.yaml --log_level INFO

Tip: make homesec loads .env and runs config/production.yaml.

Configuration

Configs are YAML and validated with Pydantic. Start with any file in config/.

Minimal example (RTSP + Dropbox + MQTT):

version: 1

cameras:
  - name: front_door
    source:
      type: rtsp
      config:
        rtsp_url_env: FRONT_DOOR_RTSP_URL
        output_dir: "./recordings"

storage:
  backend: dropbox
  dropbox:
    root: "/homecam"
    token_env: DROPBOX_TOKEN
    app_key_env: DROPBOX_APP_KEY
    app_secret_env: DROPBOX_APP_SECRET
    refresh_token_env: DROPBOX_REFRESH_TOKEN

state_store:
  dsn_env: DB_DSN

notifiers:
  - backend: mqtt
    config:
      host: "localhost"
      port: 1883

filter:
  plugin: yolo
  config:
    classes: ["person"]
    min_confidence: 0.5

vlm:
  backend: openai
  llm:
    api_key_env: OPENAI_API_KEY
    model: gpt-4o

alert_policy:
  backend: default
  enabled: true
  config:
    min_risk_level: medium

per_camera_alert:
  front_door:
    min_risk_level: low
    notify_on_activity_types: ["person_at_door", "delivery"]

A few things worth knowing:

  • Secrets never go in YAML. Use env var names (*_env) and set values in your shell or .env.
  • At least one notifier must be enabled (mqtt or sendgrid_email).
  • Built-in YOLO classes: person, bird, cat, dog, horse, sheep, cow, elephant, bear, zebra, giraffe.
  • Local storage for development:
storage:
  backend: local
  local:
    root: "./storage"
  • Set alert_policy.enabled: false to disable notifications (a noop policy is used).
  • For a quick local run, pair local_folder with local storage and drop a clip into recordings/.

CLI

  • Run the pipeline: uv run python -m homesec.cli run --config config/example.yaml --log_level INFO
  • Validate config: uv run python -m homesec.cli validate --config config/example.yaml
  • Cleanup (reanalyze and optionally delete empty clips): uv run python -m homesec.cli cleanup --config config/example.yaml --older_than_days 7 --dry_run True

Built-in plugins

  • Filters: yolo
  • VLM analyzers: openai (OpenAI-compatible API)
  • Storage: dropbox, local
  • Notifiers: mqtt, sendgrid_email
  • Alert policies: default, noop

Writing a plugin

HomeSec discovers plugins via entry points in the homesec.plugins group. A plugin module just needs to import and register itself.

# my_package/filters/custom.py
from pydantic import BaseModel
from homesec.interfaces import ObjectFilter
from homesec.plugins.filters import FilterPlugin, filter_plugin

class CustomConfig(BaseModel):
    threshold: float = 0.5

class CustomFilter(ObjectFilter):
    ...

@filter_plugin(name="custom")
def register() -> FilterPlugin:
    return FilterPlugin(
        name="custom",
        config_model=CustomConfig,
        factory=lambda cfg: CustomFilter(cfg),
    )
# pyproject.toml
[project.entry-points."homesec.plugins"]
my_filters = "my_package.filters.custom"

Observability

  • Health endpoint: GET /health (configurable in health.host/health.port)
  • Optional telemetry logs to Postgres when DB_DSN is set:
    • Start local DB: make db-up
    • Run migrations: make db-migrate

Development

  • Run tests: make test
  • Run type checking (strict): make typecheck
  • Run both: make check
  • Tests must include Given/When/Then comments.
  • Architecture notes: DESIGN.md

License

Apache 2.0. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

homesec-0.1.0.tar.gz (380.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

homesec-0.1.0-py3-none-any.whl (106.6 kB view details)

Uploaded Python 3

File details

Details for the file homesec-0.1.0.tar.gz.

File metadata

  • Download URL: homesec-0.1.0.tar.gz
  • Upload date:
  • Size: 380.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for homesec-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f2eb8c7a0e954073c2fb1172e59912da468972ab6aed986fa4751ac6c26fd543
MD5 f6adb9b58f06963c2d4e494985d91dd2
BLAKE2b-256 45584b46273a4f480588d366abe21e03fba67d289752854caafb7b17b5bb4bb6

See more details on using hashes here.

File details

Details for the file homesec-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: homesec-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 106.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for homesec-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bca5c1b5e22eb84009ac06dcc456cf453cc90abedff18b1470532377a44da7e1
MD5 b4db1ffd25c763a1c80d6f5a45bda9e0
BLAKE2b-256 5698a9d8ee2c3674d67616b5bc41916ae05a0a7e7e42aedefc8c9e9a7a576928

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page