oak-events 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- oak_events-0.1.1/.github/ISSUE_TEMPLATE/bug.yml +50 -0
- oak_events-0.1.1/.github/ISSUE_TEMPLATE/feature.yml +29 -0
- oak_events-0.1.1/.github/workflows/ci.yml +37 -0
- oak_events-0.1.1/.github/workflows/release.yml +40 -0
- oak_events-0.1.1/.gitignore +29 -0
- oak_events-0.1.1/CHANGELOG.md +35 -0
- oak_events-0.1.1/CODE_OF_CONDUCT.md +16 -0
- oak_events-0.1.1/CONTRIBUTING.md +44 -0
- oak_events-0.1.1/LICENSE +21 -0
- oak_events-0.1.1/PKG-INFO +216 -0
- oak_events-0.1.1/README.md +192 -0
- oak_events-0.1.1/SECURITY.md +26 -0
- oak_events-0.1.1/examples/claude-desktop-mcp.json +8 -0
- oak_events-0.1.1/examples/openclaw-stream.md +28 -0
- oak_events-0.1.1/examples/webhook.md +28 -0
- oak_events-0.1.1/examples/zones.example.json +7 -0
- oak_events-0.1.1/pyproject.toml +39 -0
- oak_events-0.1.1/server.json +33 -0
- oak_events-0.1.1/src/oak_events/__init__.py +8 -0
- oak_events-0.1.1/src/oak_events/__main__.py +5 -0
- oak_events-0.1.1/src/oak_events/camera.py +203 -0
- oak_events-0.1.1/src/oak_events/cli.py +178 -0
- oak_events-0.1.1/src/oak_events/events.py +309 -0
- oak_events-0.1.1/src/oak_events/mcp_server.py +182 -0
- oak_events-0.1.1/src/oak_events/privacy.py +56 -0
- oak_events-0.1.1/src/oak_events/sink.py +67 -0
- oak_events-0.1.1/tests/conftest.py +33 -0
- oak_events-0.1.1/tests/test_cli.py +60 -0
- oak_events-0.1.1/tests/test_depth_change.py +153 -0
- oak_events-0.1.1/tests/test_mcp_tools.py +67 -0
- oak_events-0.1.1/tests/test_no_images.py +64 -0
- oak_events-0.1.1/tests/test_person_tracker.py +93 -0
- oak_events-0.1.1/tests/test_privacy.py +78 -0
- oak_events-0.1.1/tests/test_sink.py +56 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Something does not work as documented
|
|
3
|
+
labels: [bug]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Thanks for the report. Please do **not** attach camera images, depth maps,
|
|
9
|
+
IP addresses, hostnames or device ids. Event lines are fine once you have
|
|
10
|
+
removed anything you consider private.
|
|
11
|
+
Security issues: use a private security advisory instead (see SECURITY.md).
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: what
|
|
14
|
+
attributes:
|
|
15
|
+
label: What happened
|
|
16
|
+
description: What you ran, what you expected, what you got.
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
- type: textarea
|
|
20
|
+
id: doctor
|
|
21
|
+
attributes:
|
|
22
|
+
label: oak-events doctor output
|
|
23
|
+
description: Output of `oak-events doctor` (redact device ids if you like).
|
|
24
|
+
render: text
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
27
|
+
- type: dropdown
|
|
28
|
+
id: hardware
|
|
29
|
+
attributes:
|
|
30
|
+
label: Camera
|
|
31
|
+
options:
|
|
32
|
+
- OAK-D (USB, RVC2)
|
|
33
|
+
- OAK-D PoE (RVC2)
|
|
34
|
+
- Other RVC2
|
|
35
|
+
- RVC4
|
|
36
|
+
- No camera (logic / MCP / CLI issue)
|
|
37
|
+
validations:
|
|
38
|
+
required: true
|
|
39
|
+
- type: input
|
|
40
|
+
id: os
|
|
41
|
+
attributes:
|
|
42
|
+
label: OS and Python version
|
|
43
|
+
placeholder: e.g. Ubuntu 24.04, Python 3.12
|
|
44
|
+
validations:
|
|
45
|
+
required: true
|
|
46
|
+
- type: textarea
|
|
47
|
+
id: events
|
|
48
|
+
attributes:
|
|
49
|
+
label: Relevant event lines or logs
|
|
50
|
+
render: text
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest a new event kind, tool or integration
|
|
3
|
+
labels: [enhancement]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
oak-events has one hard rule: no pictures leave the camera. Features that
|
|
9
|
+
would send or store frames (snapshots, thumbnails, crops, video) are out of
|
|
10
|
+
scope.
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: problem
|
|
13
|
+
attributes:
|
|
14
|
+
label: What do you want an agent to know?
|
|
15
|
+
description: The question the event or tool should answer.
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: textarea
|
|
19
|
+
id: proposal
|
|
20
|
+
attributes:
|
|
21
|
+
label: Proposed event / tool
|
|
22
|
+
description: Event kind and fields, or tool name and output.
|
|
23
|
+
- type: checkboxes
|
|
24
|
+
id: privacy
|
|
25
|
+
attributes:
|
|
26
|
+
label: Privacy
|
|
27
|
+
options:
|
|
28
|
+
- label: This feature works from detections and/or coarse depth only, without frames reaching the host.
|
|
29
|
+
required: true
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
test:
|
|
13
|
+
name: pytest (${{ matrix.os }}, Python ${{ matrix.python }})
|
|
14
|
+
runs-on: ${{ matrix.os }}
|
|
15
|
+
strategy:
|
|
16
|
+
fail-fast: false
|
|
17
|
+
matrix:
|
|
18
|
+
os: [ubuntu-latest, macos-latest]
|
|
19
|
+
python: ["3.11", "3.13"]
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
- uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: ${{ matrix.python }}
|
|
25
|
+
# Deliberately without the [camera] extra: tests must pass with no depthai and no camera.
|
|
26
|
+
- name: Install
|
|
27
|
+
run: |
|
|
28
|
+
python -m pip install --upgrade pip
|
|
29
|
+
python -m pip install -e '.[mcp]' pytest
|
|
30
|
+
- name: depthai must be absent
|
|
31
|
+
run: python -c "import importlib.util, sys; sys.exit(importlib.util.find_spec('depthai') is not None)"
|
|
32
|
+
- name: Test
|
|
33
|
+
run: python -m pytest -q
|
|
34
|
+
- name: CLI smoke
|
|
35
|
+
run: |
|
|
36
|
+
oak-events --help
|
|
37
|
+
oak-events doctor
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
build:
|
|
12
|
+
name: build sdist and wheel
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.13"
|
|
19
|
+
- name: Build
|
|
20
|
+
run: |
|
|
21
|
+
python -m pip install --upgrade pip build
|
|
22
|
+
python -m build
|
|
23
|
+
- uses: actions/upload-artifact@v4
|
|
24
|
+
with:
|
|
25
|
+
name: dist
|
|
26
|
+
path: dist/
|
|
27
|
+
|
|
28
|
+
publish:
|
|
29
|
+
name: publish to PyPI
|
|
30
|
+
needs: build
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
environment: pypi
|
|
33
|
+
permissions:
|
|
34
|
+
id-token: write
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/download-artifact@v4
|
|
37
|
+
with:
|
|
38
|
+
name: dist
|
|
39
|
+
path: dist/
|
|
40
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
.venv/
|
|
3
|
+
venv/
|
|
4
|
+
__pycache__/
|
|
5
|
+
*.py[cod]
|
|
6
|
+
*.egg-info/
|
|
7
|
+
build/
|
|
8
|
+
dist/
|
|
9
|
+
.pytest_cache/
|
|
10
|
+
.coverage
|
|
11
|
+
htmlcov/
|
|
12
|
+
|
|
13
|
+
# Local run output and models (never commit camera output or model archives)
|
|
14
|
+
/events/
|
|
15
|
+
/models/
|
|
16
|
+
*.tar.xz
|
|
17
|
+
*.blob
|
|
18
|
+
|
|
19
|
+
# oak-events never writes pictures; keep any stray ones out of git too
|
|
20
|
+
*.jpg
|
|
21
|
+
*.jpeg
|
|
22
|
+
*.png
|
|
23
|
+
*.bmp
|
|
24
|
+
*.npy
|
|
25
|
+
|
|
26
|
+
# OS / editors
|
|
27
|
+
.DS_Store
|
|
28
|
+
.idea/
|
|
29
|
+
.vscode/
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses
|
|
5
|
+
[Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [0.1.1] - 2026-10-12
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Repository moved to [cloudlabworks/oak-events](https://github.com/cloudlabworks/oak-events);
|
|
12
|
+
the MCP registry name is now `io.github.cloudlabworks/oak-events`. Old
|
|
13
|
+
`issaquahd/oak-events` links redirect.
|
|
14
|
+
- First release published to PyPI (trusted publishing).
|
|
15
|
+
|
|
16
|
+
## [0.1.0] - 2026-10-11
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- `oak-events run`: DepthAI v3 pipeline (spatial detection network + stereo
|
|
21
|
+
depth) emitting JSON-line events; only detections and depth reach the host.
|
|
22
|
+
- Events: `person_enter`, `person_exit`, `depth_baseline`, `depth_change`,
|
|
23
|
+
`camera`, `alive`.
|
|
24
|
+
- `PersonTracker` with confirm frames, gone timeout and confidence threshold.
|
|
25
|
+
- `DepthChangeDetector`: coarse depth grid with median/MAD baseline, noisy-cell
|
|
26
|
+
exclusion, hold time, and pause while a person is present.
|
|
27
|
+
- Named zones (normalized box and/or distance range).
|
|
28
|
+
- JSONL sink: stdout and/or one file per local day, atomic appends, mode 0600.
|
|
29
|
+
- `oak-events doctor`: depthai version, devices, bootloader advice (0.0.29 for
|
|
30
|
+
RVC2 PoE), privacy environment; works without depthai.
|
|
31
|
+
- `oak-events mcp`: MCP stdio server with `recent_events`, `zone_state` and
|
|
32
|
+
`camera_health` text tools; reads event files only.
|
|
33
|
+
- Privacy defaults: DepthAI telemetry, crash dumps and auto-calibration off
|
|
34
|
+
unless `OAK_EVENTS_ALLOW_TELEMETRY=1`.
|
|
35
|
+
- Device discovery by id with 90 s retry and DepthAI reconnection.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
This project adopts the **Contributor Covenant, version 2.1**:
|
|
4
|
+
<https://www.contributor-covenant.org/version/2/1/code_of_conduct/>
|
|
5
|
+
|
|
6
|
+
All contributors and maintainers are expected to follow it in every project
|
|
7
|
+
space: issues, pull requests, discussions and any other channel used for the
|
|
8
|
+
project.
|
|
9
|
+
|
|
10
|
+
## Reporting
|
|
11
|
+
|
|
12
|
+
To report unacceptable behaviour, contact the maintainers privately through a
|
|
13
|
+
GitHub security advisory on this repository (**Security** tab, **Report a
|
|
14
|
+
vulnerability**), marking the report as a Code of Conduct matter. Reports are
|
|
15
|
+
handled confidentially. Maintainers will follow the enforcement guidelines in
|
|
16
|
+
the Contributor Covenant 2.1.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Contributing to oak-events
|
|
2
|
+
|
|
3
|
+
Thanks for helping. Bug reports, hardware reports (especially RVC4) and small,
|
|
4
|
+
focused pull requests are all welcome.
|
|
5
|
+
|
|
6
|
+
## The one rule
|
|
7
|
+
|
|
8
|
+
**No pictures leave the camera.** Changes must not:
|
|
9
|
+
|
|
10
|
+
- link a colour, preview or passthrough output to a host queue,
|
|
11
|
+
- write images, depth maps or arrays (`.jpg`, `.png`, `.npy`, ...) to disk,
|
|
12
|
+
- add an MCP tool or event field that carries image data.
|
|
13
|
+
|
|
14
|
+
`tests/test_no_images.py` and the privacy tests enforce part of this; reviewers
|
|
15
|
+
check the rest.
|
|
16
|
+
|
|
17
|
+
## Development setup
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
python3 -m venv .venv
|
|
21
|
+
.venv/bin/pip install -e '.[mcp]' pytest
|
|
22
|
+
.venv/bin/pytest -q
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Tests must pass **without a camera and without `depthai` installed**; that is
|
|
26
|
+
what CI runs (Ubuntu and macOS, Python 3.11 and 3.13). Put event logic in
|
|
27
|
+
`events.py` (pure, testable with synthetic data) and keep `camera.py` a thin
|
|
28
|
+
adapter around DepthAI.
|
|
29
|
+
|
|
30
|
+
If you have hardware, also try `pip install -e '.[camera]'` and
|
|
31
|
+
`oak-events doctor`, then a short `oak-events run`, and mention the device and
|
|
32
|
+
results in your PR.
|
|
33
|
+
|
|
34
|
+
## Pull requests
|
|
35
|
+
|
|
36
|
+
- One change per PR, with tests for new logic.
|
|
37
|
+
- Update `README.md` (event schema table) when you add or change an event.
|
|
38
|
+
- Add a line under "Unreleased" in `CHANGELOG.md`.
|
|
39
|
+
- Do not include device ids, network addresses, hostnames or personal paths in
|
|
40
|
+
code, tests, docs or example output.
|
|
41
|
+
|
|
42
|
+
## Code of conduct
|
|
43
|
+
|
|
44
|
+
This project follows the [Contributor Covenant](CODE_OF_CONDUCT.md).
|
oak_events-0.1.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alex Alvord
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: oak-events
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Privacy-first events from Luxonis OAK cameras for AI agents: JSON lines and an MCP server, never pictures.
|
|
5
|
+
Author: oak-events contributors
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Keywords: agents,computer-vision,depthai,events,luxonis,mcp,oak,privacy
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Operating System :: MacOS
|
|
12
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Topic :: Home Automation
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Image Recognition
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Requires-Dist: numpy
|
|
19
|
+
Provides-Extra: camera
|
|
20
|
+
Requires-Dist: depthai>=3.9; extra == 'camera'
|
|
21
|
+
Provides-Extra: mcp
|
|
22
|
+
Requires-Dist: mcp>=1.0; extra == 'mcp'
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# oak-events
|
|
26
|
+
|
|
27
|
+
Privacy-first events from Luxonis OAK cameras for AI agents.
|
|
28
|
+
|
|
29
|
+
An OAK camera detects people, tracks them and measures depth on its own chip.
|
|
30
|
+
`oak-events` turns that into one JSON line per event ("a person entered the
|
|
31
|
+
doorway zone", "something 40 cm closer has stood in cell r2c5 for a minute")
|
|
32
|
+
and serves those lines to agents through an MCP server.
|
|
33
|
+
|
|
34
|
+
**Agents never receive a picture.** There is no image tool, no snapshot
|
|
35
|
+
command, and no code path that writes an image file.
|
|
36
|
+
|
|
37
|
+
## Why
|
|
38
|
+
|
|
39
|
+
Giving an agent a camera usually means giving it a video feed. Most agent
|
|
40
|
+
questions do not need one: *is anyone at the bench? did something on the shelf
|
|
41
|
+
move? is the camera alive?* Those are answerable from detections and a coarse
|
|
42
|
+
depth grid, which carry far less about the people in view than frames do.
|
|
43
|
+
|
|
44
|
+
## Privacy model
|
|
45
|
+
|
|
46
|
+
Stated plainly, so you can check it against the code:
|
|
47
|
+
|
|
48
|
+
1. **Colour frames stay on the camera.** The colour sensor feeds the on-chip
|
|
49
|
+
detection network. Its frames are never linked to a host output queue.
|
|
50
|
+
Only two streams reach the host: detection results (label, confidence,
|
|
51
|
+
3-D position, normalized box) and the stereo depth map
|
|
52
|
+
(`src/oak_events/camera.py`).
|
|
53
|
+
2. **Depth maps are reduced and dropped.** Each depth frame becomes a grid of
|
|
54
|
+
cell medians (default 6 x 8) in memory, then is discarded. No depth map is
|
|
55
|
+
stored.
|
|
56
|
+
3. **Only JSON lines are written**, to stdout and/or a daily `.jsonl` file.
|
|
57
|
+
A test scans the repo and a temporary run directory for image files.
|
|
58
|
+
4. **DepthAI telemetry, crash-dump upload and auto-calibration are off** by
|
|
59
|
+
default. `oak_events.privacy` forces `DEPTHAI_TELEMETRY=0`,
|
|
60
|
+
`DEPTHAI_DISABLE_CRASHDUMP_COLLECTION=1` and `DEPTHAI_AUTOCALIBRATION=OFF`
|
|
61
|
+
before `depthai` is imported. Only `OAK_EVENTS_ALLOW_TELEMETRY=1` leaves
|
|
62
|
+
DepthAI's own defaults in place.
|
|
63
|
+
5. **The MCP server only reads the JSONL files.** It never opens the camera.
|
|
64
|
+
6. **No model download at runtime.** You point `--model` at a local NNArchive
|
|
65
|
+
you fetched once.
|
|
66
|
+
|
|
67
|
+
What the events still reveal: when someone was present, for how long, how far
|
|
68
|
+
from the camera, and when objects moved. Treat the event files as sensitive
|
|
69
|
+
and keep them local.
|
|
70
|
+
|
|
71
|
+
## Supported hardware
|
|
72
|
+
|
|
73
|
+
| Device | Status |
|
|
74
|
+
| --- | --- |
|
|
75
|
+
| RVC2: OAK-D PoE | Tested live (DepthAI 3.11, bootloader 0.0.29, macOS arm64) |
|
|
76
|
+
| RVC2: OAK-D (USB) | Expected to work; untested, reports welcome |
|
|
77
|
+
| RVC4 (e.g. OAK 4) | Untested; reports welcome |
|
|
78
|
+
|
|
79
|
+
Requires DepthAI v3 (`depthai>=3.9`) and Python 3.10+.
|
|
80
|
+
|
|
81
|
+
## Quickstart
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Not on PyPI yet: install the v0.1.0 release from GitHub
|
|
85
|
+
pip install 'oak-events[camera,mcp] @ git+https://github.com/cloudlabworks/oak-events@v0.1.0'
|
|
86
|
+
|
|
87
|
+
# 1. Check the setup (works without a camera or depthai installed)
|
|
88
|
+
oak-events doctor
|
|
89
|
+
|
|
90
|
+
# 2. Fetch a detection model ONCE (see below), then run
|
|
91
|
+
oak-events run --model ~/models/yolov6-nano.rvc2.tar.xz --out-dir ~/.local/share/oak-events/events
|
|
92
|
+
|
|
93
|
+
# 3. Let an agent read the events over MCP
|
|
94
|
+
oak-events mcp --events-dir ~/.local/share/oak-events/events
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Fetching a model once
|
|
98
|
+
|
|
99
|
+
`oak-events` never downloads at runtime. Fetch an NNArchive from the Luxonis
|
|
100
|
+
model zoo once, with DepthAI itself, and keep the file:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
import depthai as dai
|
|
104
|
+
|
|
105
|
+
path = dai.getModelFromZoo(
|
|
106
|
+
dai.NNModelDescription(model="luxonis/yolov6-nano:r2-coco-512x288", platform="RVC2")
|
|
107
|
+
)
|
|
108
|
+
print(path) # copy this .tar.xz somewhere stable and pass it to --model
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
This one step contacts the Luxonis model hub. Check the exact model slug on the
|
|
112
|
+
Luxonis model zoo; any detection NNArchive whose classes include `person`
|
|
113
|
+
works (use `--person-label` if the class has another name). For RVC4, use
|
|
114
|
+
`platform="RVC4"`.
|
|
115
|
+
|
|
116
|
+
### Zones
|
|
117
|
+
|
|
118
|
+
By default everything is reported for one zone named `view`. A zones file
|
|
119
|
+
names regions by normalized image box and/or distance:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{"zones": [
|
|
123
|
+
{"name": "doorway", "bbox": [0.0, 0.0, 0.35, 1.0]},
|
|
124
|
+
{"name": "desk", "bbox": [0.4, 0.3, 1.0, 1.0], "z_mm": [400, 2500]}
|
|
125
|
+
]}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
`bbox` is `[x0, y0, x1, y1]` in 0..1 with the origin top-left; `z_mm` is
|
|
129
|
+
`[min, max]` distance in millimetres (either side may be `null`). Each zone
|
|
130
|
+
gets its own person tracker and depth-change grid. The depth map is aligned to
|
|
131
|
+
the colour camera only approximately, so leave some margin.
|
|
132
|
+
|
|
133
|
+
## Commands
|
|
134
|
+
|
|
135
|
+
| Command | What it does |
|
|
136
|
+
| --- | --- |
|
|
137
|
+
| `oak-events run --model PATH [--device-id ID] [--out-dir DIR] [--zones FILE] [--fps 10]` | Run the camera; print events, optionally append to `DIR/YYYY-MM-DD.jsonl` |
|
|
138
|
+
| `oak-events doctor [--json]` | depthai version, visible devices, bootloader advice, privacy env state |
|
|
139
|
+
| `oak-events mcp --events-dir DIR` | MCP stdio server with `recent_events`, `zone_state`, `camera_health` |
|
|
140
|
+
|
|
141
|
+
## Event schema
|
|
142
|
+
|
|
143
|
+
Every line is a JSON object with `ts` (ISO-8601 local time with offset),
|
|
144
|
+
`kind`, and the fields below.
|
|
145
|
+
|
|
146
|
+
| kind | fields | meaning |
|
|
147
|
+
| --- | --- | --- |
|
|
148
|
+
| `person_enter` | `zone`, `count`, `nearest_mm` | a person was seen in `confirm_frames` (3) consecutive frames |
|
|
149
|
+
| `person_exit` | `zone`, `dwell_s` | nobody seen for `gone_seconds` (10); dwell = first to last sighting |
|
|
150
|
+
| `depth_baseline` | `zone`, `cells_judged`, `cells_noisy`, `grid` | baseline built; noisy cells (stereo noise, low texture) are ignored |
|
|
151
|
+
| `depth_change` | `zone`, `cells` (e.g. `["r0c3"]`), `delta_mm` | a cell's depth moved > 15 % for `--hold-seconds` (60) with nobody present |
|
|
152
|
+
| `camera` | `state` (`up`, `not_found`, `error`, `reconnect`, `pipeline_stopped`, `stopped`), plus `device`, `device_model`, `bootloader`, `model`, `detail` as relevant | camera lifecycle |
|
|
153
|
+
| `alive` | `det_fps`, `person`, `occupied` | heartbeat every `--alive-every` seconds (300) |
|
|
154
|
+
|
|
155
|
+
Example:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{"ts": "2026-10-11T09:14:03-07:00", "kind": "person_enter", "zone": "doorway", "count": 1, "nearest_mm": 1840}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Depth-change detection pauses while a person is present in that zone: people
|
|
162
|
+
are not scenery.
|
|
163
|
+
|
|
164
|
+
## MCP
|
|
165
|
+
|
|
166
|
+
`oak-events mcp --events-dir DIR` runs a stdio MCP server (official `mcp`
|
|
167
|
+
Python SDK). Tools, all returning JSON text:
|
|
168
|
+
|
|
169
|
+
- `recent_events(limit=50, kind=None)` - latest events, oldest first
|
|
170
|
+
- `zone_state()` - per zone: person present or not, latest person and depth events
|
|
171
|
+
- `camera_health()` - latest `camera` and `alive` events with their age and a status (`ok`, `stale`, `no_data`, or the last camera state)
|
|
172
|
+
|
|
173
|
+
See `examples/claude-desktop-mcp.json` for a client config, and
|
|
174
|
+
`examples/openclaw-stream.md` / `examples/webhook.md` for wiring the event
|
|
175
|
+
stream into automations.
|
|
176
|
+
|
|
177
|
+
## Running it for real
|
|
178
|
+
|
|
179
|
+
Run `oak-events run` under a supervisor that restarts it on exit (systemd,
|
|
180
|
+
launchd, a container restart policy). The process exits with a `camera` event
|
|
181
|
+
explaining why: `not_found`, `error`, `pipeline_stopped`.
|
|
182
|
+
|
|
183
|
+
### PoE notes
|
|
184
|
+
|
|
185
|
+
- **Bootloader:** RVC2 PoE devices with a bootloader older than **0.0.29** can
|
|
186
|
+
fail discovery; 0.0.29 fixes it. `oak-events doctor` shows the version when
|
|
187
|
+
the device is not in use.
|
|
188
|
+
- **The device can take from ~30 s to a few minutes to free up** after a previous host disconnects (2.5 min observed on an OAK-D PoE). `oak-events run` keeps retrying discovery for up to 4 minutes.
|
|
189
|
+
`run` retries discovery for up to 90 s and asks DepthAI to reconnect up to 5
|
|
190
|
+
times before giving up.
|
|
191
|
+
- **macOS launchd:** observed, cause not proven: under a launchd job the device
|
|
192
|
+
could fail with `X_LINK_DEVICE_NOT_FOUND` while the same command worked from
|
|
193
|
+
a terminal. Running it under a supervisor process that has macOS
|
|
194
|
+
local-network permission worked. If you see this, check
|
|
195
|
+
*System Settings > Privacy & Security > Local Network*.
|
|
196
|
+
- Prefer `--device-id` over addresses; the id survives network changes.
|
|
197
|
+
|
|
198
|
+
## Development
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
python3 -m venv .venv
|
|
202
|
+
.venv/bin/pip install -e '.[mcp]' pytest
|
|
203
|
+
.venv/bin/pytest -q
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Tests need neither a camera nor `depthai`. See `CONTRIBUTING.md`.
|
|
207
|
+
|
|
208
|
+
## License
|
|
209
|
+
|
|
210
|
+
MIT. See `LICENSE`.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
oak-events is an independent community project, not affiliated with or endorsed by Luxonis. OAK and DepthAI are Luxonis trademarks, used here only to say which hardware and SDK the tool works with.
|
|
215
|
+
|
|
216
|
+
<!-- mcp-name: io.github.cloudlabworks/oak-events -->
|