Veilix HomeWatch

Technical overview

How HomeWatch is built, and why.

For the technically curious: the design decisions and tradeoffs behind HomeWatch. Three parts: self-hosted ML on a Raspberry Pi 5 inside the camera, a SwiftUI iPhone app, and Veilix Connect, our open-source remote access layer.

Last updated October 6, 2026

Local-first, on purpose

The core decision is that video never needs to leave the house to be useful. Detection happens on the Pi, alerts are created on the phone, and clips are stored on the phone. That removes a whole class of risk (a company server holding everyone’s footage) and means the system keeps working on your home network even if the internet is down.

The tradeoff is that there’s no cloud backup, and viewing away from home needs a way to reach a device behind your router without opening ports. That’s what Veilix Connect does (below).

Self-hosted ML

  • Motion first. Each frame is blurred, compared with the previous one, and checked for a changed area above a size threshold. Only frames with real movement go further, which keeps the CPU free when nothing is happening.
  • Then an object detector. Frames with motion go to MobileNet SSD, a compact neural network run through OpenCV’s DNN module. Its classes are grouped into categories: people; vehicles (car, bus, motorbike, bicycle, train); and animals (cat, dog, bird, horse, sheep, cow). Detections below 50% confidence are ignored. More categories ship as model updates.
  • Rate limits. Inference runs at most about once a second, and each category has a five-second cooldown so one visitor doesn’t produce a burst of events.
  • Snapshots off the hot path. Saving a snapshot image is slow enough to stall detection, so a separate writer thread handles it from a small queue and drops frames rather than block.

Getting events and video to the phone

  • Server-sent events for detections. Detections only flow one way, Pi to phone, so a long-lived HTTPS response the server writes lines into was simpler than WebSockets and easy to debug. Events are also saved to a small SQLite database on the Pi, capped at the latest 1,000.
  • MJPEG on the home network. A stream of JPEG frames is simple to serve and renders in a standard web view. It uses more bandwidth than H.264, which is fine on Wi-Fi; remote viewing uses WebRTC instead (below).
  • Stream overlay. The Pi stamps the time and its CPU temperature on the video, which helps keep an eye on heat when the Pi is sealed in an outdoor enclosure.

The iPhone app

  • SwiftUI and SwiftData, targeting iOS 17.2 and later. Per-camera keys live in the Keychain.
  • Each paired camera gets its own session: an event stream, a health check every 15 seconds, and its own recorder, so several cameras can alert and record independently.
  • Alert rules match on camera, detection type and a per-day schedule. Cooldowns stop a lingering visitor from triggering a notification every few seconds.
  • Clips are built from the live view: the app captures frames at about five per second and encodes them to H.264 with AVFoundation. It’s simple and works with the MJPEG stream, but frame rate is limited.

Pairing

Pairing uses either a 6-digit PIN that can only be generated on the Pi itself, or a one-time QR token that the Pi only shows to local addresses. Both expire after five minutes. A successful pairing issues a per-device API key and stream token (stored on the Pi only as SHA-256 hashes), so one phone can be revoked without affecting the others. Pairing also exchanges each side’s public keys for Veilix Connect.

Veilix Connect: remote access

  • WebRTC, not a VPN. iOS allows one VPN at a time, so a VPN-based design would clash with work VPNs. WebRTC gives NAT traversal (ICE/STUN/TURN), DTLS-SRTP encryption and H.264 video.
  • Signed, encrypted signaling. Camera and phone each hold an Ed25519 signing key and an X25519 key. Every setup message is encrypted (ChaCha20-Poly1305) and signed, and the WebRTC certificate fingerprints ride inside it, so the signaling server can’t read, alter or man-in-the-middle a session.
  • Outbound only. The camera dials out to the signaling server; nothing on your network accepts connections from the internet. On the home network the phone skips the server entirely.
  • The whole API, not just video. Events, snapshots and settings ride a WebRTC data channel, proxied to the camera’s local API through an allowlist.
  • Open source. The server is AGPL-3.0; the camera agent and iOS package are Apache-2.0. Self-hosting is a docker compose file. Prefer your own tunnel? Tailscale works too.

Alerts with the app closed

The camera encrypts each alert for the phone it’s going to and hands the ciphertext to a small push relay, which forwards it to Apple’s push service. A notification extension on the phone decrypts it, so neither the relay nor Apple sees what the camera detected.

Design tradeoffs

  • The Raspberry Pi 5 has no hardware H.264 encoder, so encoding shares the CPU with detection.
  • Clips recorded from the MJPEG view run at about 5 frames per second.
  • No cloud backup, by design: if you lose your phone, clips on it go with it.

How it was built

HomeWatch is an independent project by Veilix Labs LLC. The software was written with AI-assisted development, with the design, testing on real hardware, and product decisions done by its builder.