@trillboards/edge-sdk 0.2.4 → 0.2.6
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/README.md +4 -3
- package/deploy/docker/Dockerfile.cloud-sense +117 -0
- package/deploy/docker/Dockerfile.cpu +30 -21
- package/deploy/docker/Dockerfile.cuda +30 -21
- package/deploy/docker/Dockerfile.openvino +30 -20
- package/deploy/docker/README.md +9 -4
- package/deploy/docker/connector-entrypoint.sh +122 -0
- package/deploy/helm/README.md +1 -1
- package/deploy/k8s/daemonset.yaml +1 -1
- package/deploy/macos/README.md +161 -0
- package/deploy/macos/TrillboardsSetupApp.m +603 -0
- package/deploy/macos/build-macos-pkg.sh +588 -0
- package/deploy/macos/com.trillboards.edge.plist +62 -0
- package/deploy/macos/com.trillboards.litertlm.plist +45 -0
- package/deploy/macos/pair.command +519 -0
- package/deploy/macos/scripts/ensure-litertlm.sh +62 -0
- package/deploy/macos/scripts/postinstall +153 -0
- package/deploy/macos/scripts/setup-litertlm.sh +272 -0
- package/deploy/macos/test-install-pair.sh +383 -0
- package/deploy/macos/test-setup-litertlm-reinstall.sh +109 -0
- package/deploy/systemd/install.sh +25 -15
- package/deploy/systemd/trillboards-edge.service +4 -1
- package/deploy/windows/README.md +70 -0
- package/deploy/windows/build-windows.ps1 +225 -0
- package/deploy/windows/bundle-windows-installer.ps1 +153 -0
- package/deploy/windows/check-feeds.js +26 -0
- package/deploy/windows/e2e/fixtures/person.jpg +0 -0
- package/deploy/windows/e2e/test-local-sense.ps1 +185 -0
- package/deploy/windows/install-update.ps1 +101 -0
- package/deploy/windows/installer.nsi +138 -0
- package/deploy/windows/register-litertlm-task.ps1 +42 -0
- package/deploy/windows/register-task.ps1 +44 -0
- package/deploy/windows/run-connector.ps1 +69 -0
- package/deploy/windows/setup-litertlm.ps1 +361 -0
- package/deploy/windows/stop-existing.ps1 +72 -0
- package/deploy/windows/trillboards-edge-task.vbs +25 -0
- package/deploy/windows/trillboards-edge.cmd +33 -0
- package/deploy/windows/trillboards-pair.cmd +276 -0
- package/deploy/windows/trillboards-setup.ps1 +456 -0
- package/deploy/windows/trillboards-setup.vbs +13 -0
- package/dist/AudienceAnalyzeClient.d.ts +136 -0
- package/dist/AudienceAnalyzeClient.d.ts.map +1 -0
- package/dist/AudienceAnalyzeClient.js +246 -0
- package/dist/AudienceAnalyzeClient.js.map +1 -0
- package/dist/ChannelProber.d.ts +150 -0
- package/dist/ChannelProber.d.ts.map +1 -0
- package/dist/ChannelProber.js +887 -0
- package/dist/ChannelProber.js.map +1 -0
- package/dist/CloudEscalationPolicy.d.ts +143 -0
- package/dist/CloudEscalationPolicy.d.ts.map +1 -0
- package/dist/CloudEscalationPolicy.js +137 -0
- package/dist/CloudEscalationPolicy.js.map +1 -0
- package/dist/CloudSensingManager.d.ts +533 -0
- package/dist/CloudSensingManager.d.ts.map +1 -0
- package/dist/CloudSensingManager.js +1254 -0
- package/dist/CloudSensingManager.js.map +1 -0
- package/dist/DiscoveryReportClient.d.ts +66 -0
- package/dist/DiscoveryReportClient.d.ts.map +1 -0
- package/dist/DiscoveryReportClient.js +85 -0
- package/dist/DiscoveryReportClient.js.map +1 -0
- package/dist/EdgeAgent.d.ts +12 -2
- package/dist/EdgeAgent.d.ts.map +1 -1
- package/dist/EdgeAgent.js +55 -13
- package/dist/EdgeAgent.js.map +1 -1
- package/dist/LiteRtVlmProvider.d.ts +193 -0
- package/dist/LiteRtVlmProvider.d.ts.map +1 -0
- package/dist/LiteRtVlmProvider.js +436 -0
- package/dist/LiteRtVlmProvider.js.map +1 -0
- package/dist/MosaicSource.d.ts +108 -0
- package/dist/MosaicSource.d.ts.map +1 -0
- package/dist/MosaicSource.js +274 -0
- package/dist/MosaicSource.js.map +1 -0
- package/dist/OnvifClient.d.ts +83 -0
- package/dist/OnvifClient.d.ts.map +1 -0
- package/dist/OnvifClient.js +209 -0
- package/dist/OnvifClient.js.map +1 -0
- package/dist/PairClient.d.ts +106 -0
- package/dist/PairClient.d.ts.map +1 -0
- package/dist/PairClient.js +186 -0
- package/dist/PairClient.js.map +1 -0
- package/dist/RecorderAddressRecovery.d.ts +53 -0
- package/dist/RecorderAddressRecovery.d.ts.map +1 -0
- package/dist/RecorderAddressRecovery.js +359 -0
- package/dist/RecorderAddressRecovery.js.map +1 -0
- package/dist/SceneChangeDetector.d.ts +291 -0
- package/dist/SceneChangeDetector.d.ts.map +1 -0
- package/dist/SceneChangeDetector.js +682 -0
- package/dist/SceneChangeDetector.js.map +1 -0
- package/dist/SensingProfileClient.d.ts +59 -0
- package/dist/SensingProfileClient.d.ts.map +1 -0
- package/dist/SensingProfileClient.js +78 -0
- package/dist/SensingProfileClient.js.map +1 -0
- package/dist/SetupSessionClient.d.ts +114 -0
- package/dist/SetupSessionClient.d.ts.map +1 -0
- package/dist/SetupSessionClient.js +95 -0
- package/dist/SetupSessionClient.js.map +1 -0
- package/dist/VlmAdmissionGate.d.ts +126 -0
- package/dist/VlmAdmissionGate.d.ts.map +1 -0
- package/dist/VlmAdmissionGate.js +166 -0
- package/dist/VlmAdmissionGate.js.map +1 -0
- package/dist/autoSense.d.ts +216 -0
- package/dist/autoSense.d.ts.map +1 -0
- package/dist/autoSense.js +521 -0
- package/dist/autoSense.js.map +1 -0
- package/dist/cli.d.ts +27 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +511 -21
- package/dist/cli.js.map +1 -1
- package/dist/combinedSense.d.ts +128 -0
- package/dist/combinedSense.d.ts.map +1 -0
- package/dist/combinedSense.js +261 -0
- package/dist/combinedSense.js.map +1 -0
- package/dist/config.d.ts +351 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +99 -2
- package/dist/config.js.map +1 -1
- package/dist/connectorCadence.d.ts +135 -0
- package/dist/connectorCadence.d.ts.map +1 -0
- package/dist/connectorCadence.js +151 -0
- package/dist/connectorCadence.js.map +1 -0
- package/dist/dataDir.d.ts +33 -0
- package/dist/dataDir.d.ts.map +1 -0
- package/dist/dataDir.js +76 -0
- package/dist/dataDir.js.map +1 -0
- package/dist/deployedCadence.d.ts +167 -0
- package/dist/deployedCadence.d.ts.map +1 -0
- package/dist/deployedCadence.js +209 -0
- package/dist/deployedCadence.js.map +1 -0
- package/dist/deployedCadenceSource.d.ts +48 -0
- package/dist/deployedCadenceSource.d.ts.map +1 -0
- package/dist/deployedCadenceSource.js +74 -0
- package/dist/deployedCadenceSource.js.map +1 -0
- package/dist/diagnose.d.ts +1 -1
- package/dist/diagnose.d.ts.map +1 -1
- package/dist/diagnose.js +13 -12
- package/dist/diagnose.js.map +1 -1
- package/dist/discovery.d.ts +131 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +499 -0
- package/dist/discovery.js.map +1 -0
- package/dist/gemmaModelOta.d.ts +118 -0
- package/dist/gemmaModelOta.d.ts.map +1 -0
- package/dist/gemmaModelOta.js +291 -0
- package/dist/gemmaModelOta.js.map +1 -0
- package/dist/index.d.ts +16 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -1
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +41 -18
- package/dist/init.js.map +1 -1
- package/dist/keepAwake.d.ts +33 -0
- package/dist/keepAwake.d.ts.map +1 -0
- package/dist/keepAwake.js +54 -0
- package/dist/keepAwake.js.map +1 -0
- package/dist/legacyRecorderProfile.d.ts +20 -0
- package/dist/legacyRecorderProfile.d.ts.map +1 -0
- package/dist/legacyRecorderProfile.js +27 -0
- package/dist/legacyRecorderProfile.js.map +1 -0
- package/dist/localInferenceSchema.d.ts +132 -0
- package/dist/localInferenceSchema.d.ts.map +1 -0
- package/dist/localInferenceSchema.js +274 -0
- package/dist/localInferenceSchema.js.map +1 -0
- package/dist/localSenseE2eHarness.d.ts +101 -0
- package/dist/localSenseE2eHarness.d.ts.map +1 -0
- package/dist/localSenseE2eHarness.js +279 -0
- package/dist/localSenseE2eHarness.js.map +1 -0
- package/dist/localSensing.d.ts +268 -0
- package/dist/localSensing.d.ts.map +1 -0
- package/dist/localSensing.js +492 -0
- package/dist/localSensing.js.map +1 -0
- package/dist/modelIntegrity.d.ts +59 -0
- package/dist/modelIntegrity.d.ts.map +1 -0
- package/dist/modelIntegrity.js +165 -0
- package/dist/modelIntegrity.js.map +1 -0
- package/dist/pairVerify.d.ts +100 -0
- package/dist/pairVerify.d.ts.map +1 -0
- package/dist/pairVerify.js +296 -0
- package/dist/pairVerify.js.map +1 -0
- package/dist/qrScanner.d.ts +33 -0
- package/dist/qrScanner.d.ts.map +1 -0
- package/dist/qrScanner.js +103 -0
- package/dist/qrScanner.js.map +1 -0
- package/dist/runtimePaths.d.ts +10 -0
- package/dist/runtimePaths.d.ts.map +1 -0
- package/dist/runtimePaths.js +79 -0
- package/dist/runtimePaths.js.map +1 -0
- package/dist/sensingRunMode.d.ts +68 -0
- package/dist/sensingRunMode.d.ts.map +1 -0
- package/dist/sensingRunMode.js +346 -0
- package/dist/sensingRunMode.js.map +1 -0
- package/dist/setupMode.d.ts +98 -0
- package/dist/setupMode.d.ts.map +1 -0
- package/dist/setupMode.js +828 -0
- package/dist/setupMode.js.map +1 -0
- package/dist/setupProgress.d.ts +31 -0
- package/dist/setupProgress.d.ts.map +1 -0
- package/dist/setupProgress.js +173 -0
- package/dist/setupProgress.js.map +1 -0
- package/package.json +13 -4
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<#
|
|
2
|
+
Validates a staged connector, stops the running copy, swaps bin/lib, registers
|
|
3
|
+
the new hidden task, and restores the previous runnable version on failure.
|
|
4
|
+
#>
|
|
5
|
+
[CmdletBinding()]
|
|
6
|
+
param(
|
|
7
|
+
[Parameter(Mandatory = $true)][string]$InstallDir,
|
|
8
|
+
[Parameter(Mandatory = $true)][string]$StagingDir
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
$ErrorActionPreference = "Stop"
|
|
12
|
+
$previousDir = Join-Path $InstallDir ".previous"
|
|
13
|
+
$parts = @("bin", "lib")
|
|
14
|
+
$movedPrevious = New-Object System.Collections.Generic.List[string]
|
|
15
|
+
$movedStaged = New-Object System.Collections.Generic.List[string]
|
|
16
|
+
|
|
17
|
+
function Assert-ConnectorVersion([string]$Root) {
|
|
18
|
+
$node = Join-Path $Root "bin\node.exe"
|
|
19
|
+
$cli = Join-Path $Root "lib\edge-sdk\dist\cli.js"
|
|
20
|
+
if (-not (Test-Path $node) -or -not (Test-Path $cli)) {
|
|
21
|
+
throw "The staged connector is incomplete."
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
$oldPath = $env:PATH
|
|
25
|
+
$oldNodePath = $env:NODE_PATH
|
|
26
|
+
try {
|
|
27
|
+
$env:PATH = "$(Join-Path $Root 'bin');$oldPath"
|
|
28
|
+
$env:NODE_PATH = Join-Path $Root "lib\node_modules"
|
|
29
|
+
$version = (& $node $cli version 2>&1 | Out-String).Trim()
|
|
30
|
+
if ($LASTEXITCODE -ne 0 -or $version -notmatch 'edge-sdk v') {
|
|
31
|
+
throw "Connector version check failed: $version"
|
|
32
|
+
}
|
|
33
|
+
Write-Host "Validated $version"
|
|
34
|
+
} finally {
|
|
35
|
+
$env:PATH = $oldPath
|
|
36
|
+
$env:NODE_PATH = $oldNodePath
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function Register-Connector([string]$Root) {
|
|
41
|
+
$register = Join-Path $Root "bin\register-task.ps1"
|
|
42
|
+
& $register -InstallDir $InstallDir -Mode "auto-sense"
|
|
43
|
+
if ($LASTEXITCODE -ne 0) { throw "Scheduled-task registration failed." }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
Assert-ConnectorVersion $StagingDir
|
|
48
|
+
& (Join-Path $StagingDir "bin\stop-existing.ps1") -InstallDir $InstallDir
|
|
49
|
+
|
|
50
|
+
if (Test-Path $previousDir) { Remove-Item -Recurse -Force $previousDir }
|
|
51
|
+
New-Item -ItemType Directory -Force -Path $InstallDir, $previousDir | Out-Null
|
|
52
|
+
|
|
53
|
+
foreach ($part in $parts) {
|
|
54
|
+
$active = Join-Path $InstallDir $part
|
|
55
|
+
if (Test-Path $active) {
|
|
56
|
+
Move-Item -LiteralPath $active -Destination (Join-Path $previousDir $part)
|
|
57
|
+
$movedPrevious.Add($part)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
foreach ($part in $parts) {
|
|
61
|
+
$staged = Join-Path $StagingDir $part
|
|
62
|
+
if (-not (Test-Path $staged)) { throw "Staged connector is missing $part." }
|
|
63
|
+
Move-Item -LiteralPath $staged -Destination (Join-Path $InstallDir $part)
|
|
64
|
+
$movedStaged.Add($part)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
Assert-ConnectorVersion $InstallDir
|
|
68
|
+
Register-Connector $InstallDir
|
|
69
|
+
if (Test-Path (Join-Path $InstallDir "trillboards.config.json")) {
|
|
70
|
+
Start-ScheduledTask -TaskName "TrillboardsEdge" -ErrorAction Stop
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
Remove-Item -Recurse -Force $previousDir -ErrorAction SilentlyContinue
|
|
74
|
+
Remove-Item -Recurse -Force $StagingDir -ErrorAction SilentlyContinue
|
|
75
|
+
Write-Host "Trillboards Edge update installed successfully."
|
|
76
|
+
} catch {
|
|
77
|
+
$failure = $_
|
|
78
|
+
try {
|
|
79
|
+
$stopScript = Join-Path $InstallDir "bin\stop-existing.ps1"
|
|
80
|
+
if (Test-Path $stopScript) { & $stopScript -InstallDir $InstallDir }
|
|
81
|
+
} catch {}
|
|
82
|
+
|
|
83
|
+
foreach ($part in $movedStaged) {
|
|
84
|
+
Remove-Item -Recurse -Force (Join-Path $InstallDir $part) -ErrorAction SilentlyContinue
|
|
85
|
+
}
|
|
86
|
+
foreach ($part in $movedPrevious) {
|
|
87
|
+
$backup = Join-Path $previousDir $part
|
|
88
|
+
if (Test-Path $backup) {
|
|
89
|
+
Move-Item -LiteralPath $backup -Destination (Join-Path $InstallDir $part)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if ($movedPrevious.Count -gt 0) {
|
|
93
|
+
try {
|
|
94
|
+
Register-Connector $InstallDir
|
|
95
|
+
if (Test-Path (Join-Path $InstallDir "trillboards.config.json")) {
|
|
96
|
+
Start-ScheduledTask -TaskName "TrillboardsEdge" -ErrorAction SilentlyContinue
|
|
97
|
+
}
|
|
98
|
+
} catch {}
|
|
99
|
+
}
|
|
100
|
+
throw "Trillboards Edge update failed and the previous version was restored: $($failure.Exception.Message)"
|
|
101
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
; installer.nsi — Trillboards Edge on-device (local-sense) CCTV connector (Windows).
|
|
2
|
+
; Per-user, no-admin install (RequestExecutionLevel user) that mirrors the
|
|
3
|
+
; home-domain macOS .pkg: lays down the self-contained tree under
|
|
4
|
+
; %LOCALAPPDATA%\Trillboards\edge, registers a per-user Scheduled Task that
|
|
5
|
+
; runs local-first auto-sense at logon, installs the model supplied by the outer
|
|
6
|
+
; signed customer package, verifies local AI, then opens first-run pairing.
|
|
7
|
+
;
|
|
8
|
+
; The release workflow Authenticode-signs and verifies the finished executable
|
|
9
|
+
; with Azure Trusted Signing before publishing it to the customer CDN.
|
|
10
|
+
;
|
|
11
|
+
; Driven by build-windows.ps1 with:
|
|
12
|
+
; makensis /DPAYLOAD_DIR=<stage>\Trillboards\edge /DAPP_VERSION=<ver> /DOUT_FILE=<exe> installer.nsi
|
|
13
|
+
|
|
14
|
+
!ifndef PAYLOAD_DIR
|
|
15
|
+
!error "PAYLOAD_DIR not defined (pass /DPAYLOAD_DIR=...)"
|
|
16
|
+
!endif
|
|
17
|
+
!ifndef APP_VERSION
|
|
18
|
+
!define APP_VERSION "0.0.0"
|
|
19
|
+
!endif
|
|
20
|
+
!ifndef OUT_FILE
|
|
21
|
+
!define OUT_FILE "TrillboardsEdgeSetup.exe"
|
|
22
|
+
!endif
|
|
23
|
+
|
|
24
|
+
!define APP_NAME "Trillboards Edge - CCTV Connector"
|
|
25
|
+
!define TASK_NAME "TrillboardsEdge"
|
|
26
|
+
!define LITERT_TASK_NAME "TrillboardsLiteRtLm"
|
|
27
|
+
|
|
28
|
+
Var ModelSource
|
|
29
|
+
|
|
30
|
+
Name "${APP_NAME}"
|
|
31
|
+
OutFile "${OUT_FILE}"
|
|
32
|
+
Unicode True
|
|
33
|
+
RequestExecutionLevel user ; per-user, no admin/UAC
|
|
34
|
+
InstallDir "$LOCALAPPDATA\Trillboards\edge"
|
|
35
|
+
SetCompressor /SOLID lzma
|
|
36
|
+
ShowInstDetails show
|
|
37
|
+
BrandingText "Trillboards"
|
|
38
|
+
|
|
39
|
+
!include "MUI2.nsh"
|
|
40
|
+
!include "FileFunc.nsh"
|
|
41
|
+
|
|
42
|
+
!define MUI_ABORTWARNING
|
|
43
|
+
!define MUI_WELCOMEPAGE_TITLE "Connect your camera to Trillboards"
|
|
44
|
+
!define MUI_WELCOMEPAGE_TEXT "This installs the Trillboards camera connector and private local AI included with it. Camera pairing opens after both are installed and verified. Cloud inference stays off unless explicitly enabled."
|
|
45
|
+
!insertmacro MUI_PAGE_WELCOME
|
|
46
|
+
!insertmacro MUI_PAGE_INSTFILES
|
|
47
|
+
|
|
48
|
+
; Finish page: launch the native Windows Forms setup app through wscript. The
|
|
49
|
+
; setup engine and its cmd wrapper run with CreateNoWindow, so no console flashes.
|
|
50
|
+
!define MUI_FINISHPAGE_RUN "$INSTDIR\bin\trillboards-setup.vbs"
|
|
51
|
+
!define MUI_FINISHPAGE_RUN_TEXT "Set up my CCTV cameras now"
|
|
52
|
+
!define MUI_FINISHPAGE_TEXT "The connector and private local AI are installed. Continue in the Trillboards CCTV Setup app to pair your cameras."
|
|
53
|
+
!insertmacro MUI_PAGE_FINISH
|
|
54
|
+
|
|
55
|
+
!insertmacro MUI_UNPAGE_CONFIRM
|
|
56
|
+
!insertmacro MUI_UNPAGE_INSTFILES
|
|
57
|
+
!insertmacro MUI_LANGUAGE "English"
|
|
58
|
+
|
|
59
|
+
Function .onInit
|
|
60
|
+
; The SFX launcher supplies a process-scoped environment value so paths with
|
|
61
|
+
; spaces are unambiguous. Keep the command-line option as an engineering and
|
|
62
|
+
; recovery fallback.
|
|
63
|
+
ReadEnvStr $ModelSource "TRILLBOARDS_BUNDLED_MODEL_PATH"
|
|
64
|
+
${If} $ModelSource == ""
|
|
65
|
+
${GetParameters} $0
|
|
66
|
+
${GetOptions} $0 "/MODEL_SOURCE=" $ModelSource
|
|
67
|
+
${EndIf}
|
|
68
|
+
${If} $ModelSource == ""
|
|
69
|
+
MessageBox MB_ICONSTOP|MB_OK "This installer is missing its included local AI model. Download the complete Trillboards CCTV installer and try again."
|
|
70
|
+
Abort
|
|
71
|
+
${EndIf}
|
|
72
|
+
FunctionEnd
|
|
73
|
+
|
|
74
|
+
Section "Install"
|
|
75
|
+
; Copy and validate beside the live install first. install-update.ps1 then
|
|
76
|
+
; stops the task, swaps bin/lib atomically, verifies again, and restores the
|
|
77
|
+
; previous runnable version if registration fails. The root-level camera
|
|
78
|
+
; config is never moved or overwritten.
|
|
79
|
+
RMDir /r "$INSTDIR\.update-staging"
|
|
80
|
+
SetOutPath "$INSTDIR\.update-staging"
|
|
81
|
+
File /r "${PAYLOAD_DIR}\*"
|
|
82
|
+
|
|
83
|
+
InitPluginsDir
|
|
84
|
+
File /oname=$PLUGINSDIR\install-update.ps1 "${PAYLOAD_DIR}\bin\install-update.ps1"
|
|
85
|
+
DetailPrint "Validating and updating the background connector..."
|
|
86
|
+
nsExec::ExecToLog 'powershell -NoProfile -ExecutionPolicy Bypass -File "$PLUGINSDIR\install-update.ps1" -InstallDir "$INSTDIR" -StagingDir "$INSTDIR\.update-staging"'
|
|
87
|
+
Pop $0
|
|
88
|
+
${If} $0 != 0
|
|
89
|
+
MessageBox MB_ICONSTOP|MB_OK "Trillboards CCTV setup could not be updated safely. Your previous connector was restored. Please retry the installer."
|
|
90
|
+
Abort
|
|
91
|
+
${EndIf}
|
|
92
|
+
SetOutPath "$INSTDIR"
|
|
93
|
+
|
|
94
|
+
; The outer signed self-extractor passes its checksum-pinned model here. This
|
|
95
|
+
; is synchronous and required: pairing is never offered while AI is absent or
|
|
96
|
+
; still downloading in the background.
|
|
97
|
+
${IfNot} ${FileExists} "$ModelSource"
|
|
98
|
+
MessageBox MB_ICONSTOP|MB_OK "The local AI model included with this installer could not be found. Download a fresh Trillboards CCTV installer."
|
|
99
|
+
Abort
|
|
100
|
+
${EndIf}
|
|
101
|
+
DetailPrint "Installing and verifying private local AI..."
|
|
102
|
+
nsExec::ExecToLog '"$WINDIR\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -ExecutionPolicy Bypass -File "$INSTDIR\bin\setup-litertlm.ps1" -BundledModelPath "$ModelSource" -RequireBundledModel'
|
|
103
|
+
Pop $0
|
|
104
|
+
${If} $0 != 0
|
|
105
|
+
MessageBox MB_ICONSTOP|MB_OK "Private local AI could not be installed. Camera pairing has not started. Download a fresh installer or contact Trillboards support."
|
|
106
|
+
Abort
|
|
107
|
+
${EndIf}
|
|
108
|
+
DetailPrint "Private local AI is installed and healthy."
|
|
109
|
+
|
|
110
|
+
; Start Menu shortcuts.
|
|
111
|
+
CreateDirectory "$SMPROGRAMS\Trillboards"
|
|
112
|
+
CreateShortcut "$SMPROGRAMS\Trillboards\Trillboards CCTV Setup.lnk" "$WINDIR\System32\wscript.exe" '$\"$INSTDIR\bin\trillboards-setup.vbs$\"'
|
|
113
|
+
CreateShortcut "$SMPROGRAMS\Trillboards\Uninstall Trillboards Edge.lnk" "$INSTDIR\uninstall.exe"
|
|
114
|
+
|
|
115
|
+
; Uninstaller + Add/Remove Programs entry (per-user hive).
|
|
116
|
+
WriteUninstaller "$INSTDIR\uninstall.exe"
|
|
117
|
+
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\TrillboardsEdge" "DisplayName" "${APP_NAME}"
|
|
118
|
+
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\TrillboardsEdge" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
|
|
119
|
+
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\TrillboardsEdge" "DisplayVersion" "${APP_VERSION}"
|
|
120
|
+
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\TrillboardsEdge" "Publisher" "Trillboards"
|
|
121
|
+
WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\TrillboardsEdge" "NoModify" 1
|
|
122
|
+
WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\TrillboardsEdge" "NoRepair" 1
|
|
123
|
+
SectionEnd
|
|
124
|
+
|
|
125
|
+
Section "Uninstall"
|
|
126
|
+
; Stop + remove the background tasks (connector + litert-lm serve).
|
|
127
|
+
nsExec::ExecToLog 'powershell -NoProfile -ExecutionPolicy Bypass -File "$INSTDIR\bin\stop-existing.ps1" -InstallDir "$INSTDIR"'
|
|
128
|
+
nsExec::ExecToLog 'schtasks /End /TN "${TASK_NAME}"'
|
|
129
|
+
nsExec::ExecToLog 'schtasks /Delete /F /TN "${TASK_NAME}"'
|
|
130
|
+
nsExec::ExecToLog 'schtasks /End /TN "${LITERT_TASK_NAME}"'
|
|
131
|
+
nsExec::ExecToLog 'schtasks /Delete /F /TN "${LITERT_TASK_NAME}"'
|
|
132
|
+
Delete "$SMPROGRAMS\Trillboards\Pair a camera.lnk"
|
|
133
|
+
Delete "$SMPROGRAMS\Trillboards\Trillboards CCTV Setup.lnk"
|
|
134
|
+
Delete "$SMPROGRAMS\Trillboards\Uninstall Trillboards Edge.lnk"
|
|
135
|
+
RMDir "$SMPROGRAMS\Trillboards"
|
|
136
|
+
RMDir /r "$INSTDIR"
|
|
137
|
+
DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\TrillboardsEdge"
|
|
138
|
+
SectionEnd
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<#
|
|
2
|
+
register-litertlm-task.ps1 — register the per-user Scheduled Task that runs the
|
|
3
|
+
LiteRT-LM on-device VLM server (Gemma 4 E2B) at logon, with crash-restart.
|
|
4
|
+
Per-user + Interactive logon type → NO admin/UAC (mirrors the macOS
|
|
5
|
+
com.trillboards.litertlm LaunchAgent: KeepAlive=true + ThrottleInterval=30).
|
|
6
|
+
The connector's LiteRtVlmProvider talks to the OpenAI-compatible endpoint on
|
|
7
|
+
127.0.0.1:<Port>. Invoked by setup-litertlm.ps1.
|
|
8
|
+
#>
|
|
9
|
+
param(
|
|
10
|
+
[Parameter(Mandatory = $true)][string]$LitertLmPath,
|
|
11
|
+
[string]$Port = "9379"
|
|
12
|
+
)
|
|
13
|
+
$ErrorActionPreference = "Stop"
|
|
14
|
+
|
|
15
|
+
$TaskName = "TrillboardsLiteRtLm"
|
|
16
|
+
$UserId = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
|
|
17
|
+
# litert-lm serve --host 127.0.0.1 --port <port> (loopback only — the connector
|
|
18
|
+
# is local; never expose the model server off-box).
|
|
19
|
+
$argument = 'serve --host 127.0.0.1 --port ' + $Port
|
|
20
|
+
$Action = New-ScheduledTaskAction -Execute $LitertLmPath -Argument $argument
|
|
21
|
+
$Trigger = New-ScheduledTaskTrigger -AtLogOn -User $UserId
|
|
22
|
+
# RestartCount/Interval == the plist's ThrottleInterval crash-loop guard (e.g.
|
|
23
|
+
# while the ~2.4 GB model is still importing on first run); Zero time limit ==
|
|
24
|
+
# the always-on KeepAlive serve endpoint.
|
|
25
|
+
$Settings = New-ScheduledTaskSettingsSet -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1) `
|
|
26
|
+
-AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable `
|
|
27
|
+
-ExecutionTimeLimit ([TimeSpan]::Zero)
|
|
28
|
+
$Principal = New-ScheduledTaskPrincipal -UserId $UserId -LogonType Interactive -RunLevel Limited
|
|
29
|
+
|
|
30
|
+
Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false -ErrorAction SilentlyContinue
|
|
31
|
+
Register-ScheduledTask -TaskName $TaskName -Action $Action -Trigger $Trigger -Settings $Settings `
|
|
32
|
+
-Principal $Principal -Description "Trillboards LiteRT-LM - on-device Gemma VLM server (:$Port)" | Out-Null
|
|
33
|
+
|
|
34
|
+
$registered = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
35
|
+
if (-not $registered) {
|
|
36
|
+
Write-Error "Scheduled task '$TaskName' did NOT register (Get-ScheduledTask found nothing)."
|
|
37
|
+
exit 1
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# Start it now (don't wait for the next logon) so first-run sensing has a server.
|
|
41
|
+
Start-ScheduledTask -TaskName $TaskName
|
|
42
|
+
Write-Host "Registered scheduled task '$TaskName' (litert-lm serve on :$Port, restarts on failure)."
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<#
|
|
2
|
+
register-task.ps1 — register the per-user Scheduled Task that runs the
|
|
3
|
+
Trillboards local-first connector at logon (with crash-restart). Per-user +
|
|
4
|
+
Interactive logon type so NO admin/UAC is required (mirrors the home-domain,
|
|
5
|
+
no-sudo macOS LaunchAgent). Invoked by the NSIS installer post-copy.
|
|
6
|
+
#>
|
|
7
|
+
param(
|
|
8
|
+
[Parameter(Mandatory = $true)][string]$InstallDir,
|
|
9
|
+
# Default to auto-sense: use on-device Gemma (LiteRT-LM) and wait locally while
|
|
10
|
+
# the model is provisioning. cloud-sense remains an explicit operator choice.
|
|
11
|
+
[ValidateSet("auto-sense", "local-sense", "cloud-sense")][string]$Mode = "auto-sense"
|
|
12
|
+
)
|
|
13
|
+
$ErrorActionPreference = "Stop"
|
|
14
|
+
|
|
15
|
+
$TaskName = "TrillboardsEdge"
|
|
16
|
+
$UserId = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
|
|
17
|
+
$taskHost = Join-Path $InstallDir "bin\trillboards-edge-task.vbs"
|
|
18
|
+
$wscript = Join-Path $env:WINDIR "System32\wscript.exe"
|
|
19
|
+
|
|
20
|
+
# wscript owns the task lifetime, launches the connector with window style 0,
|
|
21
|
+
# waits for it, and returns its exit code. Task Scheduler can therefore restart
|
|
22
|
+
# crashes without exposing cmd.exe or PowerShell to the customer.
|
|
23
|
+
$argument = '"' + $taskHost + '" "' + $Mode + '"'
|
|
24
|
+
$Action = New-ScheduledTaskAction -Execute $wscript -Argument $argument -WorkingDirectory $InstallDir
|
|
25
|
+
$Trigger = New-ScheduledTaskTrigger -AtLogOn -User $UserId
|
|
26
|
+
$Settings = New-ScheduledTaskSettingsSet -RestartCount 99 -RestartInterval (New-TimeSpan -Minutes 1) `
|
|
27
|
+
-AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable `
|
|
28
|
+
-ExecutionTimeLimit ([TimeSpan]::Zero) # no time limit — sensing runs continuously
|
|
29
|
+
$Principal = New-ScheduledTaskPrincipal -UserId $UserId -LogonType Interactive -RunLevel Limited
|
|
30
|
+
|
|
31
|
+
Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false -ErrorAction SilentlyContinue
|
|
32
|
+
Register-ScheduledTask -TaskName $TaskName -Action $Action -Trigger $Trigger -Settings $Settings `
|
|
33
|
+
-Principal $Principal -Description "Trillboards Edge - CCTV $Mode connector" | Out-Null
|
|
34
|
+
|
|
35
|
+
# VERIFY the registration landed instead of trusting Register-ScheduledTask's
|
|
36
|
+
# silence — a silently-missing task is exactly how a real 16-camera install
|
|
37
|
+
# ended up paired with zero frames (the pairing helper then claimed success).
|
|
38
|
+
# Callers (installer.nsi, trillboards-pair.cmd's self-repair) branch on our
|
|
39
|
+
# exit code, so fail LOUDLY here.
|
|
40
|
+
$registered = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
41
|
+
if (-not $registered) {
|
|
42
|
+
throw "Scheduled task '$TaskName' did NOT register (Get-ScheduledTask found nothing)."
|
|
43
|
+
}
|
|
44
|
+
Write-Host "Registered scheduled task '$TaskName' (runs $Mode at logon, restarts on failure)."
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<#
|
|
2
|
+
Hidden connector supervisor. It merges stdout/stderr into one pipe and owns
|
|
3
|
+
the log file, allowing size-based rotation while the connector runs 24/7.
|
|
4
|
+
#>
|
|
5
|
+
[CmdletBinding()]
|
|
6
|
+
param(
|
|
7
|
+
[Parameter(Mandatory = $true)][string]$InstallDir,
|
|
8
|
+
[ValidateSet("auto-sense", "local-sense", "cloud-sense")][string]$Mode = "auto-sense"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
$ErrorActionPreference = "Stop"
|
|
12
|
+
$logDir = Join-Path $InstallDir "logs"
|
|
13
|
+
$logPath = Join-Path $logDir "connector.log"
|
|
14
|
+
$launcher = Join-Path $InstallDir "bin\trillboards-edge.cmd"
|
|
15
|
+
$configPath = Join-Path $InstallDir "trillboards.config.json"
|
|
16
|
+
$maxLogBytes = 5MB
|
|
17
|
+
New-Item -ItemType Directory -Force -Path $logDir | Out-Null
|
|
18
|
+
|
|
19
|
+
function Move-ConnectorLogs {
|
|
20
|
+
if (Test-Path "$logPath.3") { Remove-Item -Force "$logPath.3" }
|
|
21
|
+
for ($index = 2; $index -ge 1; $index--) {
|
|
22
|
+
$source = "$logPath.$index"
|
|
23
|
+
$target = "$logPath.$($index + 1)"
|
|
24
|
+
if (Test-Path $source) { Move-Item -Force $source $target }
|
|
25
|
+
}
|
|
26
|
+
if (Test-Path $logPath) { Move-Item -Force $logPath "$logPath.1" }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if ((Test-Path $logPath) -and (Get-Item $logPath).Length -ge $maxLogBytes) {
|
|
30
|
+
Move-ConnectorLogs
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
$writer = $null
|
|
34
|
+
$process = $null
|
|
35
|
+
try {
|
|
36
|
+
$writer = New-Object System.IO.StreamWriter($logPath, $true, (New-Object System.Text.UTF8Encoding($false)))
|
|
37
|
+
$writer.AutoFlush = $true
|
|
38
|
+
|
|
39
|
+
$startInfo = New-Object System.Diagnostics.ProcessStartInfo
|
|
40
|
+
$startInfo.FileName = $env:ComSpec
|
|
41
|
+
$startInfo.Arguments = '/d /s /c ""' + $launcher + '" ' + $Mode + ' --config "' + $configPath + '" 2>&1"'
|
|
42
|
+
$startInfo.WorkingDirectory = $InstallDir
|
|
43
|
+
$startInfo.UseShellExecute = $false
|
|
44
|
+
$startInfo.CreateNoWindow = $true
|
|
45
|
+
$startInfo.RedirectStandardOutput = $true
|
|
46
|
+
|
|
47
|
+
$process = New-Object System.Diagnostics.Process
|
|
48
|
+
$process.StartInfo = $startInfo
|
|
49
|
+
if (-not $process.Start()) { throw "The Trillboards connector did not start." }
|
|
50
|
+
|
|
51
|
+
while (-not $process.StandardOutput.EndOfStream) {
|
|
52
|
+
$line = $process.StandardOutput.ReadLine()
|
|
53
|
+
if ($null -eq $line) { continue }
|
|
54
|
+
$writer.WriteLine($line)
|
|
55
|
+
if ($writer.BaseStream.Length -ge $maxLogBytes) {
|
|
56
|
+
$writer.Dispose()
|
|
57
|
+
$writer = $null
|
|
58
|
+
Move-ConnectorLogs
|
|
59
|
+
$writer = New-Object System.IO.StreamWriter($logPath, $true, (New-Object System.Text.UTF8Encoding($false)))
|
|
60
|
+
$writer.AutoFlush = $true
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
$process.WaitForExit()
|
|
65
|
+
exit $process.ExitCode
|
|
66
|
+
} finally {
|
|
67
|
+
if ($null -ne $writer) { $writer.Dispose() }
|
|
68
|
+
if ($null -ne $process) { $process.Dispose() }
|
|
69
|
+
}
|