@trillboards/edge-sdk 0.2.1 → 0.2.3

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.
Files changed (50) hide show
  1. package/README.md +147 -2
  2. package/deploy/docker/Dockerfile.cpu +132 -0
  3. package/deploy/docker/Dockerfile.cuda +134 -0
  4. package/deploy/docker/Dockerfile.openvino +131 -0
  5. package/deploy/docker/README.md +358 -0
  6. package/deploy/helm/README.md +508 -0
  7. package/deploy/helm/trillboards-edge/Chart.yaml +19 -0
  8. package/deploy/helm/trillboards-edge/templates/_helpers.tpl +40 -0
  9. package/deploy/helm/trillboards-edge/templates/daemonset.yaml +120 -0
  10. package/deploy/helm/trillboards-edge/templates/service.yaml +15 -0
  11. package/deploy/helm/trillboards-edge/values.yaml +95 -0
  12. package/deploy/k8s/daemonset.yaml +144 -0
  13. package/dist/CommandRouter.d.ts +113 -0
  14. package/dist/CommandRouter.d.ts.map +1 -0
  15. package/dist/CommandRouter.js +392 -0
  16. package/dist/CommandRouter.js.map +1 -0
  17. package/dist/EdgeAgent.d.ts +6 -1
  18. package/dist/EdgeAgent.d.ts.map +1 -1
  19. package/dist/EdgeAgent.js +277 -10
  20. package/dist/EdgeAgent.js.map +1 -1
  21. package/dist/cli.js +60 -8
  22. package/dist/cli.js.map +1 -1
  23. package/dist/config.d.ts +1 -0
  24. package/dist/config.d.ts.map +1 -1
  25. package/dist/config.js.map +1 -1
  26. package/dist/demo.d.ts +111 -0
  27. package/dist/demo.d.ts.map +1 -0
  28. package/dist/demo.js +483 -0
  29. package/dist/demo.js.map +1 -0
  30. package/dist/diagnose.d.ts +59 -0
  31. package/dist/diagnose.d.ts.map +1 -0
  32. package/dist/diagnose.js +651 -0
  33. package/dist/diagnose.js.map +1 -0
  34. package/dist/index.d.ts +5 -0
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +7 -1
  37. package/dist/index.js.map +1 -1
  38. package/dist/init.d.ts +19 -0
  39. package/dist/init.d.ts.map +1 -0
  40. package/dist/init.js +364 -0
  41. package/dist/init.js.map +1 -0
  42. package/dist/mcp-server.d.ts +27 -0
  43. package/dist/mcp-server.d.ts.map +1 -0
  44. package/dist/mcp-server.js +1264 -0
  45. package/dist/mcp-server.js.map +1 -0
  46. package/dist/status.d.ts +11 -0
  47. package/dist/status.d.ts.map +1 -0
  48. package/dist/status.js +343 -0
  49. package/dist/status.js.map +1 -0
  50. package/package.json +5 -4
package/README.md CHANGED
@@ -59,10 +59,17 @@ await agent.start();
59
59
 
60
60
  | Command | Description |
61
61
  |---------|-------------|
62
+ | `trillboards-edge demo` | Try it instantly -- synthetic audience sensing with a live terminal dashboard. No token, camera, or models required. |
63
+ | `trillboards-edge init` | Interactive setup wizard -- prompts for token, platform, camera, audio, kiosk, models, and execution provider |
62
64
  | `trillboards-edge start [--config path]` | Start the edge agent |
65
+ | `trillboards-edge status [--host h] [--port p] [--json] [--watch]` | Query the agent status endpoint and display a formatted dashboard |
66
+ | `trillboards-edge diagnose [--json]` | Run 10 system diagnostic checks (Node.js, platform, memory, CPU, disk, camera, models, API, GPU, network) |
67
+ | `trillboards-edge mcp` | Start the MCP server for AI agent integration (Claude Desktop, Cursor) |
63
68
  | `trillboards-edge download-models [--dir path]` | Download ONNX models (BlazeFace, YAMNet) |
64
69
  | `trillboards-edge version` | Print SDK version |
65
70
 
71
+ See [docs/CLI.md](../../docs/CLI.md) for the full CLI reference with all flags and configuration details.
72
+
66
73
  ## Capability Tiers
67
74
 
68
75
  The SDK auto-detects device capabilities and adjusts inference accordingly:
@@ -95,10 +102,137 @@ This is the umbrella package. For fine-grained control, install sub-packages ind
95
102
  | [@trillboards/edge-platform-linux](https://www.npmjs.com/package/@trillboards/edge-platform-linux) | V4L2 camera, PulseAudio, systemd, kiosk mode |
96
103
  | [@trillboards/edge-platform-windows](https://www.npmjs.com/package/@trillboards/edge-platform-windows) | DirectShow, RTSP IP cameras, WASAPI audio |
97
104
 
105
+ ## MCP Server (AI Agent Integration)
106
+
107
+ The SDK includes a built-in MCP (Model Context Protocol) server that allows
108
+ AI agents to discover, configure, and diagnose edge devices.
109
+
110
+ ```bash
111
+ trillboards-edge mcp
112
+ ```
113
+
114
+ The server communicates over stdio using JSON-RPC 2.0 and talks to the running
115
+ edge agent's StatusServer on `localhost:9090`.
116
+
117
+ **7 tools available:** `get-device-status`, `get-audience-live`,
118
+ `configure-sensing`, `run-benchmark`, `diagnose-hardware`, `list-models`,
119
+ `get-buffer-stats`.
120
+
121
+ **Claude Desktop config** (`claude_desktop_config.json`):
122
+
123
+ ```json
124
+ {
125
+ "mcpServers": {
126
+ "trillboards-edge": {
127
+ "command": "npx",
128
+ "args": ["-y", "@trillboards/edge-sdk", "mcp"],
129
+ "env": { "EDGE_STATUS_PORT": "9090" }
130
+ }
131
+ }
132
+ }
133
+ ```
134
+
135
+ **Cursor config** (`.cursor/mcp.json`):
136
+
137
+ ```json
138
+ {
139
+ "mcpServers": {
140
+ "trillboards-edge": {
141
+ "command": "npx",
142
+ "args": ["-y", "@trillboards/edge-sdk", "mcp"]
143
+ }
144
+ }
145
+ }
146
+ ```
147
+
148
+ See [docs/MCP.md](../../docs/MCP.md) for the full MCP server reference.
149
+
150
+ ## Status Endpoint
151
+
152
+ When the edge agent is running, it exposes an HTTP status server (default port
153
+ 9090) with three endpoints:
154
+
155
+ | Endpoint | Method | Description |
156
+ |----------|--------|-------------|
157
+ | `/status` | GET | Full JSON status payload (device, sensing, subsystems, buffer) |
158
+ | `/health` | GET | Health check -- returns 200 if healthy, 503 if degraded |
159
+ | `/metrics` | GET | Prometheus-format metrics for scraping |
160
+
161
+ ```bash
162
+ curl http://localhost:9090/status # Full status JSON
163
+ curl http://localhost:9090/health # Health check
164
+ curl http://localhost:9090/metrics # Prometheus metrics
165
+ ```
166
+
167
+ Query from the CLI:
168
+
169
+ ```bash
170
+ trillboards-edge status # Formatted dashboard
171
+ trillboards-edge status --watch # Refresh every 5s
172
+ trillboards-edge status --host 192.168.1.50 # Remote device
173
+ trillboards-edge status --json # Raw JSON
174
+ ```
175
+
176
+ See [docs/STATUS_API.md](../../docs/STATUS_API.md) for the full status API reference.
177
+
178
+ ## Docker Deployment
179
+
180
+ ```bash
181
+ # CPU (default)
182
+ docker run -d \
183
+ --name trillboards-edge \
184
+ -e DEVICE_TOKEN=your-token \
185
+ -p 9090:9090 \
186
+ --device /dev/video0:/dev/video0 \
187
+ trillboards/edge-sdk:latest
188
+
189
+ # NVIDIA GPU
190
+ docker run -d \
191
+ --name trillboards-edge \
192
+ --gpus all \
193
+ -e DEVICE_TOKEN=your-token \
194
+ -p 9090:9090 \
195
+ --device /dev/video0:/dev/video0 \
196
+ trillboards/edge-sdk:cuda
197
+ ```
198
+
199
+ **docker-compose:**
200
+
201
+ ```yaml
202
+ services:
203
+ edge-agent:
204
+ image: trillboards/edge-sdk:latest
205
+ restart: unless-stopped
206
+ environment:
207
+ - DEVICE_TOKEN=${DEVICE_TOKEN}
208
+ ports:
209
+ - "9090:9090"
210
+ devices:
211
+ - /dev/video0:/dev/video0
212
+ volumes:
213
+ - ./models:/app/models
214
+ healthcheck:
215
+ test: ["CMD", "curl", "-f", "http://localhost:9090/health"]
216
+ interval: 30s
217
+ timeout: 5s
218
+ retries: 3
219
+ ```
220
+
221
+ The `create-trillboards-edge` scaffolding tool can generate a complete Docker or
222
+ Kubernetes project for you:
223
+
224
+ ```bash
225
+ npx create-trillboards-edge my-deploy --template docker
226
+ npx create-trillboards-edge fleet --template kubernetes
227
+ ```
228
+
229
+ See [deploy/docker/README.md](../../deploy/docker/README.md) and
230
+ [deploy/helm/README.md](../../deploy/helm/README.md) for full deployment guides.
231
+
98
232
  ## Platform Support
99
233
 
100
- - **Linux** Ubuntu 20.04+, Debian 11+, Raspberry Pi OS (ARM64)
101
- - **Windows** Windows 10/11 (x64)
234
+ - **Linux** -- Ubuntu 20.04+, Debian 11+, Raspberry Pi OS (ARM64)
235
+ - **Windows** -- Windows 10/11 (x64)
102
236
 
103
237
  ## Get a Device Token
104
238
 
@@ -108,6 +242,17 @@ npx @trillboards/ads-sdk init
108
242
 
109
243
  Or register via the [Trillboards API](https://api.trillboards.com/developer).
110
244
 
245
+ ## Documentation
246
+
247
+ | Document | Description |
248
+ |----------|-------------|
249
+ | [docs/CLI.md](../../docs/CLI.md) | Full CLI reference with all commands, flags, and configuration |
250
+ | [docs/MCP.md](../../docs/MCP.md) | MCP server reference for AI agent integration |
251
+ | [docs/STATUS_API.md](../../docs/STATUS_API.md) | Status endpoint API reference |
252
+ | [deploy/docker/README.md](../../deploy/docker/README.md) | Docker deployment guide |
253
+ | [deploy/helm/README.md](../../deploy/helm/README.md) | Helm chart deployment guide |
254
+ | [create-trillboards-edge](../../../create-trillboards-edge/README.md) | Project scaffolding tool |
255
+
111
256
  ## License
112
257
 
113
258
  MIT
@@ -0,0 +1,132 @@
1
+ # Trillboards Edge AI SDK — CPU-only container
2
+ # Usage: docker build -f Dockerfile.cpu -t trillboards/edge-sdk:latest ../../
3
+ # Run: docker run -e DEVICE_TOKEN=xxx trillboards/edge-sdk:latest
4
+
5
+ FROM node:20-slim AS builder
6
+
7
+ WORKDIR /build
8
+
9
+ # Copy workspace package files first for layer caching
10
+ COPY package.json package-lock.json* ./
11
+ COPY packages/edge-core/package.json packages/edge-core/
12
+ COPY packages/edge-sensing/package.json packages/edge-sensing/
13
+ COPY packages/edge-federated/package.json packages/edge-federated/
14
+ COPY packages/edge-ads/package.json packages/edge-ads/
15
+ COPY packages/edge-cloud/package.json packages/edge-cloud/
16
+ COPY packages/edge-sdk/package.json packages/edge-sdk/
17
+ COPY packages/edge-platform-linux/package.json packages/edge-platform-linux/
18
+
19
+ # Install all dependencies
20
+ RUN npm ci --legacy-peer-deps 2>/dev/null || npm install --legacy-peer-deps
21
+
22
+ # Copy source and build
23
+ COPY . .
24
+ RUN npm run build --workspaces --if-present
25
+
26
+ # ─── Production image ─────────────────────────────────────────────────────
27
+ FROM node:20-slim
28
+
29
+ LABEL maintainer="Trillboards <engineering@trillboards.com>"
30
+ LABEL description="Trillboards Edge AI SDK — CPU-only container for DOOH audience sensing"
31
+
32
+ # Install runtime dependencies for camera/audio (optional — headless works without)
33
+ RUN apt-get update && apt-get install -y --no-install-recommends \
34
+ libv4l-dev \
35
+ libasound2 \
36
+ ca-certificates \
37
+ curl \
38
+ && rm -rf /var/lib/apt/lists/*
39
+
40
+ WORKDIR /app
41
+
42
+ # Copy built packages
43
+ COPY --from=builder /build/packages/edge-core/dist packages/edge-core/dist
44
+ COPY --from=builder /build/packages/edge-core/package.json packages/edge-core/
45
+ COPY --from=builder /build/packages/edge-sensing/dist packages/edge-sensing/dist
46
+ COPY --from=builder /build/packages/edge-sensing/package.json packages/edge-sensing/
47
+ COPY --from=builder /build/packages/edge-federated/dist packages/edge-federated/dist
48
+ COPY --from=builder /build/packages/edge-federated/package.json packages/edge-federated/
49
+ COPY --from=builder /build/packages/edge-ads/dist packages/edge-ads/dist
50
+ COPY --from=builder /build/packages/edge-ads/package.json packages/edge-ads/
51
+ COPY --from=builder /build/packages/edge-cloud/dist packages/edge-cloud/dist
52
+ COPY --from=builder /build/packages/edge-cloud/package.json packages/edge-cloud/
53
+ COPY --from=builder /build/packages/edge-sdk/dist packages/edge-sdk/dist
54
+ COPY --from=builder /build/packages/edge-sdk/package.json packages/edge-sdk/
55
+ COPY --from=builder /build/packages/edge-platform-linux/dist packages/edge-platform-linux/dist
56
+ COPY --from=builder /build/packages/edge-platform-linux/package.json packages/edge-platform-linux/
57
+
58
+ # Copy configs directory
59
+ COPY --from=builder /build/packages/edge-sdk/configs packages/edge-sdk/configs
60
+
61
+ # Install production dependencies only
62
+ COPY --from=builder /build/package.json /build/package-lock.json* ./
63
+ RUN npm ci --legacy-peer-deps --omit=dev 2>/dev/null || npm install --legacy-peer-deps --omit=dev
64
+
65
+ # Create models directory
66
+ RUN mkdir -p /app/models /app/data
67
+
68
+ # Download default models at build time
69
+ RUN node -e " \
70
+ const https = require('https'); \
71
+ const fs = require('fs'); \
72
+ const models = { \
73
+ 'blazeface.onnx': 'https://models.trillboards.com/blazeface_128x128.onnx', \
74
+ 'yamnet.onnx': 'https://models.trillboards.com/yamnet_classification.onnx', \
75
+ }; \
76
+ Object.entries(models).forEach(([name, url]) => { \
77
+ console.log('Downloading ' + name + '...'); \
78
+ const file = fs.createWriteStream('/app/models/' + name); \
79
+ https.get(url, (res) => { \
80
+ if (res.statusCode === 301 || res.statusCode === 302) { \
81
+ https.get(res.headers.location, (r) => r.pipe(file)); \
82
+ } else { \
83
+ res.pipe(file); \
84
+ } \
85
+ }); \
86
+ }); \
87
+ " 2>/dev/null || echo "Model download skipped (build-time network may be unavailable)"
88
+
89
+ # Environment variables with defaults
90
+ ENV NODE_ENV=production
91
+ ENV DEVICE_TOKEN=""
92
+ ENV SCREEN_ID=""
93
+ ENV VENUE_TYPE=""
94
+ ENV API_BASE_URL="https://api.trillboards.com"
95
+ ENV CAMERA_ENABLED="false"
96
+ ENV AUDIO_ENABLED="false"
97
+ ENV KIOSK_ENABLED="false"
98
+ ENV MODELS_DIR="/app/models"
99
+ ENV DATA_DIR="/app/data"
100
+ ENV EXECUTION_PROVIDER="cpu"
101
+ ENV STATUS_PORT="9090"
102
+ ENV LOG_LEVEL="info"
103
+
104
+ # Expose status server port
105
+ EXPOSE 9090
106
+
107
+ # Health check against the local status endpoint
108
+ HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
109
+ CMD curl -f http://localhost:9090/health || exit 1
110
+
111
+ # Generate config from env vars and start
112
+ ENTRYPOINT ["/bin/sh", "-c", "\
113
+ echo '{}' | node -e \" \
114
+ const cfg = { \
115
+ apiBaseUrl: process.env.API_BASE_URL, \
116
+ deviceToken: process.env.DEVICE_TOKEN, \
117
+ screenId: process.env.SCREEN_ID || undefined, \
118
+ venueType: process.env.VENUE_TYPE || undefined, \
119
+ platform: 'linux', \
120
+ camera: { enabled: process.env.CAMERA_ENABLED === 'true' }, \
121
+ audio: { enabled: process.env.AUDIO_ENABLED === 'true' }, \
122
+ models: { dir: process.env.MODELS_DIR, executionProvider: process.env.EXECUTION_PROVIDER }, \
123
+ kiosk: { enabled: process.env.KIOSK_ENABLED === 'true' }, \
124
+ cloud: { enabled: false }, \
125
+ federated: { enabled: true }, \
126
+ dataDir: process.env.DATA_DIR, \
127
+ logLevel: process.env.LOG_LEVEL, \
128
+ }; \
129
+ require('fs').writeFileSync('/app/config.json', JSON.stringify(cfg, null, 2)); \
130
+ \" && \
131
+ node packages/edge-sdk/dist/cli.js start --config /app/config.json \
132
+ "]
@@ -0,0 +1,134 @@
1
+ # Trillboards Edge AI SDK — NVIDIA CUDA container
2
+ # Usage: docker build -f Dockerfile.cuda -t trillboards/edge-sdk:cuda ../../
3
+ # Run: docker run --gpus all -e DEVICE_TOKEN=xxx trillboards/edge-sdk:cuda
4
+
5
+ FROM nvidia/cuda:12.3.2-runtime-ubuntu22.04 AS base
6
+
7
+ # Install Node.js 20
8
+ RUN apt-get update && apt-get install -y --no-install-recommends \
9
+ curl \
10
+ ca-certificates \
11
+ && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
12
+ && apt-get install -y nodejs \
13
+ && rm -rf /var/lib/apt/lists/*
14
+
15
+ # ─── Builder stage ─────────────────────────────────────────────────────────
16
+ FROM base AS builder
17
+
18
+ WORKDIR /build
19
+
20
+ COPY package.json package-lock.json* ./
21
+ COPY packages/edge-core/package.json packages/edge-core/
22
+ COPY packages/edge-sensing/package.json packages/edge-sensing/
23
+ COPY packages/edge-federated/package.json packages/edge-federated/
24
+ COPY packages/edge-ads/package.json packages/edge-ads/
25
+ COPY packages/edge-cloud/package.json packages/edge-cloud/
26
+ COPY packages/edge-sdk/package.json packages/edge-sdk/
27
+ COPY packages/edge-platform-linux/package.json packages/edge-platform-linux/
28
+
29
+ RUN npm ci --legacy-peer-deps 2>/dev/null || npm install --legacy-peer-deps
30
+
31
+ COPY . .
32
+ RUN npm run build --workspaces --if-present
33
+
34
+ # ─── Production image ─────────────────────────────────────────────────────
35
+ FROM base
36
+
37
+ LABEL maintainer="Trillboards <engineering@trillboards.com>"
38
+ LABEL description="Trillboards Edge AI SDK — NVIDIA CUDA container for GPU-accelerated audience sensing"
39
+
40
+ # Install runtime dependencies
41
+ RUN apt-get update && apt-get install -y --no-install-recommends \
42
+ libv4l-dev \
43
+ libasound2 \
44
+ && rm -rf /var/lib/apt/lists/*
45
+
46
+ WORKDIR /app
47
+
48
+ # Copy built packages
49
+ COPY --from=builder /build/packages/edge-core/dist packages/edge-core/dist
50
+ COPY --from=builder /build/packages/edge-core/package.json packages/edge-core/
51
+ COPY --from=builder /build/packages/edge-sensing/dist packages/edge-sensing/dist
52
+ COPY --from=builder /build/packages/edge-sensing/package.json packages/edge-sensing/
53
+ COPY --from=builder /build/packages/edge-federated/dist packages/edge-federated/dist
54
+ COPY --from=builder /build/packages/edge-federated/package.json packages/edge-federated/
55
+ COPY --from=builder /build/packages/edge-ads/dist packages/edge-ads/dist
56
+ COPY --from=builder /build/packages/edge-ads/package.json packages/edge-ads/
57
+ COPY --from=builder /build/packages/edge-cloud/dist packages/edge-cloud/dist
58
+ COPY --from=builder /build/packages/edge-cloud/package.json packages/edge-cloud/
59
+ COPY --from=builder /build/packages/edge-sdk/dist packages/edge-sdk/dist
60
+ COPY --from=builder /build/packages/edge-sdk/package.json packages/edge-sdk/
61
+ COPY --from=builder /build/packages/edge-platform-linux/dist packages/edge-platform-linux/dist
62
+ COPY --from=builder /build/packages/edge-platform-linux/package.json packages/edge-platform-linux/
63
+
64
+ COPY --from=builder /build/packages/edge-sdk/configs packages/edge-sdk/configs
65
+ COPY --from=builder /build/package.json /build/package-lock.json* ./
66
+ RUN npm ci --legacy-peer-deps --omit=dev 2>/dev/null || npm install --legacy-peer-deps --omit=dev
67
+
68
+ RUN mkdir -p /app/models /app/data
69
+
70
+ # Download default models
71
+ RUN node -e " \
72
+ const https = require('https'); \
73
+ const fs = require('fs'); \
74
+ const models = { \
75
+ 'blazeface.onnx': 'https://models.trillboards.com/blazeface_128x128.onnx', \
76
+ 'yamnet.onnx': 'https://models.trillboards.com/yamnet_classification.onnx', \
77
+ }; \
78
+ Object.entries(models).forEach(([name, url]) => { \
79
+ console.log('Downloading ' + name + '...'); \
80
+ const file = fs.createWriteStream('/app/models/' + name); \
81
+ https.get(url, (res) => { \
82
+ if (res.statusCode === 301 || res.statusCode === 302) { \
83
+ https.get(res.headers.location, (r) => r.pipe(file)); \
84
+ } else { \
85
+ res.pipe(file); \
86
+ } \
87
+ }); \
88
+ }); \
89
+ " 2>/dev/null || echo "Model download skipped"
90
+
91
+ ENV NODE_ENV=production
92
+ ENV DEVICE_TOKEN=""
93
+ ENV SCREEN_ID=""
94
+ ENV VENUE_TYPE=""
95
+ ENV API_BASE_URL="https://api.trillboards.com"
96
+ ENV CAMERA_ENABLED="false"
97
+ ENV AUDIO_ENABLED="false"
98
+ ENV KIOSK_ENABLED="false"
99
+ ENV MODELS_DIR="/app/models"
100
+ ENV DATA_DIR="/app/data"
101
+ ENV EXECUTION_PROVIDER="cuda"
102
+ ENV STATUS_PORT="9090"
103
+ ENV LOG_LEVEL="info"
104
+
105
+ # NVIDIA runtime configuration
106
+ ENV NVIDIA_VISIBLE_DEVICES=all
107
+ ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility
108
+
109
+ EXPOSE 9090
110
+
111
+ HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
112
+ CMD curl -f http://localhost:9090/health || exit 1
113
+
114
+ ENTRYPOINT ["/bin/sh", "-c", "\
115
+ echo '{}' | node -e \" \
116
+ const cfg = { \
117
+ apiBaseUrl: process.env.API_BASE_URL, \
118
+ deviceToken: process.env.DEVICE_TOKEN, \
119
+ screenId: process.env.SCREEN_ID || undefined, \
120
+ venueType: process.env.VENUE_TYPE || undefined, \
121
+ platform: 'linux', \
122
+ camera: { enabled: process.env.CAMERA_ENABLED === 'true' }, \
123
+ audio: { enabled: process.env.AUDIO_ENABLED === 'true' }, \
124
+ models: { dir: process.env.MODELS_DIR, executionProvider: process.env.EXECUTION_PROVIDER }, \
125
+ kiosk: { enabled: process.env.KIOSK_ENABLED === 'true' }, \
126
+ cloud: { enabled: false }, \
127
+ federated: { enabled: true }, \
128
+ dataDir: process.env.DATA_DIR, \
129
+ logLevel: process.env.LOG_LEVEL, \
130
+ }; \
131
+ require('fs').writeFileSync('/app/config.json', JSON.stringify(cfg, null, 2)); \
132
+ \" && \
133
+ node packages/edge-sdk/dist/cli.js start --config /app/config.json \
134
+ "]
@@ -0,0 +1,131 @@
1
+ # Trillboards Edge AI SDK — Intel OpenVINO container
2
+ # Usage: docker build -f Dockerfile.openvino -t trillboards/edge-sdk:openvino ../../
3
+ # Run: docker run -e DEVICE_TOKEN=xxx trillboards/edge-sdk:openvino
4
+ # Optimized for Intel HD 620+ GPUs (Backpackster, NUC, mini-PCs)
5
+
6
+ FROM openvino/ubuntu22_runtime:2024.0.0 AS base
7
+
8
+ USER root
9
+
10
+ # Install Node.js 20
11
+ RUN apt-get update && apt-get install -y --no-install-recommends \
12
+ curl \
13
+ ca-certificates \
14
+ && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
15
+ && apt-get install -y nodejs \
16
+ && rm -rf /var/lib/apt/lists/*
17
+
18
+ # ─── Builder stage ─────────────────────────────────────────────────────────
19
+ FROM base AS builder
20
+
21
+ WORKDIR /build
22
+
23
+ COPY package.json package-lock.json* ./
24
+ COPY packages/edge-core/package.json packages/edge-core/
25
+ COPY packages/edge-sensing/package.json packages/edge-sensing/
26
+ COPY packages/edge-federated/package.json packages/edge-federated/
27
+ COPY packages/edge-ads/package.json packages/edge-ads/
28
+ COPY packages/edge-cloud/package.json packages/edge-cloud/
29
+ COPY packages/edge-sdk/package.json packages/edge-sdk/
30
+ COPY packages/edge-platform-linux/package.json packages/edge-platform-linux/
31
+
32
+ RUN npm ci --legacy-peer-deps 2>/dev/null || npm install --legacy-peer-deps
33
+
34
+ COPY . .
35
+ RUN npm run build --workspaces --if-present
36
+
37
+ # ─── Production image ─────────────────────────────────────────────────────
38
+ FROM base
39
+
40
+ LABEL maintainer="Trillboards <engineering@trillboards.com>"
41
+ LABEL description="Trillboards Edge AI SDK — Intel OpenVINO container for accelerated inference"
42
+
43
+ RUN apt-get update && apt-get install -y --no-install-recommends \
44
+ libv4l-dev \
45
+ libasound2 \
46
+ && rm -rf /var/lib/apt/lists/*
47
+
48
+ WORKDIR /app
49
+
50
+ COPY --from=builder /build/packages/edge-core/dist packages/edge-core/dist
51
+ COPY --from=builder /build/packages/edge-core/package.json packages/edge-core/
52
+ COPY --from=builder /build/packages/edge-sensing/dist packages/edge-sensing/dist
53
+ COPY --from=builder /build/packages/edge-sensing/package.json packages/edge-sensing/
54
+ COPY --from=builder /build/packages/edge-federated/dist packages/edge-federated/dist
55
+ COPY --from=builder /build/packages/edge-federated/package.json packages/edge-federated/
56
+ COPY --from=builder /build/packages/edge-ads/dist packages/edge-ads/dist
57
+ COPY --from=builder /build/packages/edge-ads/package.json packages/edge-ads/
58
+ COPY --from=builder /build/packages/edge-cloud/dist packages/edge-cloud/dist
59
+ COPY --from=builder /build/packages/edge-cloud/package.json packages/edge-cloud/
60
+ COPY --from=builder /build/packages/edge-sdk/dist packages/edge-sdk/dist
61
+ COPY --from=builder /build/packages/edge-sdk/package.json packages/edge-sdk/
62
+ COPY --from=builder /build/packages/edge-platform-linux/dist packages/edge-platform-linux/dist
63
+ COPY --from=builder /build/packages/edge-platform-linux/package.json packages/edge-platform-linux/
64
+
65
+ COPY --from=builder /build/packages/edge-sdk/configs packages/edge-sdk/configs
66
+ COPY --from=builder /build/package.json /build/package-lock.json* ./
67
+ RUN npm ci --legacy-peer-deps --omit=dev 2>/dev/null || npm install --legacy-peer-deps --omit=dev
68
+
69
+ RUN mkdir -p /app/models /app/data
70
+
71
+ RUN node -e " \
72
+ const https = require('https'); \
73
+ const fs = require('fs'); \
74
+ const models = { \
75
+ 'blazeface.onnx': 'https://models.trillboards.com/blazeface_128x128.onnx', \
76
+ 'yamnet.onnx': 'https://models.trillboards.com/yamnet_classification.onnx', \
77
+ }; \
78
+ Object.entries(models).forEach(([name, url]) => { \
79
+ console.log('Downloading ' + name + '...'); \
80
+ const file = fs.createWriteStream('/app/models/' + name); \
81
+ https.get(url, (res) => { \
82
+ if (res.statusCode === 301 || res.statusCode === 302) { \
83
+ https.get(res.headers.location, (r) => r.pipe(file)); \
84
+ } else { \
85
+ res.pipe(file); \
86
+ } \
87
+ }); \
88
+ }); \
89
+ " 2>/dev/null || echo "Model download skipped"
90
+
91
+ ENV NODE_ENV=production
92
+ ENV DEVICE_TOKEN=""
93
+ ENV SCREEN_ID=""
94
+ ENV VENUE_TYPE=""
95
+ ENV API_BASE_URL="https://api.trillboards.com"
96
+ ENV CAMERA_ENABLED="false"
97
+ ENV AUDIO_ENABLED="false"
98
+ ENV KIOSK_ENABLED="false"
99
+ ENV MODELS_DIR="/app/models"
100
+ ENV DATA_DIR="/app/data"
101
+ ENV EXECUTION_PROVIDER="openvino"
102
+ ENV STATUS_PORT="9090"
103
+ ENV LOG_LEVEL="info"
104
+
105
+ EXPOSE 9090
106
+
107
+ HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
108
+ CMD curl -f http://localhost:9090/health || exit 1
109
+
110
+ ENTRYPOINT ["/bin/sh", "-c", "\
111
+ source /opt/intel/openvino/setupvars.sh && \
112
+ echo '{}' | node -e \" \
113
+ const cfg = { \
114
+ apiBaseUrl: process.env.API_BASE_URL, \
115
+ deviceToken: process.env.DEVICE_TOKEN, \
116
+ screenId: process.env.SCREEN_ID || undefined, \
117
+ venueType: process.env.VENUE_TYPE || undefined, \
118
+ platform: 'linux', \
119
+ camera: { enabled: process.env.CAMERA_ENABLED === 'true' }, \
120
+ audio: { enabled: process.env.AUDIO_ENABLED === 'true' }, \
121
+ models: { dir: process.env.MODELS_DIR, executionProvider: process.env.EXECUTION_PROVIDER }, \
122
+ kiosk: { enabled: process.env.KIOSK_ENABLED === 'true' }, \
123
+ cloud: { enabled: false }, \
124
+ federated: { enabled: true }, \
125
+ dataDir: process.env.DATA_DIR, \
126
+ logLevel: process.env.LOG_LEVEL, \
127
+ }; \
128
+ require('fs').writeFileSync('/app/config.json', JSON.stringify(cfg, null, 2)); \
129
+ \" && \
130
+ node packages/edge-sdk/dist/cli.js start --config /app/config.json \
131
+ "]