@trillboards/edge-sdk 0.2.2 → 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 +4 -3
@@ -0,0 +1,95 @@
1
+ # Default values for trillboards-edge Helm chart
2
+
3
+ # Image configuration
4
+ image:
5
+ repository: trillboards/edge-sdk
6
+ tag: "latest"
7
+ pullPolicy: Always
8
+
9
+ # Available tags: latest (CPU), cuda (NVIDIA GPU), openvino (Intel GPU)
10
+ # Override per-node using nodeSelector + separate releases if heterogeneous fleet
11
+
12
+ # Trillboards API configuration
13
+ api:
14
+ baseUrl: "https://api.trillboards.com"
15
+
16
+ # Device token — create a Kubernetes secret:
17
+ # kubectl create secret generic trillboards-edge --from-literal=device-token=YOUR_TOKEN
18
+ deviceToken:
19
+ existingSecret: "trillboards-edge"
20
+ secretKey: "device-token"
21
+
22
+ # Sensing configuration
23
+ sensing:
24
+ camera:
25
+ enabled: true
26
+ audio:
27
+ enabled: true
28
+ kiosk:
29
+ enabled: false
30
+ url: "https://screen.trillboards.com"
31
+ executionProvider: "cpu" # cpu, openvino, directml, cuda
32
+ logLevel: "info"
33
+
34
+ # Resource limits
35
+ resources:
36
+ requests:
37
+ cpu: "250m"
38
+ memory: "256Mi"
39
+ limits:
40
+ cpu: "1000m"
41
+ memory: "1Gi"
42
+
43
+ # GPU resources (for CUDA/OpenVINO images)
44
+ gpu:
45
+ enabled: false
46
+ # nvidia.com/gpu: 1
47
+
48
+ # Status server
49
+ statusServer:
50
+ port: 9090
51
+
52
+ # Prometheus scraping
53
+ prometheus:
54
+ enabled: true
55
+ port: 9090
56
+ path: "/metrics"
57
+
58
+ # Health probes
59
+ probes:
60
+ liveness:
61
+ initialDelaySeconds: 30
62
+ periodSeconds: 30
63
+ readiness:
64
+ initialDelaySeconds: 10
65
+ periodSeconds: 10
66
+
67
+ # Model storage — hostPath for persistent models across restarts
68
+ models:
69
+ hostPath: "/opt/trillboards/models"
70
+
71
+ # Data storage — hostPath for signal buffer, device identity, etc.
72
+ data:
73
+ hostPath: "/opt/trillboards/data"
74
+
75
+ # Node scheduling
76
+ nodeSelector:
77
+ trillboards.com/edge-device: "true"
78
+
79
+ tolerations:
80
+ - key: "edge"
81
+ operator: "Exists"
82
+ effect: "NoSchedule"
83
+
84
+ affinity: {}
85
+
86
+ # DaemonSet update strategy
87
+ updateStrategy:
88
+ type: RollingUpdate
89
+ rollingUpdate:
90
+ maxUnavailable: 1
91
+
92
+ # Security context
93
+ securityContext:
94
+ privileged: false
95
+ readOnlyRootFilesystem: false
@@ -0,0 +1,144 @@
1
+ # Trillboards Edge SDK — Kubernetes DaemonSet
2
+ # Deploys one edge agent per node for fleet-wide audience sensing
3
+ #
4
+ # Usage:
5
+ # kubectl create secret generic trillboards-edge \
6
+ # --from-literal=device-token=YOUR_TOKEN
7
+ # kubectl apply -f daemonset.yaml
8
+ #
9
+ # For GPU nodes, use the CUDA image and add NVIDIA tolerations.
10
+
11
+ apiVersion: apps/v1
12
+ kind: DaemonSet
13
+ metadata:
14
+ name: trillboards-edge-agent
15
+ namespace: default
16
+ labels:
17
+ app: trillboards-edge
18
+ component: agent
19
+ spec:
20
+ selector:
21
+ matchLabels:
22
+ app: trillboards-edge
23
+ updateStrategy:
24
+ type: RollingUpdate
25
+ rollingUpdate:
26
+ maxUnavailable: 1
27
+ template:
28
+ metadata:
29
+ labels:
30
+ app: trillboards-edge
31
+ component: agent
32
+ annotations:
33
+ prometheus.io/scrape: "true"
34
+ prometheus.io/port: "9090"
35
+ prometheus.io/path: "/metrics"
36
+ spec:
37
+ terminationGracePeriodSeconds: 30
38
+ containers:
39
+ - name: edge-agent
40
+ image: trillboards/edge-sdk:latest
41
+ imagePullPolicy: Always
42
+ ports:
43
+ - name: status
44
+ containerPort: 9090
45
+ protocol: TCP
46
+ env:
47
+ - name: DEVICE_TOKEN
48
+ valueFrom:
49
+ secretKeyRef:
50
+ name: trillboards-edge
51
+ key: device-token
52
+ - name: SCREEN_ID
53
+ valueFrom:
54
+ fieldRef:
55
+ fieldPath: spec.nodeName
56
+ - name: API_BASE_URL
57
+ value: "https://api.trillboards.com"
58
+ - name: CAMERA_ENABLED
59
+ value: "true"
60
+ - name: AUDIO_ENABLED
61
+ value: "true"
62
+ - name: KIOSK_ENABLED
63
+ value: "false"
64
+ - name: EXECUTION_PROVIDER
65
+ value: "cpu"
66
+ - name: LOG_LEVEL
67
+ value: "info"
68
+ - name: NODE_NAME
69
+ valueFrom:
70
+ fieldRef:
71
+ fieldPath: spec.nodeName
72
+ resources:
73
+ requests:
74
+ cpu: "250m"
75
+ memory: "256Mi"
76
+ limits:
77
+ cpu: "1000m"
78
+ memory: "1Gi"
79
+ livenessProbe:
80
+ httpGet:
81
+ path: /health
82
+ port: status
83
+ initialDelaySeconds: 30
84
+ periodSeconds: 30
85
+ timeoutSeconds: 5
86
+ failureThreshold: 3
87
+ readinessProbe:
88
+ httpGet:
89
+ path: /health
90
+ port: status
91
+ initialDelaySeconds: 10
92
+ periodSeconds: 10
93
+ timeoutSeconds: 3
94
+ failureThreshold: 2
95
+ volumeMounts:
96
+ - name: models
97
+ mountPath: /app/models
98
+ - name: data
99
+ mountPath: /app/data
100
+ # Mount camera device if available
101
+ - name: video-devices
102
+ mountPath: /dev
103
+ readOnly: true
104
+ securityContext:
105
+ privileged: false
106
+ readOnlyRootFilesystem: false
107
+ volumes:
108
+ - name: models
109
+ hostPath:
110
+ path: /opt/trillboards/models
111
+ type: DirectoryOrCreate
112
+ - name: data
113
+ hostPath:
114
+ path: /opt/trillboards/data
115
+ type: DirectoryOrCreate
116
+ - name: video-devices
117
+ hostPath:
118
+ path: /dev
119
+ type: Directory
120
+ # Schedule on edge nodes only
121
+ nodeSelector:
122
+ trillboards.com/edge-device: "true"
123
+ tolerations:
124
+ - key: "edge"
125
+ operator: "Exists"
126
+ effect: "NoSchedule"
127
+ ---
128
+ # Service for status endpoint access
129
+ apiVersion: v1
130
+ kind: Service
131
+ metadata:
132
+ name: trillboards-edge-status
133
+ namespace: default
134
+ labels:
135
+ app: trillboards-edge
136
+ spec:
137
+ selector:
138
+ app: trillboards-edge
139
+ ports:
140
+ - name: status
141
+ port: 9090
142
+ targetPort: status
143
+ protocol: TCP
144
+ clusterIP: None # Headless — each pod addressable individually
@@ -0,0 +1,113 @@
1
+ /**
2
+ * CommandRouter — Routes incoming `deviceCommand` socket events to
3
+ * the appropriate handler and reports results back to the caller.
4
+ *
5
+ * Supported commands:
6
+ * config.push — Hot-push sensing/VAS/full config
7
+ * device.screenshot — Capture + upload a screenshot to S3
8
+ * power.sleep — DPMS display off
9
+ * power.wake — DPMS display on
10
+ * kiosk.reload — Reload kiosk browser
11
+ * device.restart — Restart the edge agent process
12
+ * device.ping — Heartbeat ping/pong
13
+ * device.info — Return host system information
14
+ */
15
+ import { EventEmitter } from 'events';
16
+ /**
17
+ * Capabilities injected by EdgeAgent when constructing the CommandRouter.
18
+ * Each function encapsulates a side-effect the router delegates to rather
19
+ * than performing directly — this keeps the router unit-testable.
20
+ */
21
+ export interface CommandContext {
22
+ reloadKiosk: () => Promise<void>;
23
+ captureScreenshot: () => Promise<Buffer | null>;
24
+ getUploadUrl: (type: string) => Promise<string | null>;
25
+ uploadToS3: (url: string, data: Buffer, contentType: string) => Promise<boolean>;
26
+ setSleepMode: (sleep: boolean) => Promise<void>;
27
+ restartDevice: () => Promise<void>;
28
+ updateConfig: (configPatch: Record<string, unknown>) => Promise<void>;
29
+ }
30
+ /**
31
+ * Shape of the `deviceCommand` event payload received from the backend.
32
+ * Matches the server-side dispatcher: `{ commandId, command, payload, ... }`.
33
+ */
34
+ export interface DeviceCommand {
35
+ commandId: string;
36
+ command: string;
37
+ payload?: Record<string, unknown>;
38
+ timestamp?: number;
39
+ }
40
+ /**
41
+ * Outcome of executing a single command — sent back to the server
42
+ * via `deviceCommandStatus`.
43
+ */
44
+ export interface CommandResult {
45
+ commandId: string;
46
+ command: string;
47
+ status: 'completed' | 'failed' | 'unsupported';
48
+ result?: unknown;
49
+ error?: string;
50
+ durationMs: number;
51
+ }
52
+ export declare class CommandRouter extends EventEmitter {
53
+ private readonly context;
54
+ private readonly commandHistory;
55
+ private readonly maxHistory;
56
+ private readonly startedAt;
57
+ constructor(context: CommandContext, maxHistory?: number);
58
+ /**
59
+ * Route and execute an incoming device command.
60
+ * Returns the `CommandResult` which the caller should send back via socket.
61
+ *
62
+ * This method **never throws** — every failure path is captured in
63
+ * the result with `status: 'failed'` and a human-readable error message.
64
+ */
65
+ handleCommand(cmd: DeviceCommand): Promise<CommandResult>;
66
+ /**
67
+ * Return a shallow copy of the recent command history, newest-first.
68
+ */
69
+ getHistory(): CommandResult[];
70
+ private dispatch;
71
+ /**
72
+ * config.push — Update sensing/VAS config.
73
+ * Payload: `{ type: 'sensing' | 'vas' | 'full', config: {...} }`
74
+ */
75
+ private handleConfigPush;
76
+ /**
77
+ * device.screenshot — Capture kiosk screenshot, upload to S3.
78
+ * 1. captureScreenshot() -> Buffer | null
79
+ * 2. getUploadUrl('screenshot') -> presigned URL
80
+ * 3. uploadToS3(url, buffer, 'image/png')
81
+ */
82
+ private handleScreenshot;
83
+ /**
84
+ * power.sleep — Put the display to sleep via DPMS.
85
+ */
86
+ private handlePowerSleep;
87
+ /**
88
+ * power.wake — Wake the display from DPMS sleep.
89
+ */
90
+ private handlePowerWake;
91
+ /**
92
+ * kiosk.reload — Reload the kiosk browser page.
93
+ */
94
+ private handleKioskReload;
95
+ /**
96
+ * device.restart — Restart the edge agent process.
97
+ *
98
+ * Note: after calling `context.restartDevice()`, this process may terminate
99
+ * before the result can be sent. The caller should emit the ack/status
100
+ * *before* actually restarting if reliable delivery matters.
101
+ */
102
+ private handleDeviceRestart;
103
+ /**
104
+ * device.ping — Simple liveness check. Returns a pong with server timestamp.
105
+ */
106
+ private handleDevicePing;
107
+ /**
108
+ * device.info — Return system information useful for remote diagnostics.
109
+ */
110
+ private handleDeviceInfo;
111
+ private recordHistory;
112
+ }
113
+ //# sourceMappingURL=CommandRouter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommandRouter.d.ts","sourceRoot":"","sources":["../src/CommandRouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAKtC;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAChD,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACvD,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjF,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,YAAY,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,aAAa,CAAC;IAC/C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAiBD,qBAAa,aAAc,SAAQ,YAAY;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAuB;IACtD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,OAAO,EAAE,cAAc,EAAE,UAAU,SAAM;IASrD;;;;;;OAMG;IACG,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAuB/D;;OAEG;IACH,UAAU,IAAI,aAAa,EAAE;YAMf,QAAQ;IA+BtB;;;OAGG;YACW,gBAAgB;IAoC9B;;;;;OAKG;YACW,gBAAgB;IAwD9B;;OAEG;YACW,gBAAgB;IAqB9B;;OAEG;YACW,eAAe;IAqB7B;;OAEG;YACW,iBAAiB;IAqB/B;;;;;;OAMG;YACW,mBAAmB;IAqBjC;;OAEG;YACW,gBAAgB;IAU9B;;OAEG;YACW,gBAAgB;IAsC9B,OAAO,CAAC,aAAa;CAMtB"}