@blueharford/scrypted-spatial-awareness 0.1.0

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.
@@ -0,0 +1,3 @@
1
+ {
2
+ "scrypted.debugHost": "127.0.0.1"
3
+ }
package/CLAUDE.md ADDED
@@ -0,0 +1,168 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ This is a Scrypted plugin for cross-camera object tracking ("Spatial Awareness"). It correlates detected objects as they move between cameras, maintains global tracking state, and provides alerts for property entry/exit and movement patterns.
8
+
9
+ ## Build & Development Commands
10
+
11
+ ```bash
12
+ # Install dependencies
13
+ npm install
14
+
15
+ # Build the plugin
16
+ npm run build
17
+
18
+ # Deploy to local Scrypted server (127.0.0.1)
19
+ npm run scrypted-deploy
20
+
21
+ # Deploy to remote Scrypted server
22
+ npm run scrypted-deploy <ip-address>
23
+
24
+ # Debug in VS Code
25
+ # 1. Edit .vscode/settings.json with Scrypted server IP
26
+ # 2. Press F5 or use Run > Start Debugging
27
+
28
+ # Login to Scrypted (required once)
29
+ npx scrypted login
30
+ ```
31
+
32
+ ## Architecture
33
+
34
+ ### Plugin Entry Point
35
+ - `src/main.ts` - Exports `SpatialAwarenessPlugin` class implementing `DeviceProvider`, `Settings`, `HttpRequestHandler`
36
+
37
+ ### Core Tracking Engine
38
+ - `src/core/tracking-engine.ts` - Orchestrates detection events, correlation, and state updates
39
+ - `src/core/object-correlator.ts` - Multi-factor correlation algorithm (timing, visual, spatial, class)
40
+ - `src/core/transit-predictor.ts` - Predicts expected cameras and transit times
41
+
42
+ ### Data Models
43
+ - `src/models/topology.ts` - Camera nodes, connections, zones
44
+ - `src/models/tracked-object.ts` - Global tracked object with journey history
45
+ - `src/models/alert.ts` - Alert types and rules
46
+
47
+ ### State Management
48
+ - `src/state/tracking-state.ts` - In-memory store with persistence and change notifications
49
+
50
+ ### Virtual Devices
51
+ - `src/devices/global-tracker-sensor.ts` - OccupancySensor for property-wide tracking
52
+ - `src/devices/tracking-zone.ts` - Zone-specific motion/occupancy sensors
53
+
54
+ ## Key Scrypted Patterns
55
+
56
+ ### Listening to Object Detection Events
57
+ ```typescript
58
+ import sdk, { ScryptedInterface, ObjectsDetected } from '@scrypted/sdk';
59
+
60
+ const camera = sdk.systemManager.getDeviceById(cameraId);
61
+ camera.listen(ScryptedInterface.ObjectDetector, async (source, details, data) => {
62
+ const results = data as ObjectsDetected;
63
+ // results.detections[] contains ObjectDetectionResult items
64
+ });
65
+ ```
66
+
67
+ ### ObjectDetectionResult Structure
68
+ ```typescript
69
+ {
70
+ boundingBox: [x, y, width, height], // normalized coordinates
71
+ className: 'person' | 'car' | 'animal' | 'package',
72
+ score: 0.95, // confidence
73
+ id: 'abc123', // tracking ID (single camera)
74
+ history: { firstSeen: number, lastSeen: number },
75
+ movement: { moving: boolean },
76
+ zones: string[],
77
+ embedding?: string // visual feature embedding (base64)
78
+ }
79
+ ```
80
+
81
+ ### StorageSettings Pattern
82
+ ```typescript
83
+ import { StorageSettings } from '@scrypted/sdk/storage-settings';
84
+
85
+ storageSettings = new StorageSettings(this, {
86
+ settingKey: {
87
+ title: 'Setting Title',
88
+ type: 'number',
89
+ defaultValue: 30,
90
+ group: 'GroupName',
91
+ },
92
+ });
93
+ ```
94
+
95
+ ### DeviceProvider Pattern
96
+ ```typescript
97
+ async getDevice(nativeId: string): Promise<any> {
98
+ // Return or create device instance by nativeId
99
+ }
100
+
101
+ async releaseDevice(id: string, nativeId: string): Promise<void> {
102
+ // Cleanup device
103
+ }
104
+ ```
105
+
106
+ ## Correlation Algorithm
107
+
108
+ Objects are correlated across cameras using weighted factors:
109
+ - **Timing (30%)**: Transit time within expected min/max range
110
+ - **Visual (35%)**: Embedding similarity (cosine distance)
111
+ - **Spatial (25%)**: Exit zone → Entry zone coherence
112
+ - **Class (10%)**: Object class must match
113
+
114
+ Threshold for automatic correlation: 0.6 (configurable)
115
+
116
+ ## Camera Topology Configuration
117
+
118
+ Topology is stored as JSON with:
119
+ - `cameras[]` - Camera nodes with entry/exit point flags
120
+ - `connections[]` - Links between cameras with exit/entry zones and transit times
121
+ - `globalZones[]` - Named zones spanning multiple cameras
122
+
123
+ ## API Endpoints
124
+
125
+ - `GET /api/tracked-objects` - All tracked objects
126
+ - `GET /api/journey/{globalId}` - Journey for specific object
127
+ - `GET|PUT /api/topology` - Camera topology config
128
+ - `GET /api/alerts` - Recent alerts
129
+ - `GET|POST /api/floor-plan` - Floor plan image (base64)
130
+ - `GET /ui/editor` - Visual topology editor
131
+
132
+ ## MQTT Integration
133
+
134
+ When enabled, publishes to Home Assistant via MQTT:
135
+ - `{baseTopic}/occupancy/state` - ON/OFF occupancy
136
+ - `{baseTopic}/count/state` - Active object count
137
+ - `{baseTopic}/person_count/state` - People on property
138
+ - `{baseTopic}/vehicle_count/state` - Vehicles on property
139
+ - `{baseTopic}/state` - Full JSON state
140
+ - `{baseTopic}/alerts` - Alert events
141
+ - `{baseTopic}/events/entry|exit|transition` - Movement events
142
+
143
+ ## Project Structure
144
+
145
+ ```
146
+ src/
147
+ ├── main.ts # Plugin entry point
148
+ ├── core/
149
+ │ ├── tracking-engine.ts # Central orchestrator
150
+ │ └── object-correlator.ts # Cross-camera matching
151
+ ├── models/
152
+ │ ├── topology.ts # Camera topology types
153
+ │ ├── tracked-object.ts # Tracked object types
154
+ │ └── alert.ts # Alert types
155
+ ├── devices/
156
+ │ ├── global-tracker-sensor.ts
157
+ │ └── tracking-zone.ts
158
+ ├── state/
159
+ │ └── tracking-state.ts # State management
160
+ ├── alerts/
161
+ │ └── alert-manager.ts # Alert generation
162
+ ├── integrations/
163
+ │ └── mqtt-publisher.ts # MQTT for Home Assistant
164
+ ├── ui/
165
+ │ └── editor.html # Visual topology editor
166
+ └── utils/
167
+ └── id-generator.ts
168
+ ```
package/README.md ADDED
@@ -0,0 +1,152 @@
1
+ # Spatial Awareness - Scrypted Plugin
2
+
3
+ Cross-camera object tracking for Scrypted NVR with spatial awareness capabilities.
4
+
5
+ ## Features
6
+
7
+ - **Cross-Camera Tracking**: Correlate objects (people, vehicles, animals) as they move between cameras
8
+ - **Journey History**: Complete path history for each tracked object across your property
9
+ - **Entry/Exit Detection**: Know when objects enter or leave your property
10
+ - **Visual Floor Plan Editor**: Configure camera topology with an intuitive visual editor
11
+ - **MQTT Integration**: Export tracking data to Home Assistant for automations
12
+ - **REST API**: Query tracked objects and journeys programmatically
13
+ - **Smart Alerts**: Get notified about property entry/exit, unusual paths, dwell time, and restricted zones
14
+
15
+ ## Installation
16
+
17
+ ### From Scrypted Plugin Repository
18
+ 1. Open Scrypted Management Console
19
+ 2. Go to Plugins
20
+ 3. Search for "Spatial Awareness"
21
+ 4. Click Install
22
+
23
+ ### From NPM
24
+ ```bash
25
+ npm install @blueharford/scrypted-spatial-awareness
26
+ ```
27
+
28
+ ## Setup
29
+
30
+ 1. **Add Cameras**: In plugin settings, select cameras with object detection enabled
31
+ 2. **Configure Topology**:
32
+ - Access the visual editor at `/ui/editor` (via plugin's HTTP endpoint)
33
+ - Upload a floor plan image
34
+ - Place cameras on the floor plan
35
+ - Draw connections between cameras with expected transit times
36
+ 3. **Enable Integrations**: Optionally enable MQTT for Home Assistant
37
+ 4. **Create Zones**: Add tracking zones for specific area monitoring
38
+
39
+ ## How It Works
40
+
41
+ The plugin listens to object detection events from all configured cameras. When an object (person, car, animal, package) is detected:
42
+
43
+ 1. **Same Camera**: If the object is already being tracked on this camera, the sighting is added to its history
44
+ 2. **Cross-Camera Correlation**: If the object disappeared from another camera recently, the plugin attempts to correlate using:
45
+ - **Timing (30%)**: Does the transit time match the expected range?
46
+ - **Visual (35%)**: Do the visual embeddings match (if available)?
47
+ - **Spatial (25%)**: Was the object in the exit zone of the previous camera and entry zone of the new camera?
48
+ - **Class (10%)**: Is it the same type of object?
49
+ 3. **New Object**: If no correlation is found, a new tracked object is created
50
+
51
+ ## API Endpoints
52
+
53
+ The plugin exposes a REST API via Scrypted's HTTP handler:
54
+
55
+ | Endpoint | Method | Description |
56
+ |----------|--------|-------------|
57
+ | `/api/tracked-objects` | GET | List all tracked objects |
58
+ | `/api/journey/{id}` | GET | Get journey for specific object |
59
+ | `/api/topology` | GET | Get camera topology configuration |
60
+ | `/api/topology` | PUT | Update camera topology |
61
+ | `/api/alerts` | GET | Get recent alerts |
62
+ | `/api/floor-plan` | GET/POST | Get or upload floor plan image |
63
+ | `/ui/editor` | GET | Visual topology editor |
64
+
65
+ ## MQTT Topics
66
+
67
+ When MQTT is enabled, the plugin publishes to:
68
+
69
+ | Topic | Description |
70
+ |-------|-------------|
71
+ | `{baseTopic}/occupancy/state` | ON/OFF property occupancy |
72
+ | `{baseTopic}/count/state` | Number of active tracked objects |
73
+ | `{baseTopic}/person_count/state` | Number of people on property |
74
+ | `{baseTopic}/vehicle_count/state` | Number of vehicles on property |
75
+ | `{baseTopic}/state` | Full JSON state with all objects |
76
+ | `{baseTopic}/alerts` | Alert events |
77
+ | `{baseTopic}/events/entry` | Entry events |
78
+ | `{baseTopic}/events/exit` | Exit events |
79
+ | `{baseTopic}/events/transition` | Camera transition events |
80
+
81
+ Default base topic: `scrypted/spatial-awareness`
82
+
83
+ ## Virtual Devices
84
+
85
+ The plugin creates these virtual devices in Scrypted:
86
+
87
+ ### Global Object Tracker
88
+ - **Type**: Occupancy Sensor
89
+ - **Purpose**: Shows whether any objects are currently tracked on the property
90
+ - **Use**: Trigger automations when property becomes occupied/unoccupied
91
+
92
+ ### Tracking Zones (User-Created)
93
+ - **Type**: Motion + Occupancy Sensor
94
+ - **Purpose**: Monitor specific areas across one or more cameras
95
+ - **Types**: Entry, Exit, Dwell, Restricted
96
+ - **Use**: Create zone-specific automations and alerts
97
+
98
+ ## Alert Types
99
+
100
+ | Alert | Description |
101
+ |-------|-------------|
102
+ | Property Entry | Object entered the property via an entry point |
103
+ | Property Exit | Object exited the property via an exit point |
104
+ | Unusual Path | Object took an unexpected route between cameras |
105
+ | Dwell Time | Object lingered too long in an area |
106
+ | Restricted Zone | Object entered a restricted zone |
107
+ | Lost Tracking | Object disappeared without exiting |
108
+
109
+ ## Configuration Options
110
+
111
+ ### Tracking Settings
112
+ - **Correlation Window**: Maximum time (seconds) to wait for cross-camera correlation
113
+ - **Correlation Threshold**: Minimum confidence (0-1) for automatic correlation
114
+ - **Lost Timeout**: Time before marking an object as lost
115
+ - **Visual Matching**: Enable/disable visual embedding matching
116
+
117
+ ### MQTT Settings
118
+ - **Enable MQTT**: Toggle MQTT publishing
119
+ - **Broker URL**: MQTT broker address (e.g., `mqtt://localhost:1883`)
120
+ - **Username/Password**: MQTT authentication
121
+ - **Base Topic**: Topic prefix for all messages
122
+
123
+ ## Requirements
124
+
125
+ - Scrypted with NVR plugin
126
+ - Cameras with object detection enabled (via Scrypted NVR, OpenVINO, CoreML, ONNX, or TensorFlow Lite)
127
+ - Optional: MQTT broker for Home Assistant integration
128
+
129
+ ## Development
130
+
131
+ ```bash
132
+ # Install dependencies
133
+ npm install
134
+
135
+ # Build
136
+ npm run build
137
+
138
+ # Deploy to local Scrypted
139
+ npm run scrypted-deploy
140
+
141
+ # Debug in VS Code
142
+ # Edit .vscode/settings.json with your Scrypted server IP
143
+ # Press F5 to start debugging
144
+ ```
145
+
146
+ ## License
147
+
148
+ Apache-2.0
149
+
150
+ ## Author
151
+
152
+ Joshua Seidel ([@blueharford](https://github.com/blueharford))