@trillboards/edge-sdk 0.2.4 → 0.2.7

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 (204) hide show
  1. package/README.md +4 -3
  2. package/deploy/docker/Dockerfile.cloud-sense +117 -0
  3. package/deploy/docker/Dockerfile.cpu +30 -21
  4. package/deploy/docker/Dockerfile.cuda +30 -21
  5. package/deploy/docker/Dockerfile.openvino +30 -20
  6. package/deploy/docker/README.md +9 -5
  7. package/deploy/docker/connector-entrypoint.sh +122 -0
  8. package/deploy/helm/README.md +1 -1
  9. package/deploy/k8s/daemonset.yaml +1 -1
  10. package/deploy/macos/README.md +161 -0
  11. package/deploy/macos/TrillboardsSetupApp.m +603 -0
  12. package/deploy/macos/build-macos-pkg.sh +588 -0
  13. package/deploy/macos/com.trillboards.edge.plist +62 -0
  14. package/deploy/macos/com.trillboards.litertlm.plist +45 -0
  15. package/deploy/macos/pair.command +519 -0
  16. package/deploy/macos/scripts/ensure-litertlm.sh +62 -0
  17. package/deploy/macos/scripts/postinstall +153 -0
  18. package/deploy/macos/scripts/setup-litertlm.sh +272 -0
  19. package/deploy/macos/test-install-pair.sh +383 -0
  20. package/deploy/macos/test-setup-litertlm-reinstall.sh +109 -0
  21. package/deploy/systemd/install.sh +25 -15
  22. package/deploy/systemd/trillboards-edge.service +4 -1
  23. package/deploy/windows/README.md +70 -0
  24. package/deploy/windows/build-windows.ps1 +225 -0
  25. package/deploy/windows/bundle-windows-installer.ps1 +153 -0
  26. package/deploy/windows/check-feeds.js +26 -0
  27. package/deploy/windows/e2e/fixtures/person.jpg +0 -0
  28. package/deploy/windows/e2e/test-local-sense.ps1 +185 -0
  29. package/deploy/windows/install-service.ps1 +6 -1
  30. package/deploy/windows/install-update.ps1 +101 -0
  31. package/deploy/windows/installer.nsi +138 -0
  32. package/deploy/windows/register-litertlm-task.ps1 +42 -0
  33. package/deploy/windows/register-task.ps1 +44 -0
  34. package/deploy/windows/run-connector.ps1 +69 -0
  35. package/deploy/windows/setup-litertlm.ps1 +361 -0
  36. package/deploy/windows/stop-existing.ps1 +72 -0
  37. package/deploy/windows/trillboards-edge-task.vbs +25 -0
  38. package/deploy/windows/trillboards-edge.cmd +33 -0
  39. package/deploy/windows/trillboards-pair.cmd +276 -0
  40. package/deploy/windows/trillboards-setup.ps1 +456 -0
  41. package/deploy/windows/trillboards-setup.vbs +13 -0
  42. package/dist/AudienceAnalyzeClient.d.ts +136 -0
  43. package/dist/AudienceAnalyzeClient.d.ts.map +1 -0
  44. package/dist/AudienceAnalyzeClient.js +246 -0
  45. package/dist/AudienceAnalyzeClient.js.map +1 -0
  46. package/dist/ChannelProber.d.ts +150 -0
  47. package/dist/ChannelProber.d.ts.map +1 -0
  48. package/dist/ChannelProber.js +887 -0
  49. package/dist/ChannelProber.js.map +1 -0
  50. package/dist/CloudEscalationPolicy.d.ts +143 -0
  51. package/dist/CloudEscalationPolicy.d.ts.map +1 -0
  52. package/dist/CloudEscalationPolicy.js +137 -0
  53. package/dist/CloudEscalationPolicy.js.map +1 -0
  54. package/dist/CloudSensingManager.d.ts +557 -0
  55. package/dist/CloudSensingManager.d.ts.map +1 -0
  56. package/dist/CloudSensingManager.js +1267 -0
  57. package/dist/CloudSensingManager.js.map +1 -0
  58. package/dist/DiscoveryReportClient.d.ts +66 -0
  59. package/dist/DiscoveryReportClient.d.ts.map +1 -0
  60. package/dist/DiscoveryReportClient.js +85 -0
  61. package/dist/DiscoveryReportClient.js.map +1 -0
  62. package/dist/EdgeAgent.d.ts +12 -2
  63. package/dist/EdgeAgent.d.ts.map +1 -1
  64. package/dist/EdgeAgent.js +55 -13
  65. package/dist/EdgeAgent.js.map +1 -1
  66. package/dist/LiteRtVlmProvider.d.ts +193 -0
  67. package/dist/LiteRtVlmProvider.d.ts.map +1 -0
  68. package/dist/LiteRtVlmProvider.js +436 -0
  69. package/dist/LiteRtVlmProvider.js.map +1 -0
  70. package/dist/MosaicSource.d.ts +108 -0
  71. package/dist/MosaicSource.d.ts.map +1 -0
  72. package/dist/MosaicSource.js +274 -0
  73. package/dist/MosaicSource.js.map +1 -0
  74. package/dist/OnvifClient.d.ts +83 -0
  75. package/dist/OnvifClient.d.ts.map +1 -0
  76. package/dist/OnvifClient.js +209 -0
  77. package/dist/OnvifClient.js.map +1 -0
  78. package/dist/PairClient.d.ts +106 -0
  79. package/dist/PairClient.d.ts.map +1 -0
  80. package/dist/PairClient.js +186 -0
  81. package/dist/PairClient.js.map +1 -0
  82. package/dist/RecorderAddressRecovery.d.ts +53 -0
  83. package/dist/RecorderAddressRecovery.d.ts.map +1 -0
  84. package/dist/RecorderAddressRecovery.js +359 -0
  85. package/dist/RecorderAddressRecovery.js.map +1 -0
  86. package/dist/SceneChangeDetector.d.ts +291 -0
  87. package/dist/SceneChangeDetector.d.ts.map +1 -0
  88. package/dist/SceneChangeDetector.js +682 -0
  89. package/dist/SceneChangeDetector.js.map +1 -0
  90. package/dist/SensingProfileClient.d.ts +59 -0
  91. package/dist/SensingProfileClient.d.ts.map +1 -0
  92. package/dist/SensingProfileClient.js +78 -0
  93. package/dist/SensingProfileClient.js.map +1 -0
  94. package/dist/SetupSessionClient.d.ts +114 -0
  95. package/dist/SetupSessionClient.d.ts.map +1 -0
  96. package/dist/SetupSessionClient.js +95 -0
  97. package/dist/SetupSessionClient.js.map +1 -0
  98. package/dist/VlmAdmissionGate.d.ts +126 -0
  99. package/dist/VlmAdmissionGate.d.ts.map +1 -0
  100. package/dist/VlmAdmissionGate.js +166 -0
  101. package/dist/VlmAdmissionGate.js.map +1 -0
  102. package/dist/autoSense.d.ts +266 -0
  103. package/dist/autoSense.d.ts.map +1 -0
  104. package/dist/autoSense.js +606 -0
  105. package/dist/autoSense.js.map +1 -0
  106. package/dist/cli.d.ts +27 -1
  107. package/dist/cli.d.ts.map +1 -1
  108. package/dist/cli.js +526 -27
  109. package/dist/cli.js.map +1 -1
  110. package/dist/combinedSense.d.ts +128 -0
  111. package/dist/combinedSense.d.ts.map +1 -0
  112. package/dist/combinedSense.js +261 -0
  113. package/dist/combinedSense.js.map +1 -0
  114. package/dist/config.d.ts +351 -0
  115. package/dist/config.d.ts.map +1 -1
  116. package/dist/config.js +99 -2
  117. package/dist/config.js.map +1 -1
  118. package/dist/connectorCadence.d.ts +135 -0
  119. package/dist/connectorCadence.d.ts.map +1 -0
  120. package/dist/connectorCadence.js +151 -0
  121. package/dist/connectorCadence.js.map +1 -0
  122. package/dist/dataDir.d.ts +33 -0
  123. package/dist/dataDir.d.ts.map +1 -0
  124. package/dist/dataDir.js +76 -0
  125. package/dist/dataDir.js.map +1 -0
  126. package/dist/deployedCadence.d.ts +167 -0
  127. package/dist/deployedCadence.d.ts.map +1 -0
  128. package/dist/deployedCadence.js +209 -0
  129. package/dist/deployedCadence.js.map +1 -0
  130. package/dist/deployedCadenceSource.d.ts +48 -0
  131. package/dist/deployedCadenceSource.d.ts.map +1 -0
  132. package/dist/deployedCadenceSource.js +74 -0
  133. package/dist/deployedCadenceSource.js.map +1 -0
  134. package/dist/diagnose.d.ts +1 -1
  135. package/dist/diagnose.d.ts.map +1 -1
  136. package/dist/diagnose.js +15 -13
  137. package/dist/diagnose.js.map +1 -1
  138. package/dist/discovery.d.ts +131 -0
  139. package/dist/discovery.d.ts.map +1 -0
  140. package/dist/discovery.js +499 -0
  141. package/dist/discovery.js.map +1 -0
  142. package/dist/gemmaModelOta.d.ts +118 -0
  143. package/dist/gemmaModelOta.d.ts.map +1 -0
  144. package/dist/gemmaModelOta.js +291 -0
  145. package/dist/gemmaModelOta.js.map +1 -0
  146. package/dist/index.d.ts +16 -1
  147. package/dist/index.d.ts.map +1 -1
  148. package/dist/index.js +40 -1
  149. package/dist/index.js.map +1 -1
  150. package/dist/init.d.ts.map +1 -1
  151. package/dist/init.js +25 -87
  152. package/dist/init.js.map +1 -1
  153. package/dist/keepAwake.d.ts +33 -0
  154. package/dist/keepAwake.d.ts.map +1 -0
  155. package/dist/keepAwake.js +54 -0
  156. package/dist/keepAwake.js.map +1 -0
  157. package/dist/legacyRecorderProfile.d.ts +20 -0
  158. package/dist/legacyRecorderProfile.d.ts.map +1 -0
  159. package/dist/legacyRecorderProfile.js +27 -0
  160. package/dist/legacyRecorderProfile.js.map +1 -0
  161. package/dist/localInferenceSchema.d.ts +132 -0
  162. package/dist/localInferenceSchema.d.ts.map +1 -0
  163. package/dist/localInferenceSchema.js +274 -0
  164. package/dist/localInferenceSchema.js.map +1 -0
  165. package/dist/localSenseE2eHarness.d.ts +101 -0
  166. package/dist/localSenseE2eHarness.d.ts.map +1 -0
  167. package/dist/localSenseE2eHarness.js +279 -0
  168. package/dist/localSenseE2eHarness.js.map +1 -0
  169. package/dist/localSensing.d.ts +284 -0
  170. package/dist/localSensing.d.ts.map +1 -0
  171. package/dist/localSensing.js +512 -0
  172. package/dist/localSensing.js.map +1 -0
  173. package/dist/mcp-server.d.ts.map +1 -1
  174. package/dist/mcp-server.js +3 -1
  175. package/dist/mcp-server.js.map +1 -1
  176. package/dist/modelIntegrity.d.ts +80 -0
  177. package/dist/modelIntegrity.d.ts.map +1 -0
  178. package/dist/modelIntegrity.js +194 -0
  179. package/dist/modelIntegrity.js.map +1 -0
  180. package/dist/pairVerify.d.ts +100 -0
  181. package/dist/pairVerify.d.ts.map +1 -0
  182. package/dist/pairVerify.js +296 -0
  183. package/dist/pairVerify.js.map +1 -0
  184. package/dist/qrScanner.d.ts +33 -0
  185. package/dist/qrScanner.d.ts.map +1 -0
  186. package/dist/qrScanner.js +103 -0
  187. package/dist/qrScanner.js.map +1 -0
  188. package/dist/runtimePaths.d.ts +10 -0
  189. package/dist/runtimePaths.d.ts.map +1 -0
  190. package/dist/runtimePaths.js +79 -0
  191. package/dist/runtimePaths.js.map +1 -0
  192. package/dist/sensingRunMode.d.ts +86 -0
  193. package/dist/sensingRunMode.d.ts.map +1 -0
  194. package/dist/sensingRunMode.js +346 -0
  195. package/dist/sensingRunMode.js.map +1 -0
  196. package/dist/setupMode.d.ts +98 -0
  197. package/dist/setupMode.d.ts.map +1 -0
  198. package/dist/setupMode.js +828 -0
  199. package/dist/setupMode.js.map +1 -0
  200. package/dist/setupProgress.d.ts +31 -0
  201. package/dist/setupProgress.d.ts.map +1 -0
  202. package/dist/setupProgress.js +173 -0
  203. package/dist/setupProgress.js.map +1 -0
  204. package/package.json +13 -4
@@ -0,0 +1,276 @@
1
+ @echo off
2
+ REM Trillboards first-run pairing helper — STAGED and HONEST. Every claim it
3
+ REM prints is verified first (the Hiten failure was this script claiming
4
+ REM "connected" while the TrillboardsEdge scheduled task was never registered
5
+ REM and zero frames had ever been proven):
6
+ REM [1] pair code -> config (device token delivered ONLY here)
7
+ REM [2] connection authenticated round-trip via `verify-connection`
8
+ REM [3] service scheduled task EXISTS (auto-repair via register-task.ps1)
9
+ REM [4] running task actually STARTED (state polled, locale-safe via PS)
10
+ REM RESUMABLE: if a verified config already exists it skips straight to the
11
+ REM service stages — re-running after a network/service fix needs NO new code.
12
+ setlocal
13
+ set "UI_MODE=0"
14
+ set "UI_STATUS_FILE="
15
+
16
+ :parse_args
17
+ if "%~1"=="" goto :args_done
18
+ if /I "%~1"=="--setup" (
19
+ set "UI_MODE=1"
20
+ shift /1
21
+ goto :parse_args
22
+ )
23
+ if /I "%~1"=="--status-file" (
24
+ set "UI_STATUS_FILE=%~2"
25
+ shift /1
26
+ shift /1
27
+ goto :parse_args
28
+ )
29
+ shift /1
30
+ goto :parse_args
31
+
32
+ :args_done
33
+ for %%I in ("%~dp0..") do set "ROOT=%%~fI"
34
+ set "CFG=%ROOT%\trillboards.config.json"
35
+ set "LOGDIR=%LOCALAPPDATA%\Trillboards\logs"
36
+ set "LOG=%LOGDIR%\pairing.log"
37
+ set "TASK=TrillboardsEdge"
38
+ if not exist "%LOGDIR%" mkdir "%LOGDIR%" >nul 2>&1
39
+
40
+ echo ==================================================
41
+ echo Trillboards camera pairing
42
+ echo ==================================================
43
+ echo.
44
+
45
+ REM Caution (non-blocking): sensing stops if this machine sleeps or turns off.
46
+ powershell -NoProfile -NonInteractive -Command "$b=Get-CimInstance Win32_Battery -ErrorAction SilentlyContinue; if($b -and $b.BatteryStatus -eq 1){ exit 0 }; exit 1" >nul 2>&1
47
+ if not errorlevel 1 (
48
+ echo NOTE: this computer is on battery. It must stay ON and PLUGGED IN for
49
+ echo your cameras to keep reporting. The connector prevents sleep while it
50
+ echo runs, but a closed lid / shutdown still stops it.
51
+ echo.
52
+ )
53
+
54
+ REM ── Resume path: a saved, complete pairing skips the code prompt. Branch on
55
+ REM WHY verification failed: only an auth rejection (3) or a token-less config
56
+ REM (4) needs a new code — a network/server failure (2/5) means the saved
57
+ REM pairing is fine and the operator just fixes connectivity (NO new code).
58
+ if not exist "%CFG%" goto :ask_code
59
+ "%~dp0node.exe" "%~dp0check-feeds.js" "%CFG%" >nul 2>&1
60
+ if errorlevel 1 goto :ask_code
61
+ call "%~dp0trillboards-edge.cmd" verify-connection --config "%CFG%" >nul 2>&1
62
+ set "VERIFY_RC=%ERRORLEVEL%"
63
+ if "%VERIFY_RC%"=="0" (
64
+ echo Already paired on this computer ^(connection verified^) — checking the
65
+ echo background service...
66
+ echo [%date% %time%] resume: existing config verified >> "%LOG%"
67
+ goto :ensure_task
68
+ )
69
+ if "%VERIFY_RC%"=="2" goto :resume_offline
70
+ if "%VERIFY_RC%"=="5" goto :resume_offline
71
+ goto :ask_code
72
+
73
+ :resume_offline
74
+ echo This computer already has a saved Trillboards pairing, but it can't reach
75
+ echo Trillboards right now. Check the internet connection ^(Wi-Fi/ethernet,
76
+ echo firewall^), then re-open "Pair a camera" — you will NOT need a new code.
77
+ echo [%date% %time%] resume: saved config, connection check failed ^(rc=%VERIFY_RC%^) >> "%LOG%"
78
+ call :write_ui_status error "This computer is offline" "Check the internet connection, then try again. Your saved pairing is still secure."
79
+ goto :done_fail
80
+
81
+ :ask_code
82
+ REM Dual-mode entry. DEFAULT (just press Enter) = the validate-first SETUP flow:
83
+ REM this window shows a short code, you type it into the portal, and the portal
84
+ REM proves every camera stream BEFORE anything is created. Pasting a code from
85
+ REM the portal's classic Install step keeps the legacy claim-code flow working
86
+ REM (old wizard versions, scripted installs).
87
+ if "%UI_MODE%"=="1" goto :setup_mode
88
+ echo Press ENTER to start camera setup (this window will show you a code
89
+ echo to type into the Trillboards portal).
90
+ echo.
91
+ echo Or, if the portal already gave you a code (classic flow), paste it here.
92
+ echo.
93
+ set "CODE="
94
+ set /p CODE="Code (or press Enter): "
95
+ if "%CODE%"=="" goto :setup_mode
96
+
97
+ call "%~dp0trillboards-edge.cmd" pair --code "%CODE%" --config "%CFG%"
98
+ set "PAIR_RC=%ERRORLEVEL%"
99
+ if "%PAIR_RC%"=="0" goto :paired
100
+ if "%PAIR_RC%"=="7" (
101
+ REM Paired but the API REJECTED the fresh pairing (auth). Unlike rc=6, the
102
+ REM saved config is unusable — the owner genuinely needs a new code.
103
+ echo.
104
+ echo Trillboards rejected this new pairing. Generate a FRESH code in the
105
+ echo portal and run "Pair a camera" again.
106
+ echo [%date% %time%] pair: saved but auth-rejected ^(rc=7^) >> "%LOG%"
107
+ goto :done_fail
108
+ )
109
+ if "%PAIR_RC%"=="6" (
110
+ REM Paired + saved, but the connection check failed. The CLI already printed
111
+ REM the real reason (network/server) — the code is SPENT but NOT wasted.
112
+ echo.
113
+ echo Your pairing is saved on this computer. Fix the connection issue above,
114
+ echo then re-open "Pair a camera" from the Start Menu — it will pick up where
115
+ echo you left off. You will NOT need a new code.
116
+ echo [%date% %time%] pair: saved but unverified ^(rc=6^) >> "%LOG%"
117
+ goto :done_fail
118
+ )
119
+ REM Hard pair failure — the CLI printed the classified reason (bad/expired code,
120
+ REM network, rate-limit, server). Do NOT add the old blanket "double-check the
121
+ REM code" here: for non-code failures that message was a lie.
122
+ echo [%date% %time%] pair: failed ^(rc=%PAIR_RC%^) >> "%LOG%"
123
+ goto :done_fail
124
+
125
+ :paired
126
+ REM Gate on RTSP URLs before starting, mirroring the macOS pair.command guard:
127
+ REM the creds-stay-on-prem pair path returns cameras WITHOUT an rtspUrl (written
128
+ REM as empty placeholders) and pairing still exits 0, but cloud-sense would skip
129
+ REM the URL-less feeds and exit with nothing - so do NOT start the task or claim
130
+ REM "connected" until every feed has its rtsp:// URL (Codex P2 on #7731).
131
+ "%~dp0node.exe" "%~dp0check-feeds.js" "%CFG%"
132
+ if errorlevel 1 (
133
+ echo.
134
+ echo Paired, but one or more camera feeds still need an RTSP URL.
135
+ echo Camera credentials stay on this PC. Add the rtsp:// URL^(s^) to:
136
+ echo "%CFG%"
137
+ echo then re-run this pairing helper to start. The connector was NOT
138
+ echo started yet, so it won't keep restarting on an incomplete config.
139
+ echo [%date% %time%] pair: ok, feeds missing rtspUrl — not started >> "%LOG%"
140
+ call :write_ui_status error "Camera links are incomplete" "One or more cameras still need a stream link. Contact Trillboards support."
141
+ goto :done_fail
142
+ )
143
+ goto :ensure_task
144
+
145
+
146
+ :setup_mode
147
+ REM ── Validate-first setup: the CLI displays the code, keeps this window's
148
+ REM staged progress, and exits 0 once the portal finalizes cameras and the
149
+ REM config is written — then the SAME honest service stages below run.
150
+ if defined UI_STATUS_FILE (
151
+ call "%~dp0trillboards-edge.cmd" setup --config "%CFG%" --status-file "%UI_STATUS_FILE%"
152
+ ) else (
153
+ call "%~dp0trillboards-edge.cmd" setup --config "%CFG%"
154
+ )
155
+ set "SETUP_RC=%ERRORLEVEL%"
156
+ if "%SETUP_RC%"=="0" (
157
+ echo [%date% %time%] setup: config received >> "%LOG%"
158
+ goto :ensure_task
159
+ )
160
+ if "%SETUP_RC%"=="3" (
161
+ echo.
162
+ echo The new setup flow is not available yet on the server. Use the classic
163
+ echo flow instead: generate a code in the portal and paste it below.
164
+ echo [%date% %time%] setup: server 404 ^(rc=3^) — classic fallback >> "%LOG%"
165
+ if "%UI_MODE%"=="1" (
166
+ call :write_ui_status error "Setup is temporarily unavailable" "Try again shortly or contact Trillboards support."
167
+ goto :done_fail
168
+ )
169
+ goto :ask_code
170
+ )
171
+ if "%SETUP_RC%"=="2" (
172
+ echo.
173
+ echo Setup ended without finishing ^(expired or timed out^). Re-open
174
+ echo "Pair a camera" to start again — nothing was created, nothing is lost.
175
+ echo [%date% %time%] setup: expired/timeout ^(rc=2^) >> "%LOG%"
176
+ call :write_ui_status error "Setup ended before finishing" "Try again when you are ready. No cameras were created."
177
+ goto :done_fail
178
+ )
179
+ echo.
180
+ echo Setup hit an error ^(see above^). Details were saved to:
181
+ echo "%LOG%"
182
+ echo [%date% %time%] setup: failed ^(rc=%SETUP_RC%^) >> "%LOG%"
183
+ call :write_ui_status error "Setup needs attention" "Try again. If the problem continues, contact Trillboards support."
184
+ goto :done_fail
185
+
186
+ :ensure_task
187
+ REM Local AI is installed by the customer installer before this pairing helper
188
+ REM can open. Re-check it synchronously in required-bundle mode: this may restart
189
+ REM the service, but it can never download a missing model from the network.
190
+ call :write_ui_status local_ai "Checking local AI" "Verifying the private AI service installed with Trillboards."
191
+ if not exist "%~dp0setup-litertlm.ps1" (
192
+ echo [%date% %time%] local-ai: setup script missing >> "%LOG%"
193
+ call :write_ui_status local_ai_error "Local AI setup is incomplete" "Your cameras are paired. Reinstall the Trillboards CCTV connector."
194
+ goto :done_fail
195
+ )
196
+ if defined UI_STATUS_FILE (
197
+ powershell.exe -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File "%~dp0setup-litertlm.ps1" -RequireBundledModel -ProgressPath "%UI_STATUS_FILE%" >> "%LOG%" 2>&1
198
+ ) else (
199
+ powershell.exe -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File "%~dp0setup-litertlm.ps1" -RequireBundledModel >> "%LOG%" 2>&1
200
+ )
201
+ if errorlevel 1 (
202
+ echo [%date% %time%] local-ai: verification failed >> "%LOG%"
203
+ call :write_ui_status local_ai_error "Local AI needs attention" "The included local AI could not be started. Reinstall Trillboards CCTV Setup; your camera pairing is saved."
204
+ goto :done_fail
205
+ )
206
+ echo [%date% %time%] local-ai: bundled model and service verified >> "%LOG%"
207
+
208
+ call :write_ui_status starting_service "Starting Trillboards" "Installing and verifying the background camera service."
209
+
210
+ REM ── Stage 3: the background service must EXIST. The installer registers it,
211
+ REM but that registration can fail silently (it did for Hiten) — so verify and
212
+ REM self-repair here instead of assuming.
213
+ powershell -NoProfile -NonInteractive -Command "if (Get-ScheduledTask -TaskName '%TASK%' -ErrorAction SilentlyContinue) { exit 0 }; exit 1" >nul 2>&1
214
+ if not errorlevel 1 goto :start_task
215
+ echo Background service is not installed — repairing...
216
+ echo [%date% %time%] task: missing, running register-task.ps1 >> "%LOG%"
217
+ powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0register-task.ps1" -InstallDir "%ROOT%" >> "%LOG%" 2>&1
218
+ powershell -NoProfile -NonInteractive -Command "if (Get-ScheduledTask -TaskName '%TASK%' -ErrorAction SilentlyContinue) { exit 0 }; exit 1" >nul 2>&1
219
+ if not errorlevel 1 goto :start_task
220
+ echo.
221
+ echo ERROR: could not install the background service ^(scheduled task "%TASK%"^).
222
+ echo Your pairing IS saved — nothing is lost — but sensing cannot start until
223
+ echo this is fixed. Details were saved to:
224
+ echo "%LOG%"
225
+ echo Please send that file to Trillboards support.
226
+ call :write_ui_status error "Background service could not be installed" "Your camera pairing is saved. Restart this computer, then try again."
227
+ goto :done_fail
228
+
229
+ :start_task
230
+ REM ── Stage 4: the service must actually RUN. Start it, then poll its state
231
+ REM (PowerShell enum — locale-safe, unlike schtasks' localized "Running" text).
232
+ powershell -NoProfile -NonInteractive -Command "Start-ScheduledTask -TaskName '%TASK%'" >> "%LOG%" 2>&1
233
+ powershell -NoProfile -NonInteractive -Command "$d=[DateTime]::Now.AddSeconds(15); while([DateTime]::Now -lt $d){ $t=Get-ScheduledTask -TaskName '%TASK%' -ErrorAction SilentlyContinue; if($t -and $t.State -eq 'Running'){ exit 0 }; Start-Sleep -Milliseconds 800 }; exit 1" >nul 2>&1
234
+ if errorlevel 1 (
235
+ echo.
236
+ echo ERROR: the background service is installed but would not start.
237
+ echo Your pairing IS saved. Try restarting this computer — the service starts
238
+ echo automatically at login. If it still fails, send this file to support:
239
+ echo "%LOG%"
240
+ echo [%date% %time%] task: registered but did not reach Running in 15s >> "%LOG%"
241
+ call :write_ui_status error "Cameras paired, service not running" "Restart this computer, then open Trillboards CCTV Setup again. Your pairing is saved."
242
+ goto :done_fail
243
+ )
244
+
245
+ echo.
246
+ echo [OK] Paired
247
+ echo [OK] Connected to Trillboards
248
+ echo [OK] Private local AI installed and healthy
249
+ echo [OK] Background service installed and running
250
+ echo.
251
+ echo Setup is complete. Trillboards and private local AI are running.
252
+ echo [%date% %time%] success: paired + verified + task running >> "%LOG%"
253
+ call :write_ui_status ready "Camera setup is complete" "Trillboards and private local AI are running in the background."
254
+ echo.
255
+ if "%UI_MODE%"=="1" (
256
+ endlocal
257
+ exit /b 0
258
+ )
259
+ pause
260
+ endlocal
261
+ exit /b 0
262
+
263
+ :done_fail
264
+ echo.
265
+ if "%UI_MODE%"=="1" (
266
+ endlocal
267
+ exit /b 1
268
+ )
269
+ pause
270
+ endlocal
271
+ exit /b 1
272
+
273
+ :write_ui_status
274
+ if not defined UI_STATUS_FILE exit /b 0
275
+ call "%~dp0trillboards-edge.cmd" setup-status --status-file "%UI_STATUS_FILE%" --stage "%~1" --title "%~2" --message "%~3" >nul 2>&1
276
+ exit /b 0