@trillboards/edge-sdk 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.
- package/configs/backpackster.json +32 -0
- package/configs/generic-linux.json +31 -0
- package/configs/windows-dooh.json +35 -0
- package/deploy/docker/.dockerignore +4 -0
- package/deploy/docker/Dockerfile +31 -0
- package/deploy/docker/config.json +21 -0
- package/deploy/docker/package.json +9 -0
- package/deploy/systemd/install.sh +68 -0
- package/deploy/systemd/trillboards-edge.service +42 -0
- package/deploy/windows/install-service.ps1 +95 -0
- package/dist/EdgeAgent.d.ts +39 -0
- package/dist/EdgeAgent.d.ts.map +1 -0
- package/dist/EdgeAgent.js +418 -0
- package/dist/EdgeAgent.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +217 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +44 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +97 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.EdgeAgent = void 0;
|
|
37
|
+
const events_1 = require("events");
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const edge_core_1 = require("@trillboards/edge-core");
|
|
41
|
+
const edge_sensing_1 = require("@trillboards/edge-sensing");
|
|
42
|
+
const edge_federated_1 = require("@trillboards/edge-federated");
|
|
43
|
+
const edge_ads_1 = require("@trillboards/edge-ads");
|
|
44
|
+
class EdgeAgent extends events_1.EventEmitter {
|
|
45
|
+
constructor(config) {
|
|
46
|
+
super();
|
|
47
|
+
this.platform = null;
|
|
48
|
+
this.camera = null;
|
|
49
|
+
this.audio = null;
|
|
50
|
+
this.socketManager = null;
|
|
51
|
+
this.sensingService = null;
|
|
52
|
+
this.telemetryScheduler = null;
|
|
53
|
+
this.recoveryLadder = null;
|
|
54
|
+
this.browserManager = null;
|
|
55
|
+
this.federatedTrainer = null;
|
|
56
|
+
this.healthRegistry = null;
|
|
57
|
+
this.signalBuffer = null;
|
|
58
|
+
this.running = false;
|
|
59
|
+
this.signalHandlersRegistered = false;
|
|
60
|
+
this.boundShutdownSigint = null;
|
|
61
|
+
this.boundShutdownSigterm = null;
|
|
62
|
+
this.config = config;
|
|
63
|
+
}
|
|
64
|
+
async start() {
|
|
65
|
+
if (this.running)
|
|
66
|
+
return;
|
|
67
|
+
this.running = true;
|
|
68
|
+
try {
|
|
69
|
+
const dataDir = this.config.dataDir || path.join(process.env.HOME || process.env.USERPROFILE || '/tmp', '.trillboards');
|
|
70
|
+
if (!fs.existsSync(dataDir)) {
|
|
71
|
+
fs.mkdirSync(dataDir, { recursive: true });
|
|
72
|
+
}
|
|
73
|
+
this.log('info', `Starting Trillboards Edge Agent v0.1.0`);
|
|
74
|
+
this.log('info', `Platform: ${this.config.platform}`);
|
|
75
|
+
this.log('info', `Data directory: ${dataDir}`);
|
|
76
|
+
// 1. Load platform adapter (uses require() for optional deps)
|
|
77
|
+
this.platform = await this.loadPlatformAdapter();
|
|
78
|
+
this.log('info', `Platform adapter loaded: ${this.config.platform}`);
|
|
79
|
+
// 2. Initialize device identity
|
|
80
|
+
const identity = new edge_core_1.DeviceIdentity(this.platform);
|
|
81
|
+
const fingerprint = await identity.getFingerprint();
|
|
82
|
+
const sessionId = identity.getSessionId();
|
|
83
|
+
this.log('info', `Device fingerprint: ${fingerprint}`);
|
|
84
|
+
// 3. Compute device capability tier
|
|
85
|
+
const tier = (0, edge_core_1.computeTier)(this.platform);
|
|
86
|
+
const capabilityMatrix = (0, edge_core_1.getCapabilityMatrix)(tier);
|
|
87
|
+
this.log('info', `Capability tier: TIER_${tier} (${capabilityMatrix.description})`);
|
|
88
|
+
// 4. Initialize health registry
|
|
89
|
+
this.healthRegistry = new edge_core_1.SubsystemHealthRegistry(dataDir);
|
|
90
|
+
// 5. Initialize signal buffer (SQLite)
|
|
91
|
+
this.signalBuffer = new edge_core_1.SignalBuffer(path.join(dataDir, 'signal_buffer.db'));
|
|
92
|
+
this.log('info', `Signal buffer: ${this.signalBuffer.count()} buffered signals`);
|
|
93
|
+
// 6. Initialize sensing config and VAS weights (needed by SocketManager)
|
|
94
|
+
const sensingConfig = new edge_core_1.SensingConfig();
|
|
95
|
+
const vasWeightConfig = new edge_core_1.VASWeightConfig();
|
|
96
|
+
// 7. Connect to backend via Socket.io
|
|
97
|
+
this.socketManager = new edge_core_1.SocketManager({
|
|
98
|
+
url: this.config.socketUrl || this.config.apiBaseUrl,
|
|
99
|
+
fingerprint,
|
|
100
|
+
deviceToken: this.config.deviceToken,
|
|
101
|
+
sensingConfig,
|
|
102
|
+
vasWeightConfig,
|
|
103
|
+
});
|
|
104
|
+
this.socketManager.connect();
|
|
105
|
+
this.healthRegistry.updateHealth(edge_core_1.Subsystem.SOCKET, edge_core_1.SubsystemStatus.CONNECTED);
|
|
106
|
+
this.log('info', 'Socket connected to backend');
|
|
107
|
+
// 8. Initialize camera if enabled (uses require() for optional platform deps)
|
|
108
|
+
if (this.config.camera?.enabled) {
|
|
109
|
+
try {
|
|
110
|
+
this.camera = await this.loadCamera();
|
|
111
|
+
if (this.camera) {
|
|
112
|
+
await this.camera.open(this.config.camera.deviceId);
|
|
113
|
+
this.healthRegistry.updateHealth(edge_core_1.Subsystem.CAMERA, edge_core_1.SubsystemStatus.ACTIVE);
|
|
114
|
+
this.log('info', `Camera opened: ${this.camera.getResolution().width}x${this.camera.getResolution().height}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
this.log('warn', `Camera init failed: ${err instanceof Error ? err.message : err}`);
|
|
119
|
+
this.healthRegistry.updateHealth(edge_core_1.Subsystem.CAMERA, edge_core_1.SubsystemStatus.ERROR, String(err));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// 9. Initialize audio if enabled (uses require() for optional platform deps)
|
|
123
|
+
if (this.config.audio?.enabled) {
|
|
124
|
+
try {
|
|
125
|
+
this.audio = await this.loadAudio();
|
|
126
|
+
if (this.audio) {
|
|
127
|
+
await this.audio.open(this.config.audio.deviceId);
|
|
128
|
+
this.healthRegistry.updateHealth(edge_core_1.Subsystem.MICROPHONE, edge_core_1.SubsystemStatus.ACTIVE);
|
|
129
|
+
this.log('info', `Audio opened: ${this.audio.getSampleRate()}Hz`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
this.log('warn', `Audio init failed: ${err instanceof Error ? err.message : err}`);
|
|
134
|
+
this.healthRegistry.updateHealth(edge_core_1.Subsystem.MICROPHONE, edge_core_1.SubsystemStatus.ERROR, String(err));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// 10. Initialize audience sensing pipeline
|
|
138
|
+
const modelsDir = this.config.models?.dir || './models';
|
|
139
|
+
const faceModelPath = this.config.models?.blazeFacePath || path.join(modelsDir, 'blazeface.onnx');
|
|
140
|
+
const audioModelPath = this.config.models?.yamnetPath || path.join(modelsDir, 'yamnet.onnx');
|
|
141
|
+
this.sensingService = new edge_sensing_1.AudienceSensingService({
|
|
142
|
+
fingerprint,
|
|
143
|
+
socketManager: this.socketManager,
|
|
144
|
+
sensingConfig,
|
|
145
|
+
vasWeightConfig,
|
|
146
|
+
healthRegistry: this.healthRegistry,
|
|
147
|
+
signalBuffer: this.signalBuffer,
|
|
148
|
+
capabilityMatrix,
|
|
149
|
+
camera: this.camera || undefined,
|
|
150
|
+
audio: this.audio || undefined,
|
|
151
|
+
faceModelPath,
|
|
152
|
+
audioModelPath: fs.existsSync(audioModelPath) ? audioModelPath : undefined,
|
|
153
|
+
executionProvider: (this.config.models?.executionProvider || 'cpu'),
|
|
154
|
+
screenId: this.config.screenId,
|
|
155
|
+
venueType: this.config.venueType,
|
|
156
|
+
});
|
|
157
|
+
await this.sensingService.initialize();
|
|
158
|
+
this.sensingService.start();
|
|
159
|
+
this.log('info', 'Audience sensing pipeline started');
|
|
160
|
+
// 11. Start heartbeat telemetry
|
|
161
|
+
this.telemetryScheduler = new edge_core_1.TelemetryScheduler({
|
|
162
|
+
socketManager: this.socketManager,
|
|
163
|
+
fingerprint,
|
|
164
|
+
screenId: this.config.screenId,
|
|
165
|
+
platform: this.platform,
|
|
166
|
+
healthRegistry: this.healthRegistry,
|
|
167
|
+
});
|
|
168
|
+
this.telemetryScheduler.start();
|
|
169
|
+
this.log('info', 'Heartbeat telemetry started (30s interval)');
|
|
170
|
+
// 12. Initialize recovery ladder
|
|
171
|
+
const recoveryCallbacks = {
|
|
172
|
+
onReloadPlayer: async () => {
|
|
173
|
+
if (this.browserManager) {
|
|
174
|
+
await this.browserManager.close();
|
|
175
|
+
await this.browserManager.launch();
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
onRecreatePlayer: async () => {
|
|
179
|
+
if (this.browserManager) {
|
|
180
|
+
await this.browserManager.close();
|
|
181
|
+
await this.browserManager.launch();
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
onRebindCamera: async () => {
|
|
185
|
+
if (this.camera?.isOpen()) {
|
|
186
|
+
await this.camera.close();
|
|
187
|
+
await this.camera.open(this.config.camera?.deviceId);
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
onRebindMicrophone: async () => {
|
|
191
|
+
if (this.audio?.isOpen()) {
|
|
192
|
+
await this.audio.close();
|
|
193
|
+
await this.audio.open(this.config.audio?.deviceId);
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
onRestartSensingService: async () => {
|
|
197
|
+
if (this.sensingService) {
|
|
198
|
+
await this.sensingService.stop();
|
|
199
|
+
await this.sensingService.initialize();
|
|
200
|
+
this.sensingService.start();
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
onRestartDeviceService: async () => {
|
|
204
|
+
this.log('warn', 'Recovery: full service restart requested');
|
|
205
|
+
await this.stop();
|
|
206
|
+
await this.start();
|
|
207
|
+
},
|
|
208
|
+
onEmitRecoveryEvent: (event, details) => {
|
|
209
|
+
this.log('warn', `Recovery event: ${event} ${JSON.stringify(details)}`);
|
|
210
|
+
this.emit('recovery', { event, details, timestamp: Date.now() });
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
this.recoveryLadder = new edge_core_1.RecoveryLadder(this.healthRegistry, recoveryCallbacks, capabilityMatrix.maxRecoveryLevel);
|
|
214
|
+
this.recoveryLadder.start();
|
|
215
|
+
// 13. Launch kiosk browser if enabled
|
|
216
|
+
if (this.config.kiosk?.enabled) {
|
|
217
|
+
try {
|
|
218
|
+
this.browserManager = new edge_ads_1.BrowserManager({
|
|
219
|
+
screenBaseUrl: this.config.kiosk.url || 'https://screen.trillboards.com',
|
|
220
|
+
fingerprint,
|
|
221
|
+
sessionId,
|
|
222
|
+
screenId: this.config.screenId,
|
|
223
|
+
venueType: this.config.venueType,
|
|
224
|
+
platform: this.config.platform,
|
|
225
|
+
browserPath: this.config.kiosk.chromiumPath,
|
|
226
|
+
});
|
|
227
|
+
await this.browserManager.launch();
|
|
228
|
+
this.healthRegistry.updateHealth(edge_core_1.Subsystem.PLAYER, edge_core_1.SubsystemStatus.PLAYING);
|
|
229
|
+
this.log('info', `Kiosk browser launched: ${this.config.kiosk.url || 'https://screen.trillboards.com'}`);
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
this.log('warn', `Kiosk launch failed: ${err instanceof Error ? err.message : err}`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// 14. Initialize federated learning if enabled
|
|
236
|
+
if (this.config.federated?.enabled && capabilityMatrix.federatedLearningEnabled) {
|
|
237
|
+
const machineId = await this.platform.getMachineId();
|
|
238
|
+
this.federatedTrainer = new edge_federated_1.FederatedTrainer(machineId, {
|
|
239
|
+
persistenceDir: dataDir,
|
|
240
|
+
});
|
|
241
|
+
// Start with upload callback that sends gradients via socket
|
|
242
|
+
this.federatedTrainer.start(async (payload) => {
|
|
243
|
+
if (this.socketManager) {
|
|
244
|
+
this.socketManager.emitEvent('gradientUpload', payload);
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
this.log('info', 'Federated learning initialized');
|
|
248
|
+
}
|
|
249
|
+
// Handle graceful shutdown — register only once to prevent listener leak
|
|
250
|
+
if (!this.signalHandlersRegistered) {
|
|
251
|
+
this.boundShutdownSigint = () => this.shutdown('SIGINT');
|
|
252
|
+
this.boundShutdownSigterm = () => this.shutdown('SIGTERM');
|
|
253
|
+
process.on('SIGINT', this.boundShutdownSigint);
|
|
254
|
+
process.on('SIGTERM', this.boundShutdownSigterm);
|
|
255
|
+
this.signalHandlersRegistered = true;
|
|
256
|
+
}
|
|
257
|
+
this.log('info', 'Edge Agent is running. Press Ctrl+C to stop.');
|
|
258
|
+
this.emit('started', { fingerprint, tier });
|
|
259
|
+
}
|
|
260
|
+
catch (err) {
|
|
261
|
+
this.running = false;
|
|
262
|
+
throw err;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
async stop() {
|
|
266
|
+
if (!this.running)
|
|
267
|
+
return;
|
|
268
|
+
this.running = false;
|
|
269
|
+
this.log('info', 'Stopping Edge Agent...');
|
|
270
|
+
if (this.recoveryLadder)
|
|
271
|
+
this.recoveryLadder.stop();
|
|
272
|
+
if (this.telemetryScheduler)
|
|
273
|
+
this.telemetryScheduler.stop();
|
|
274
|
+
if (this.sensingService)
|
|
275
|
+
await this.sensingService.stop();
|
|
276
|
+
if (this.federatedTrainer)
|
|
277
|
+
await this.federatedTrainer.stop();
|
|
278
|
+
if (this.browserManager)
|
|
279
|
+
await this.browserManager.close();
|
|
280
|
+
if (this.socketManager)
|
|
281
|
+
this.socketManager.disconnect();
|
|
282
|
+
if (this.signalBuffer)
|
|
283
|
+
this.signalBuffer.shutdown();
|
|
284
|
+
if (this.healthRegistry)
|
|
285
|
+
this.healthRegistry.dispose();
|
|
286
|
+
// Remove signal handlers to prevent leaks
|
|
287
|
+
if (this.signalHandlersRegistered) {
|
|
288
|
+
if (this.boundShutdownSigint)
|
|
289
|
+
process.removeListener('SIGINT', this.boundShutdownSigint);
|
|
290
|
+
if (this.boundShutdownSigterm)
|
|
291
|
+
process.removeListener('SIGTERM', this.boundShutdownSigterm);
|
|
292
|
+
this.signalHandlersRegistered = false;
|
|
293
|
+
this.boundShutdownSigint = null;
|
|
294
|
+
this.boundShutdownSigterm = null;
|
|
295
|
+
}
|
|
296
|
+
this.log('info', 'Edge Agent stopped.');
|
|
297
|
+
this.emit('stopped');
|
|
298
|
+
}
|
|
299
|
+
async shutdown(signal) {
|
|
300
|
+
this.log('info', `Received ${signal}, shutting down gracefully...`);
|
|
301
|
+
await this.stop();
|
|
302
|
+
process.exit(0);
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Load the platform-specific adapter using require() so that optional
|
|
306
|
+
* dependencies fail gracefully at runtime when not installed.
|
|
307
|
+
*/
|
|
308
|
+
async loadPlatformAdapter() {
|
|
309
|
+
if (this.config.platform === 'windows') {
|
|
310
|
+
try {
|
|
311
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
312
|
+
const { WindowsPlatformAdapter } = require('@trillboards/edge-platform-windows');
|
|
313
|
+
return new WindowsPlatformAdapter();
|
|
314
|
+
}
|
|
315
|
+
catch {
|
|
316
|
+
throw new Error('Windows platform adapter not found. Install: npm install @trillboards/edge-platform-windows');
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
try {
|
|
321
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
322
|
+
const { LinuxPlatformAdapter } = require('@trillboards/edge-platform-linux');
|
|
323
|
+
return new LinuxPlatformAdapter();
|
|
324
|
+
}
|
|
325
|
+
catch {
|
|
326
|
+
throw new Error('Linux platform adapter not found. Install: npm install @trillboards/edge-platform-linux');
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Load the platform-specific camera provider using require() for optional deps.
|
|
332
|
+
*/
|
|
333
|
+
async loadCamera() {
|
|
334
|
+
if (this.config.platform === 'windows') {
|
|
335
|
+
try {
|
|
336
|
+
if (this.config.camera?.rtspUrl) {
|
|
337
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
338
|
+
const { RTSPCameraProvider } = require('@trillboards/edge-platform-windows');
|
|
339
|
+
return new RTSPCameraProvider({ rtspUrl: this.config.camera.rtspUrl });
|
|
340
|
+
}
|
|
341
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
342
|
+
const { DirectShowCameraProvider } = require('@trillboards/edge-platform-windows');
|
|
343
|
+
return new DirectShowCameraProvider({
|
|
344
|
+
width: this.config.camera?.width || 640,
|
|
345
|
+
height: this.config.camera?.height || 480,
|
|
346
|
+
fps: this.config.camera?.fps || 5,
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
catch {
|
|
350
|
+
this.log('warn', 'Windows camera adapter not available');
|
|
351
|
+
return null;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
try {
|
|
356
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
357
|
+
const { V4L2CameraProvider } = require('@trillboards/edge-platform-linux');
|
|
358
|
+
return new V4L2CameraProvider({
|
|
359
|
+
device: this.config.camera?.deviceId || '/dev/video0',
|
|
360
|
+
width: this.config.camera?.width || 640,
|
|
361
|
+
height: this.config.camera?.height || 480,
|
|
362
|
+
fps: this.config.camera?.fps || 5,
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
this.log('warn', 'Linux camera adapter not available');
|
|
367
|
+
return null;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Load the platform-specific audio provider using require() for optional deps.
|
|
373
|
+
*/
|
|
374
|
+
async loadAudio() {
|
|
375
|
+
if (this.config.platform === 'windows') {
|
|
376
|
+
try {
|
|
377
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
378
|
+
const { WindowsAudioProvider } = require('@trillboards/edge-platform-windows');
|
|
379
|
+
return new WindowsAudioProvider();
|
|
380
|
+
}
|
|
381
|
+
catch {
|
|
382
|
+
this.log('warn', 'Windows audio adapter not available');
|
|
383
|
+
return null;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
try {
|
|
388
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
389
|
+
const { PulseAudioProvider } = require('@trillboards/edge-platform-linux');
|
|
390
|
+
return new PulseAudioProvider();
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
this.log('warn', 'Linux audio adapter not available');
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
log(level, message) {
|
|
399
|
+
const configLevel = this.config.logLevel || 'info';
|
|
400
|
+
const levels = ['debug', 'info', 'warn', 'error'];
|
|
401
|
+
if (levels.indexOf(level) >= levels.indexOf(configLevel)) {
|
|
402
|
+
const ts = new Date().toISOString();
|
|
403
|
+
const prefix = `[${ts}] [${level.toUpperCase()}]`;
|
|
404
|
+
if (level === 'error') {
|
|
405
|
+
console.error(`${prefix} ${message}`);
|
|
406
|
+
}
|
|
407
|
+
else if (level === 'warn') {
|
|
408
|
+
console.warn(`${prefix} ${message}`);
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
console.log(`${prefix} ${message}`);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
this.emit('log', { level, message, timestamp: Date.now() });
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
exports.EdgeAgent = EdgeAgent;
|
|
418
|
+
//# sourceMappingURL=EdgeAgent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EdgeAgent.js","sourceRoot":"","sources":["../src/EdgeAgent.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
const config_1 = require("./config");
|
|
38
|
+
const EdgeAgent_1 = require("./EdgeAgent");
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const https = __importStar(require("https"));
|
|
42
|
+
const VERSION = '0.1.0';
|
|
43
|
+
async function main() {
|
|
44
|
+
const args = process.argv.slice(2);
|
|
45
|
+
const command = args[0];
|
|
46
|
+
switch (command) {
|
|
47
|
+
case 'start':
|
|
48
|
+
await startAgent(args.slice(1));
|
|
49
|
+
break;
|
|
50
|
+
case 'download-models':
|
|
51
|
+
await downloadModels(args.slice(1));
|
|
52
|
+
break;
|
|
53
|
+
case 'version':
|
|
54
|
+
case '--version':
|
|
55
|
+
case '-v':
|
|
56
|
+
console.log(`@trillboards/edge-sdk v${VERSION}`);
|
|
57
|
+
break;
|
|
58
|
+
case 'help':
|
|
59
|
+
case '--help':
|
|
60
|
+
case '-h':
|
|
61
|
+
default:
|
|
62
|
+
printHelp();
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function startAgent(args) {
|
|
67
|
+
const configIdx = args.indexOf('--config');
|
|
68
|
+
const configPath = configIdx >= 0 && args[configIdx + 1]
|
|
69
|
+
? args[configIdx + 1]
|
|
70
|
+
: 'trillboards.config.json';
|
|
71
|
+
console.log(`Trillboards Edge AI SDK v${VERSION}`);
|
|
72
|
+
console.log(`Loading config: ${configPath}`);
|
|
73
|
+
const config = (0, config_1.loadConfig)(configPath);
|
|
74
|
+
const agent = new EdgeAgent_1.EdgeAgent(config);
|
|
75
|
+
agent.on('started', ({ fingerprint, tier }) => {
|
|
76
|
+
console.log(`\n Device: ${fingerprint}`);
|
|
77
|
+
console.log(` Tier: TIER_${tier}`);
|
|
78
|
+
console.log(` Screen: ${config.screenId || '(auto-assign)'}`);
|
|
79
|
+
console.log(` API: ${config.apiBaseUrl}`);
|
|
80
|
+
console.log(` Camera: ${config.camera?.enabled ? 'ON' : 'OFF'}`);
|
|
81
|
+
console.log(` Audio: ${config.audio?.enabled ? 'ON' : 'OFF'}`);
|
|
82
|
+
console.log(` Kiosk: ${config.kiosk?.enabled ? 'ON' : 'OFF'}`);
|
|
83
|
+
console.log(` Models: ${config.models?.executionProvider || 'cpu'}`);
|
|
84
|
+
console.log('');
|
|
85
|
+
});
|
|
86
|
+
await agent.start();
|
|
87
|
+
// Keep the process running
|
|
88
|
+
await new Promise(() => { });
|
|
89
|
+
}
|
|
90
|
+
const MODEL_URLS = {
|
|
91
|
+
'blazeface.onnx': 'https://models.trillboards.com/blazeface_128x128.onnx',
|
|
92
|
+
'yamnet.onnx': 'https://models.trillboards.com/yamnet_classification.onnx',
|
|
93
|
+
};
|
|
94
|
+
async function downloadModels(args) {
|
|
95
|
+
const dirIdx = args.indexOf('--dir');
|
|
96
|
+
const modelsDir = dirIdx >= 0 && args[dirIdx + 1] ? args[dirIdx + 1] : './models';
|
|
97
|
+
const resolved = path.resolve(modelsDir);
|
|
98
|
+
if (!fs.existsSync(resolved)) {
|
|
99
|
+
fs.mkdirSync(resolved, { recursive: true });
|
|
100
|
+
}
|
|
101
|
+
console.log(`Downloading ONNX models to: ${resolved}`);
|
|
102
|
+
console.log('');
|
|
103
|
+
for (const [filename, url] of Object.entries(MODEL_URLS)) {
|
|
104
|
+
const dest = path.join(resolved, filename);
|
|
105
|
+
if (fs.existsSync(dest)) {
|
|
106
|
+
console.log(` [SKIP] ${filename} (already exists)`);
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
console.log(` [GET] ${filename}...`);
|
|
110
|
+
try {
|
|
111
|
+
await downloadFile(url, dest);
|
|
112
|
+
const stats = fs.statSync(dest);
|
|
113
|
+
const sizeMb = (stats.size / (1024 * 1024)).toFixed(1);
|
|
114
|
+
console.log(` [OK] ${filename} (${sizeMb} MB)`);
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
console.error(` [FAIL] ${filename}: ${err instanceof Error ? err.message : err}`);
|
|
118
|
+
// Remove partial download
|
|
119
|
+
if (fs.existsSync(dest))
|
|
120
|
+
fs.unlinkSync(dest);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
console.log('\nDone. Set models.dir in your config to point to this directory.');
|
|
124
|
+
}
|
|
125
|
+
function downloadFile(url, dest, maxRedirects = 5) {
|
|
126
|
+
return new Promise((resolve, reject) => {
|
|
127
|
+
if (maxRedirects < 0) {
|
|
128
|
+
reject(new Error('Too many redirects'));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const file = fs.createWriteStream(dest);
|
|
132
|
+
const request = https.get(url, (response) => {
|
|
133
|
+
if (response.statusCode === 301 ||
|
|
134
|
+
response.statusCode === 302 ||
|
|
135
|
+
response.statusCode === 307 ||
|
|
136
|
+
response.statusCode === 308) {
|
|
137
|
+
file.close();
|
|
138
|
+
fs.unlinkSync(dest);
|
|
139
|
+
if (response.headers.location) {
|
|
140
|
+
downloadFile(response.headers.location, dest, maxRedirects - 1).then(resolve, reject);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
reject(new Error('Redirect with no location header'));
|
|
144
|
+
}
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (response.statusCode !== 200) {
|
|
148
|
+
file.close();
|
|
149
|
+
fs.unlinkSync(dest);
|
|
150
|
+
reject(new Error(`HTTP ${response.statusCode}`));
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
response.pipe(file);
|
|
154
|
+
file.on('finish', () => {
|
|
155
|
+
file.close();
|
|
156
|
+
resolve();
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
request.on('error', (err) => {
|
|
160
|
+
file.close();
|
|
161
|
+
if (fs.existsSync(dest))
|
|
162
|
+
fs.unlinkSync(dest);
|
|
163
|
+
reject(err);
|
|
164
|
+
});
|
|
165
|
+
request.setTimeout(30000, () => {
|
|
166
|
+
request.destroy();
|
|
167
|
+
reject(new Error('Download timed out after 30s'));
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
function printHelp() {
|
|
172
|
+
console.log(`
|
|
173
|
+
Trillboards Edge AI SDK v${VERSION}
|
|
174
|
+
|
|
175
|
+
Usage:
|
|
176
|
+
trillboards-edge start [--config <path>] Start the edge agent
|
|
177
|
+
trillboards-edge download-models [--dir <path>] Download ONNX models
|
|
178
|
+
trillboards-edge version Show version
|
|
179
|
+
trillboards-edge help Show this help
|
|
180
|
+
|
|
181
|
+
Examples:
|
|
182
|
+
# Quick start with default config
|
|
183
|
+
trillboards-edge start --config trillboards.config.json
|
|
184
|
+
|
|
185
|
+
# Download models first
|
|
186
|
+
trillboards-edge download-models --dir ./models
|
|
187
|
+
|
|
188
|
+
# Use with npx (no global install)
|
|
189
|
+
npx @trillboards/edge-sdk start --config trillboards.config.json
|
|
190
|
+
|
|
191
|
+
Config file (trillboards.config.json):
|
|
192
|
+
{
|
|
193
|
+
"apiBaseUrl": "https://api.trillboards.com",
|
|
194
|
+
"deviceToken": "your-device-token",
|
|
195
|
+
"screenId": "your-screen-id",
|
|
196
|
+
"camera": { "enabled": true },
|
|
197
|
+
"audio": { "enabled": true },
|
|
198
|
+
"models": { "dir": "./models", "executionProvider": "cpu" },
|
|
199
|
+
"kiosk": { "enabled": true }
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
Supported platforms:
|
|
203
|
+
- Linux (Ubuntu 18.04+, Debian 10+, ARM64/x64)
|
|
204
|
+
- Windows 10+ (x64)
|
|
205
|
+
|
|
206
|
+
Execution providers:
|
|
207
|
+
- cpu Default, works everywhere
|
|
208
|
+
- openvino Intel HD 620+ (Backpackster)
|
|
209
|
+
- directml Windows GPU (DirectX 12)
|
|
210
|
+
- cuda NVIDIA GPU (requires CUDA toolkit)
|
|
211
|
+
`);
|
|
212
|
+
}
|
|
213
|
+
main().catch((err) => {
|
|
214
|
+
console.error(`Fatal error: ${err instanceof Error ? err.message : err}`);
|
|
215
|
+
process.exit(1);
|
|
216
|
+
});
|
|
217
|
+
//# sourceMappingURL=cli.js.map
|