- connect-board.ps1 / .bat: PowerShell twin of connect-board.sh so teams on Windows 11 attach the USB Uno Q to the local self-host stack (adb forward + self-register; -Watch for auto-reattach; .bat bypasses execution policy) - provision-wifi.sh: idempotent nmcli join over adb, venue WiFi baked as default - provision-fleet.sh: run the WiFi step per board during fleet bring-up - REQUIREMENTS.md: Windows 11 section (Docker+WSL2, native adb, USB driver), 'does adb see your board?' check, and correct the WiFi reality (board needs venue WiFi for the cloud brain; we pre-join it) Co-Authored-By: Claude Opus 4.8 <[email protected]>
106 lines
3.9 KiB
PowerShell
106 lines
3.9 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Attach the USB Uno Q board to your LOCAL self-host stack (Windows 11).
|
|
|
|
.DESCRIPTION
|
|
PowerShell twin of connect-board.sh. Runs adb ON the Windows host so Docker
|
|
Desktop's host.docker.internal reaches the forwarded port. Forwards the tunnels
|
|
and registers the board with the containerized API; in LOCAL_MODE the API
|
|
auto-binds the board to your team in the browser — no claim code.
|
|
|
|
.EXAMPLE
|
|
.\connect-board.ps1 # attach once
|
|
.\connect-board.ps1 -Watch # re-attach on every (re)connect (leave running)
|
|
|
|
.NOTES
|
|
Env overrides: WEB_URL, FLEET_SECRET, KIT_ID, NODE_URL, SERIAL
|
|
If Windows blocks the script, run it as:
|
|
powershell -NoProfile -ExecutionPolicy Bypass -File .\connect-board.ps1
|
|
(or just double-click connect-board.bat).
|
|
#>
|
|
param([switch]$Watch)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
$Web = if ($env:WEB_URL) { $env:WEB_URL } else { 'http://localhost:8090' }
|
|
$Api = "$Web/api"
|
|
$Secret = if ($env:FLEET_SECRET) { $env:FLEET_SECRET } else { 'apess2026' }
|
|
$KitId = if ($env:KIT_ID) { $env:KIT_ID } else { 'crimson-node' }
|
|
# How the API *container* reaches the board: adb binds the Windows host loopback,
|
|
# and Docker Desktop maps host.docker.internal to the Windows host.
|
|
$NodeUrl = if ($env:NODE_URL) { $env:NODE_URL } else { 'http://host.docker.internal:8080' }
|
|
$Ports = @(8080, 9999)
|
|
|
|
function Log($m) { Write-Host "[connect] $m" -ForegroundColor Cyan }
|
|
function Ok($m) { Write-Host " [OK] $m" -ForegroundColor Green }
|
|
function Warn($m) { Write-Host " [!] $m" -ForegroundColor Yellow }
|
|
|
|
if (-not (Get-Command adb -ErrorAction SilentlyContinue)) {
|
|
Write-Host "connect-board: adb not found on PATH. Install Android platform-tools and reopen the terminal." -ForegroundColor Red
|
|
exit 127
|
|
}
|
|
|
|
function Get-Serial {
|
|
if ($env:SERIAL) { return $env:SERIAL }
|
|
foreach ($line in (& adb devices)) {
|
|
if ($line -match '^(\S+)\s+device$') { return $Matches[1] }
|
|
}
|
|
return $null
|
|
}
|
|
|
|
function Connect-Once {
|
|
$serial = Get-Serial
|
|
if (-not $serial) { Warn 'no board attached over USB'; return $false }
|
|
Ok "board $serial attached"
|
|
|
|
# 1 - forward tunnels (they vanish on re-plug)
|
|
$existing = (& adb -s $serial forward --list) -join "`n"
|
|
foreach ($p in $Ports) {
|
|
if ($existing -notmatch "tcp:$p") { & adb -s $serial forward "tcp:$p" "tcp:$p" | Out-Null }
|
|
}
|
|
Ok "tunnels forwarded ($($Ports -join ' '))"
|
|
|
|
# 2 - wait for the board daemon (App Lab app auto-starts on boot)
|
|
$n = 0
|
|
while ($true) {
|
|
try { Invoke-WebRequest -Uri 'http://127.0.0.1:8080/health' -TimeoutSec 2 -UseBasicParsing | Out-Null; break }
|
|
catch {
|
|
$n++
|
|
if ($n -gt 90) { Warn 'board daemon never came up'; return $false }
|
|
Start-Sleep -Seconds 2
|
|
}
|
|
}
|
|
Ok 'board daemon healthy'
|
|
|
|
# 3 - register with the LOCAL stack (LOCAL_MODE auto-binds it in the browser)
|
|
$body = @{ kitId = $KitId; claimCode = 'local'; url = $NodeUrl; token = 'open-lan' } | ConvertTo-Json -Compress
|
|
try {
|
|
$r = Invoke-RestMethod -Uri "$Api/nodes/self-register" -Method Post `
|
|
-Headers @{ 'x-fleet-secret' = $Secret; 'content-type' = 'application/json' } `
|
|
-Body $body -TimeoutSec 5
|
|
if ($r.url) {
|
|
Ok 'registered with the local stack'
|
|
Log 'attached — it auto-connects in the browser (no code needed)'
|
|
return $true
|
|
}
|
|
Warn "register returned an unexpected response: $($r | ConvertTo-Json -Compress)"
|
|
return $false
|
|
} catch {
|
|
Warn "register failed — is the stack up? ($Web) · $($_.Exception.Message)"
|
|
return $false
|
|
}
|
|
}
|
|
|
|
if ($Watch) {
|
|
Log 'watching for the board — will attach on every (re)connect (Ctrl-C to stop)'
|
|
while ($true) {
|
|
& adb wait-for-device | Out-Null
|
|
Start-Sleep -Seconds 3 # let Linux + the App Lab app finish booting
|
|
if (-not (Connect-Once)) { Warn 'attach incomplete; will retry on next reconnect' }
|
|
while (Get-Serial) { Start-Sleep -Seconds 2 }
|
|
Log 'board disconnected — waiting for re-plug'
|
|
}
|
|
} else {
|
|
[void](Connect-Once)
|
|
}
|