Skip to content

edycutjong/scarecrow

Repository files navigation

πŸ§‘β€βš–οΈ For Judges

The pitch (30s): A $50 off-grid Raspberry Pi that understands a scene and reasons about a plain-English rule β€” "alert if a person is near the shed, ignore the dog" β€” then speaks the alert and pushes it to a phone. Fully offline, ≀4GB RAM, solar-powered. Not motion detection β€” multimodal reasoning on the edge.

Run it in 30 seconds (works on any laptop, no Pi needed):

npm install && npm start      # β†’ open http://localhost:8080

The dashboard shows the live pipeline, camera HUD, rule editor, and event log. Add a rule or "teach" a known entity right from the UI.

Where to look:

Judging signal Where Status
Deep QVAC integration (5 distinct APIs) completion + multimodal, ragSearch, textToSpeech, startQVACProvider β€” see Why ONLY QVAC βœ… real @qvac/sdk v0.10.2
Capability unlock (RAG known-entity recall) src/core/memory.ts β€” your car/pet won't trip it, a stranger will βœ…
≀4GB on retail hardware /api/status reports real measured RSS; single-model loadβ†’inferβ†’unload βœ… measured, not faked
True offline python3 scripts/verify_offline.py β€” static cloud-import/URL scan + live network probe βœ…
Production quality npm test β†’ 128 unit tests; npm run ci (lint + types + coverage) βœ…
Reproducible classification python3 scripts/bench.py β†’ real precision/recall of the offline baseline over 233 labeled scenes βœ…

Mandatory constraints β€” all met: 100% on-device inference through @qvac/sdk (zero cloud APIs β€” the hard disqualifier; every interface declared in docs/REMOTE_APIS.md), MIT licensed and fully public, BYOH consumer hardware (Pi 4/5), reproducible via scripts/setup-pi.sh.

Evidence bundle: remote-API declaration (docs/REMOTE_APIS.md β€” zero cloud APIs) Β· structured inference audit log (GET /api/audit β€” model loads/unloads, TTFT, tokens/sec) Β· offline scan + live network probe (verify_offline.py) Β· real classification baseline over 233 labeled scenes (bench.py) Β· append-only event log (data/events.jsonl) Β· readiness gate (check_submission_readiness.py) Β· physical demo runbook (DEMO.md). Model latency, peak RAM, and mWh/event are captured on-device (see Benchmarks) β€” not simulated.

Radical honesty: nothing fake is shown as real. The RAM gauge is measured process RSS (tagged RSS); battery/solar are modelled and clearly tagged SIM in the UI until an INA219 sensor is wired (SCARECROW_BATTERY_PCT/SCARECROW_SOLAR_W). Camera capture uses real libcamera-still on the Pi. See Honest Limitations.


Scarecrow Logo

Scarecrow πŸ”Œ

$50 off-grid AI sentry on a Raspberry Pi ≀4GB. Camera β†’ multimodal scene understanding β†’ natural-language rule matching β†’ spoken TTS alerts. Solar/battery powered, fully offline.

Scarecrow Hero

Built for QVAC Hackathon Track


Node.js TypeScript Raspberry Pi QVAC CI


πŸ‘€ See It Work

πŸ“Ί Watch the full demo on YouTube

What the camera sees (test clip)

Person approaching the shed at dusk

A person in dark clothing approaching the shed at dusk.

What Scarecrow does (real dashboard)

Scarecrow dashboard raising a real alert

πŸ”΄ Reasons about the scene β†’ THREAT DETECTED β†’ speaks the alert β†’ logs it.

A dog crossing the yard past the shed

A dog trotting across the same yard.

Scarecrow seeing the dog and staying silent

βœ… Sees the dog (green box, 0.88) β†’ matches the ignore rule β†’ PERIMETER CLEAR, no alert.

Known-entity recall (on-device RAG)

An unfamiliar dark van in the driveway

An unfamiliar dark van…

The owner's silver truck

…vs. your silver truck (taught once).

Scarecrow alerting on the van but recognizing the known truck

The van trips a πŸ”΄ ALERT; the silver truck is recognised and the alert is suppressed β€” "🧩 Recognised known entity: My silver truck." Teach it once; a stranger's vehicle still alerts.

This is reasoning, not motion detection. Same yard, same camera β€” Scarecrow alerts on the person and stays silent for the dog because it understands the scene against your plain-English rules. The scene clips are stimulus (yours / licensed stock / AI-generated); the dashboard, spoken alert, and RAM gauge are the real system on-device. Open it yourself with npm start.


πŸ’‘ The Problem & Solution

Traditional security cameras need WiFi, cloud subscriptions, and constant power. In farms, construction sites, and remote properties, none of these are available.

Scarecrow turns a $50 Raspberry Pi into an intelligent sentry that understands what it sees:

Key Features:

  • πŸ“Έ Vision AI β€” QVAC-Vision-1B analyzes camera frames locally
  • πŸ”’ NL Rules β€” Plain English rules: "alert if person near shed, ignore dogs"
  • 🧩 Known-Entity Recall β€” on-device RAG remembers your car/pet/mail carrier and suppresses false alarms
  • πŸ”Š Spoken Alerts β€” Piper TTS announces threats through a speaker
  • πŸ“² P2P Phone Push β€” alerts a paired phone over the LAN, no cloud
  • β˜€οΈ Solar Powered β€” PIR-triggered wake with configurable sleep intervals
  • πŸ–₯️ Pi Dashboard β€” live web UI + rule editor served from Pi's hotspot

πŸ—οΈ Architecture & Tech Stack

flowchart TD
    A["⚑ PIR Wake"] --> B["πŸ“Έ Camera"]
    B --> C["🧠 QVAC-Vision-1B"]
    C --> D["πŸ“ Scene Description"]
    D --> E["πŸ”’ Llama 3.2 1B Rules"]
    E --> F{"Alert?"}
    F -- Yes --> K{"🧩 Known entity? (RAG)"}
    F -- No --> H["πŸ’€ Sleep"]
    K -- Known --> H
    K -- Unknown --> G["πŸ”Š Piper TTS + πŸ“² P2P Push"]
    G --> I["πŸ“Š Event Log + Dashboard"]
    I --> H
    H --> A
Loading
Layer Technology
Runtime Node.js on Raspberry Pi 4/5
AI Engine @qvac/sdk (completion, multimodal, RAG, TTS, P2P)
Vision QVAC-Vision-1B (multimodal)
Rules Llama 3.2 1B (NL evaluation)
Known entities GTE-Large embeddings (on-device RAG)
TTS Piper via @qvac/sdk
Alerts Holepunch-backed P2P phone push
Dashboard Vanilla HTML/JS (Pi hotspot)

πŸ’° Hardware BOM (~$50)

Part Cost
Raspberry Pi 4 (2GB/4GB) ~$35
Pi Camera Module v2 ~$10
USB Speaker ~$5
PIR Motion Sensor (HC-SR501) ~$2
Solar panel + battery (optional) ~$15

πŸ”Œ Wiring

        β˜€ Solar ──▢ [ Solar + UPS HAT ] ◀──▢ πŸ”‹ 18650 Li-ion
                           β”‚ 5V / 3A (USB-C)
                           β–Ό
   πŸ“· Camera ──CSI ribbon──▢ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” ◀── USB ── πŸ”Š Speaker
                            β”‚  Raspberry Pi  β”‚            (spoken alerts)
   πŸ‘ HC-SR501 PIR ──GPIO17──▢│    4 (≀4GB)    β”‚
                            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        (VCC→5V · OUT→GPIO17 · GND→GND — see table)
Wire Pi connection Phys. pin BCM
PIR VCC 5V 2 β€”
PIR OUT GPIO17 11 17 (matches gpio.ts)
PIR GND GND 6 β€”
Camera CSI camera port ribbon β€”
Speaker USB-A β€” β€”
Power in USB-C 5V/3A β€” β€”

The PIR is the power-aware wake source β€” the Pi sleeps until motion, then wakes β†’ captures β†’ infers β†’ sleeps. Change the pin via startPIRSentry({ pin }). Solar/battery is optional; any 5V/3A USB-C supply works for a wall-powered build.

πŸ† Why ONLY QVAC?

QVAC SDK Method Scarecrow Usage Cloud Alternative You'd Need
loadModel(QVAC_VISION_1B) Multimodal scene analysis from camera frames Google Cloud Vision API
completion() + images Describe what the camera sees in natural language GPT-4 Vision
completion() (Llama 1B) NL rule evaluation: "alert if person near shed" OpenAI API
ragIngest() / ragSearch() Recognize known-friendly entities, suppress false alarms Pinecone + embeddings API
textToSpeech() (Piper) Spoken alerts when rules match Amazon Polly
startQVACProvider() (P2P) Push alerts to a paired phone over the LAN Firebase Cloud Messaging
unloadModel() Critical β€” free RAM between model swaps on 4GB Pi N/A

Take QVAC out and you'd need 5+ cloud services (Google Vision + OpenAI + Pinecone + Amazon Polly + Firebase), a WiFi router, and a power outlet β€” destroying the entire $50 off-grid premise.

πŸš€ Getting Started

git clone https://github.com/edycutjong/scarecrow.git
cd scarecrow
npm install
python3 scripts/seed.py

# Start the sentry loop AND serve the live dashboard over the Pi hotspot
npm start                 # β†’ http://192.168.4.1:8080 (PORT env to override)

# Sentry loop only, no dashboard (headless)
npm run sentry

The dashboard polls a tiny zero-dependency HTTP API (node:http) for live data:

Endpoint Returns
GET / Live dashboard (camera HUD, pipeline, rules, events)
GET /api/status Stage, RAM, battery, solar, frames, armed state
GET /api/events Event log from the sentry loop
GET /api/rules Β· POST Β· DELETE /api/rules/:id List / add / remove natural-language rules
GET /api/entities Β· POST Β· DELETE /api/entities/:id List / teach / forget known-friendly entities
GET /api/audit Structured inference audit log + summary (model loads/unloads, TTFT, tokens/sec)
GET /api/health Liveness probe

Opened directly as a file (open src/web/index.html) the dashboard runs in a self-contained simulation; pointed at the API it switches to LIVE mode automatically β€” and the rule/entity editors become live. On an alert, a P2P phone push is sent via @qvac/sdk (src/core/p2p.ts).

🧩 Known-entity allow-list (on-device RAG)

Teach Scarecrow what to ignore β€” "my silver truck," "the mail carrier," "my dog Max." Before raising an alert, src/core/memory.ts runs an on-device semantic search (ragIngest/ragSearch, GTE-Large embeddings) against the scene; a match above threshold suppresses the alert. This is reasoning, not a blocklist: the owner's car pulling in won't trip it, but a stranger's will.

πŸ”Œ Power modes

Command Behaviour
npm start Dashboard + fixed-interval sentry loop
npm run sentry Headless fixed-interval loop
PIR mode (startPIRSentry, src/core/gpio.ts) Sleep β†’ motion-triggered wake β†’ check β†’ sleep (solar-optimal)

Events are persisted append-only to data/events.jsonl (src/core/storage.ts) and restored on boot β€” a zero-dependency, inspectable offline evidence trail.

Honest telemetry. /api/status reports real measured process RSS for the RAM gauge (process.memoryUsage().rss, tagged RSS in the UI). Battery/solar are modelled and tagged SIM on the dashboard until a real sensor is wired β€” export SCARECROW_BATTERY_PCT / SCARECROW_SOLAR_W (e.g. from an INA219 daemon) and the values go live with powerSimulated: false.

πŸ“ Provisioning a Pi

bash scripts/setup-pi.sh        # camera, audio, Node, deps
bash scripts/setup-pi.sh --ap   # also configure the Scarecrow-AP hotspot

πŸ“Š Benchmarks

Classification quality (real, reproducible anywhere β€” python3 scripts/bench.py). Precision/recall of the documented offline keyword-fallback baseline over the 233 labeled fixture scenes β€” the floor the Llama 3.2 1B engine improves on:

Baseline metric Value
Precision 0.67
Recall 0.43
F1 0.52
Accuracy 0.73 (169/233)

The modest recall is the point: a keyword baseline misses non-"person" alerts (vehicles, etc.), which is exactly why on-device LLM reasoning is used. The Llama model's real precision/recall is measured on-device (needs the model).

Latency Β· RAM Β· power β€” measured on the Pi, not simulated. These depend on the QVAC models and physical rig, so they are captured on-device (the dashboard /api/status reports live RSS; htop/vcgencmd for memory; INA219 for mWh/event). Targets for Raspberry Pi 4 (4GB):

Stage Target
Vision analysis (1 frame) < 4,000 ms
Rule evaluation < 2,000 ms
TTS alert < 2,000 ms
Full pipeline < 8,000 ms
Peak RAM < 3,800 MB (≀4GB constraint)

These are budgets, not measurements β€” fill them from a real Pi run for the submission. The benchmark script never fabricates device numbers.

πŸ§ͺ Testing & CI

128 unit tests (vision, rules + live editing + real fallback classification over the 233-scene fixture set, power state machine, telemetry, inference audit log, RAG known-entity recognition, P2P phone alerts, PIR wake, JSONL persistence, dashboard API) + offline verification scan + readiness suite. Run npm test. (Tests mock only the @qvac/sdk/hardware boundary; every assertion exercises real project logic β€” no tautological label-fed tests.)

4-stage pipeline: Quality β†’ Security β†’ Offline Verify β†’ Deploy

python3 scripts/verify_offline.py
python3 scripts/bench.py
python3 scripts/check_submission_readiness.py
Layer Tool Status
Code Quality ESLint + TypeScript βœ…
Security (SAST) CodeQL βœ…
Dependency Audit (SCA) npm audit + Dependabot βœ…
Secret Scanning TruffleHog βœ…
Offline Verification verify_offline.py (cloud-import/URL scan + net probe) βœ…

πŸ“ Project Structure

scarecrow/
β”œβ”€β”€ docs/               # README assets
β”œβ”€β”€ data/fixtures/      # test_rules.json, test_scenes.json
β”œβ”€β”€ scripts/            # setup-pi, seed, bench, verify, readiness
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ core/
β”‚   β”‚   β”œβ”€β”€ qvac.ts     # @qvac/sdk wrapper
β”‚   β”‚   β”œβ”€β”€ vision.ts   # Camera + multimodal analysis
β”‚   β”‚   β”œβ”€β”€ rules.ts    # NL rule engine + add/remove
β”‚   β”‚   β”œβ”€β”€ memory.ts   # RAG known-entity allow-list (ragSearch)
β”‚   β”‚   β”œβ”€β”€ power.ts    # Sentry loop + live telemetry (getSystemStatus)
β”‚   β”‚   β”œβ”€β”€ gpio.ts     # PIR motion-wake source
β”‚   β”‚   β”œβ”€β”€ storage.ts  # Append-only JSONL event persistence
β”‚   β”‚   β”œβ”€β”€ p2p.ts      # P2P phone push alerts on match
β”‚   β”‚   └── audit.ts    # Structured inference audit log (loads/unloads, TTFT, tok/s)
β”‚   └── web/
β”‚       β”œβ”€β”€ server.ts   # Dashboard HTTP server + JSON API (node:http)
β”‚       └── index.html  # Live dashboard + rule/entity editor (Pi hotspot)
β”œβ”€β”€ .github/            # CI/CD + CodeQL + Dependabot
└── README.md

⚠️ Honest Limitations

  1. Camera capture simulated in dev (real Pi Camera required)
  2. PIR wake uses the onoff GPIO binding on the Pi; dev/CI run a simulated motion source
  3. Battery/solar are modelled (tagged SIM in the UI) until an INA219 sensor feeds SCARECROW_BATTERY_PCT/SCARECROW_SOLAR_W; the RAM gauge is real measured RSS
  4. Event log persists to append-only JSONL; a queryable SQLite store is future work
  5. Single-model-at-a-time due to 4GB constraint
  6. English rules only

πŸ“„ License

MIT Β© 2026 Edy Cu

πŸ™ Acknowledgments

Built for QVAC Hackathon I β€” Unleash Edge AI (DoraHacks). Proving that useful AI doesn't need the cloud β€” just a $50 Pi and QVAC.

About

πŸ”Œ Off-grid AI sentry: vision + rules + spoken alerts on a Raspberry Pi ≀4GB

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors