robopark 3.3.37 → 3.3.38

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.
@@ -0,0 +1,128 @@
1
+ /**
2
+ * RoboPark — explicit kiosk microphone/speaker selection.
3
+ *
4
+ * This adds no new API. The vision server already owns the media selection:
5
+ * `GET /api/media/inventory` lists the devices and `POST /api/media/config`
6
+ * sets `audio_device` / `audio_output_device`, forwarding both to
7
+ * audio_server_pi.py's own `/set-device`. The scheduler already stores the
8
+ * chosen values on the device row (`devices.audio_device`,
9
+ * `devices.audio_output_device`, both patchable via `PATCH /api/devices/<id>`).
10
+ *
11
+ * So `--mic` / `--speaker` only resolve a human-typed name or index against
12
+ * that inventory and drive the two endpoints that already exist; the scheduler
13
+ * device row is the persistence, which is what makes a rerun with no flags
14
+ * reapply the previous choice.
15
+ */
16
+ import chalk from 'chalk';
17
+ export async function fetchInventory(port) {
18
+ try {
19
+ const res = await fetch(`http://127.0.0.1:${port}/api/media/inventory`, {
20
+ signal: AbortSignal.timeout(5_000),
21
+ });
22
+ if (!res.ok)
23
+ return null;
24
+ return (await res.json());
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ }
30
+ /**
31
+ * Resolve `--mic ...` / `--speaker ...` to the id the vision server expects.
32
+ *
33
+ * A bare index is passed straight through: the inventory is the audio server's
34
+ * sounddevice list, and on a machine where that server is not running the list
35
+ * is empty but an index is still the right thing to persist. A name is matched
36
+ * case-insensitively, exact first, then unique substring — an ambiguous
37
+ * substring is an error rather than a coin flip, since picking the wrong
38
+ * microphone is silent and looks like a dead agent.
39
+ */
40
+ export function resolveAudioDevice(wanted, choices, kind) {
41
+ const value = wanted.trim();
42
+ if (!value)
43
+ return {};
44
+ if (/^\d+$/.test(value)) {
45
+ const known = choices.find(c => String(c.id) === value);
46
+ return known
47
+ ? { id: value }
48
+ : { id: value, warning: `${kind} index ${value} is not in the vision server's inventory — applying it anyway` };
49
+ }
50
+ const lower = value.toLowerCase();
51
+ const exact = choices.filter(c => String(c.name).toLowerCase() === lower);
52
+ if (exact.length === 1)
53
+ return { id: String(exact[0].id) };
54
+ const partial = choices.filter(c => String(c.name).toLowerCase().includes(lower));
55
+ if (partial.length === 1)
56
+ return { id: String(partial[0].id) };
57
+ if (partial.length > 1) {
58
+ return { error: `"${value}" matches ${partial.length} ${kind}s: ${partial.map(c => `${c.id}=${c.name}`).join(', ')} — pass the index instead` };
59
+ }
60
+ const listed = choices.length
61
+ ? choices.map(c => `${c.id}=${c.name}`).join(', ')
62
+ : '(the vision server reported no audio devices; audio_server_pi.py is not running on this machine)';
63
+ return { error: `no ${kind} matches "${value}". Available: ${listed}` };
64
+ }
65
+ /** Push a selection at the vision server, which forwards it to the audio server. */
66
+ export async function applyAudioSelection(port, selection) {
67
+ const body = {};
68
+ if (selection.audioDevice !== undefined)
69
+ body.audio_device = selection.audioDevice;
70
+ if (selection.audioOutputDevice !== undefined)
71
+ body.audio_output_device = selection.audioOutputDevice;
72
+ if (!Object.keys(body).length)
73
+ return true;
74
+ try {
75
+ const res = await fetch(`http://127.0.0.1:${port}/api/media/config`, {
76
+ method: 'POST',
77
+ headers: { 'content-type': 'application/json' },
78
+ body: JSON.stringify(body),
79
+ signal: AbortSignal.timeout(8_000),
80
+ });
81
+ return res.ok;
82
+ }
83
+ catch {
84
+ return false;
85
+ }
86
+ }
87
+ /**
88
+ * Turn the flags (or, with no flags, the values already stored on the device
89
+ * row) into a selection to apply.
90
+ *
91
+ * Throws on an unresolvable name: a kiosk that silently kept the Windows
92
+ * default after being told which microphone to use is the failure this flag
93
+ * exists to remove.
94
+ */
95
+ export async function planAudioSelection(port, flags, stored) {
96
+ const selection = {};
97
+ if (!flags.mic && !flags.speaker) {
98
+ // No flags: reapply what a previous run persisted, so reruns are stable.
99
+ if (stored.audioDevice)
100
+ selection.audioDevice = String(stored.audioDevice);
101
+ if (stored.audioOutputDevice)
102
+ selection.audioOutputDevice = String(stored.audioOutputDevice);
103
+ return selection;
104
+ }
105
+ const inventory = (await fetchInventory(port)) ?? {};
106
+ if (inventory.audio_server && inventory.audio_server.online === false) {
107
+ console.log(chalk.yellow(` ⚠ audio: the vision server cannot reach audio_server_pi.py (${inventory.audio_server.error ?? 'offline'})`));
108
+ console.log(chalk.dim(' the selection is still recorded and pushed, but nothing will switch devices until that server runs'));
109
+ }
110
+ if (flags.mic) {
111
+ const resolved = resolveAudioDevice(flags.mic, inventory.audio_input ?? [], 'microphone');
112
+ if (resolved.error)
113
+ throw new Error(resolved.error);
114
+ if (resolved.warning)
115
+ console.log(chalk.yellow(` ⚠ ${resolved.warning}`));
116
+ selection.audioDevice = resolved.id;
117
+ }
118
+ if (flags.speaker) {
119
+ const resolved = resolveAudioDevice(flags.speaker, inventory.audio_output ?? [], 'speaker');
120
+ if (resolved.error)
121
+ throw new Error(resolved.error);
122
+ if (resolved.warning)
123
+ console.log(chalk.yellow(` ⚠ ${resolved.warning}`));
124
+ selection.audioOutputDevice = resolved.id;
125
+ }
126
+ return selection;
127
+ }
128
+ //# sourceMappingURL=audio-select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-select.js","sourceRoot":"","sources":["../../src/robopark/audio-select.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,185 @@
1
+ /**
2
+ * RoboPark — camera/microphone device preemption.
3
+ *
4
+ * On a kiosk the vision server is the sole owner of the capture devices. A USB
5
+ * camera on Windows cannot be opened twice, so any leftover holder makes the
6
+ * MJPEG generator yield nothing: Flask answers `/` with 200 while `/video_feed`
7
+ * never produces a first byte. That is the exact shape of the kongor failure
8
+ * this module exists to prevent.
9
+ *
10
+ * The selection is an ALLOWLIST, not a heuristic sweep. Only three families are
11
+ * ever targeted, and every one of them is something robopark itself started:
12
+ * 1. the vision/audio python servers, matched on their script filename;
13
+ * 2. a python process listening on the vision port;
14
+ * 3. a kiosk browser running out of a `~/.robopark/kiosk-*` profile directory,
15
+ * which is the dedicated profile `kiosk-browser.ts` creates and nothing
16
+ * else on the machine uses.
17
+ *
18
+ * Everything else is skipped and reported. Node processes are never candidates
19
+ * at all: a false positive here would take down the infinicode mesh node, the
20
+ * scheduler, or the control-center UI, which is far worse than a camera that
21
+ * fails to open.
22
+ */
23
+ import { spawnSync } from 'node:child_process';
24
+ /** Python scripts that open the camera or the audio devices. */
25
+ const DEVICE_SCRIPTS = [
26
+ 'app_pi_clean.py',
27
+ 'audio_server_pi.py',
28
+ 'vision_motion_trigger.py',
29
+ ];
30
+ const PYTHON_IMAGE = /^(python|python3|pythonw)(\d(\.\d+)?)?(\.exe)?$/i;
31
+ const BROWSER_IMAGE = /^(chrome|msedge|brave|chromium|chromium-browser|google-chrome|firefox|firefox-esr)(\.exe)?$/i;
32
+ /**
33
+ * The kiosk profile directory `kiosk-browser.ts` builds
34
+ * (`~/.robopark/kiosk-<robot>-<family>`). Matching the path rather than the
35
+ * browser image is what separates the kiosk window from the operator's own
36
+ * browser, which must never be touched.
37
+ */
38
+ const KIOSK_PROFILE = /[\\/]\.robopark[\\/]kiosk-/i;
39
+ /**
40
+ * Processes that are never killed, whatever else they look like.
41
+ *
42
+ * These are the operator's tooling. `/T` is likewise never used anywhere in
43
+ * this module: killing a process tree has previously taken the infinicode mesh
44
+ * node down as collateral.
45
+ */
46
+ const PROTECTED = [
47
+ { pattern: /infinicode/i, label: 'infinicode mesh node' },
48
+ { pattern: /robopark[\\/]scheduler|scheduler[\\/]main\.py|uvicorn/i, label: 'robopark scheduler' },
49
+ { pattern: /\bnext\b|frontend-service|robopark[\\/]ui/i, label: 'control-center UI' },
50
+ { pattern: /robopark-cli|[\\/]bin[\\/]robopark/i, label: 'robopark CLI' },
51
+ ];
52
+ function protectedBy(cmd) {
53
+ return PROTECTED.find(entry => entry.pattern.test(cmd))?.label ?? null;
54
+ }
55
+ /** Every process on this machine, with its full command line. */
56
+ export function listProcesses() {
57
+ if (process.platform === 'win32') {
58
+ const res = spawnSync('powershell', [
59
+ '-NoProfile',
60
+ '-NonInteractive',
61
+ '-Command',
62
+ 'Get-CimInstance Win32_Process | Select-Object ProcessId,Name,CommandLine | ConvertTo-Json -Compress',
63
+ ], { encoding: 'utf8', maxBuffer: 32 * 1024 * 1024 });
64
+ if (res.status !== 0 || !res.stdout.trim())
65
+ return [];
66
+ try {
67
+ const parsed = JSON.parse(res.stdout);
68
+ const rows = Array.isArray(parsed) ? parsed : [parsed];
69
+ return rows.map(r => ({ pid: Number(r.ProcessId), name: String(r.Name ?? ''), cmd: String(r.CommandLine ?? '') }));
70
+ }
71
+ catch {
72
+ return [];
73
+ }
74
+ }
75
+ const res = spawnSync('ps', ['-eo', 'pid=,comm=,args='], { encoding: 'utf8', maxBuffer: 32 * 1024 * 1024 });
76
+ if (res.status !== 0)
77
+ return [];
78
+ return res.stdout
79
+ .split('\n')
80
+ .map(line => line.trim().match(/^(\d+)\s+(\S+)\s*(.*)$/))
81
+ .filter((m) => Boolean(m))
82
+ .map(m => ({ pid: Number(m[1]), name: m[2].split('/').pop() ?? m[2], cmd: m[3] }));
83
+ }
84
+ /** PIDs listening on `port`, whatever they are. */
85
+ export function listenersOn(port) {
86
+ const pids = new Set();
87
+ if (process.platform === 'win32') {
88
+ const res = spawnSync('netstat', ['-ano', '-p', 'tcp'], { encoding: 'utf8', maxBuffer: 8 * 1024 * 1024 });
89
+ if (res.status !== 0)
90
+ return pids;
91
+ for (const line of res.stdout.split('\n')) {
92
+ if (!/LISTENING/i.test(line))
93
+ continue;
94
+ const parts = line.trim().split(/\s+/);
95
+ const local = parts[1] ?? '';
96
+ if (!local.endsWith(`:${port}`))
97
+ continue;
98
+ const pid = Number(parts[parts.length - 1]);
99
+ if (Number.isInteger(pid) && pid > 0)
100
+ pids.add(pid);
101
+ }
102
+ return pids;
103
+ }
104
+ const res = spawnSync('lsof', ['-nP', `-iTCP:${port}`, '-sTCP:LISTEN', '-t'], { encoding: 'utf8' });
105
+ if (res.status !== 0)
106
+ return pids;
107
+ for (const line of res.stdout.split('\n')) {
108
+ const pid = Number(line.trim());
109
+ if (Number.isInteger(pid) && pid > 0)
110
+ pids.add(pid);
111
+ }
112
+ return pids;
113
+ }
114
+ /**
115
+ * Decide, without killing anything, which processes hold the kiosk's devices.
116
+ *
117
+ * `skipped` only records processes that came close enough to matter — a
118
+ * protected process, or something on the vision port that is not ours. Listing
119
+ * every idle process would bury the two lines an operator needs to read.
120
+ */
121
+ export function planPreemption(port, rows, listeners) {
122
+ const targets = [];
123
+ const skipped = [];
124
+ const self = new Set([process.pid, process.ppid]);
125
+ for (const row of rows) {
126
+ if (self.has(row.pid))
127
+ continue;
128
+ const script = DEVICE_SCRIPTS.find(s => row.cmd.includes(s));
129
+ const isPython = PYTHON_IMAGE.test(row.name);
130
+ const onPort = listeners.has(row.pid);
131
+ const kioskBrowser = BROWSER_IMAGE.test(row.name) && KIOSK_PROFILE.test(row.cmd);
132
+ let reason = null;
133
+ if (isPython && script)
134
+ reason = `vision/audio server (${script})`;
135
+ else if (isPython && onPort)
136
+ reason = `python listening on the vision port ${port}`;
137
+ else if (kioskBrowser)
138
+ reason = `robopark kiosk browser (~/.robopark/kiosk-* profile)`;
139
+ if (!reason) {
140
+ // Anything else holding the vision port is reported but not killed: it is
141
+ // not a process robopark started, so it is not ours to terminate.
142
+ if (onPort) {
143
+ skipped.push({ pid: row.pid, name: row.name, reason: `holds port ${port} but is not a robopark python server — not killing; stop it yourself if the feed stays dead` });
144
+ }
145
+ continue;
146
+ }
147
+ const guard = protectedBy(row.cmd);
148
+ if (guard) {
149
+ skipped.push({ pid: row.pid, name: row.name, reason: `looks like a device holder but is protected (${guard}) — skipped` });
150
+ continue;
151
+ }
152
+ targets.push({ pid: row.pid, name: row.name, reason });
153
+ }
154
+ return { targets, skipped };
155
+ }
156
+ /** Kill one pid. Never `/T`: that would take the process's children with it. */
157
+ function killPid(pid) {
158
+ if (process.platform === 'win32') {
159
+ const res = spawnSync('taskkill', ['/PID', String(pid), '/F'], { encoding: 'utf8' });
160
+ return { ok: res.status === 0, detail: String(res.stderr || res.stdout || '').trim() };
161
+ }
162
+ try {
163
+ process.kill(pid, 'SIGTERM');
164
+ return { ok: true, detail: '' };
165
+ }
166
+ catch (err) {
167
+ return { ok: false, detail: err instanceof Error ? err.message : String(err) };
168
+ }
169
+ }
170
+ export function preemptDevices(port, opts = {}) {
171
+ const plan = planPreemption(port, listProcesses(), listenersOn(port));
172
+ const killed = [];
173
+ const failed = [];
174
+ if (opts.dryRun)
175
+ return { ...plan, killed, failed };
176
+ for (const target of plan.targets) {
177
+ const res = killPid(target.pid);
178
+ if (res.ok)
179
+ killed.push(target);
180
+ else
181
+ failed.push({ ...target, detail: res.detail || 'taskkill failed' });
182
+ }
183
+ return { ...plan, killed, failed };
184
+ }
185
+ //# sourceMappingURL=device-preempt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-preempt.js","sourceRoot":"","sources":["../../src/robopark/device-preempt.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,8 @@
17
17
  import { hostname } from 'node:os';
18
18
  import chalk from 'chalk';
19
19
  import { robotReachableSchedulerUrl, schedulerApiUrl } from './add-robot.js';
20
+ import { applyAudioSelection, planAudioSelection } from './audio-select.js';
21
+ import { preemptDevices } from './device-preempt.js';
20
22
  import { findBrowser, kioskLaunch, launchCommandLine, launchKiosk } from './kiosk-browser.js';
21
23
  import { loadHubProfile } from './profile.js';
22
24
  import { resolveTailnet } from './tailscale.js';
@@ -29,19 +31,32 @@ const READY_TIMEOUT_MS = 30_000;
29
31
  const READY_POLL_MS = 1_000;
30
32
  const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
31
33
  /**
32
- * True once the local vision server actually answers on /video_feed.
34
+ * True once the local vision server actually delivers a frame on /video_feed.
33
35
  *
34
- * The body is an endless multipart stream, so it must be cancelled rather than
35
- * read: awaiting it would never resolve and the probe would look like a hang
36
- * instead of a success.
36
+ * Response headers are NOT enough: when the capture device cannot be opened,
37
+ * Flask still streams a multipart body whose generator never yields, so a
38
+ * 200 here can coexist with a completely dead camera. Requiring one real chunk
39
+ * is what makes "ready" mean the camera works. The body is an endless stream,
40
+ * so the reader is cancelled rather than drained — awaiting it would never
41
+ * resolve and the probe would look like a hang instead of a success.
37
42
  */
38
43
  async function feedReady(port) {
39
44
  const controller = new AbortController();
40
45
  const timer = setTimeout(() => controller.abort(), 4_000);
41
46
  try {
42
47
  const res = await fetch(`http://127.0.0.1:${port}/video_feed`, { signal: controller.signal });
43
- await res.body?.cancel();
44
- return res.ok;
48
+ if (!res.ok || !res.body) {
49
+ await res.body?.cancel();
50
+ return false;
51
+ }
52
+ const reader = res.body.getReader();
53
+ try {
54
+ const { value, done } = await reader.read();
55
+ return !done && Boolean(value?.length);
56
+ }
57
+ finally {
58
+ await reader.cancel().catch(() => { });
59
+ }
45
60
  }
46
61
  catch {
47
62
  return false;
@@ -50,14 +65,69 @@ async function feedReady(port) {
50
65
  clearTimeout(timer);
51
66
  }
52
67
  }
68
+ /** True once Flask itself answers, whatever the camera is doing. */
69
+ async function serverAlive(port) {
70
+ try {
71
+ const res = await fetch(`http://127.0.0.1:${port}/`, { signal: AbortSignal.timeout(3_000) });
72
+ await res.body?.cancel();
73
+ return true;
74
+ }
75
+ catch {
76
+ return false;
77
+ }
78
+ }
79
+ /** The vision server's own view of the capture device, for the failure message. */
80
+ async function cameraStatus(port) {
81
+ try {
82
+ const res = await fetch(`http://127.0.0.1:${port}/api/camera/status`, { signal: AbortSignal.timeout(3_000) });
83
+ if (!res.ok)
84
+ return `HTTP ${res.status}`;
85
+ const status = (await res.json());
86
+ return `device=${status.device ?? '?'} open=${status.open ? 'yes' : 'no'}${status.read_stalled ? ' read=stalled' : ''}`;
87
+ }
88
+ catch {
89
+ return 'unavailable';
90
+ }
91
+ }
92
+ /**
93
+ * Distinguish "nothing is listening" from "Flask is up but the camera yields
94
+ * nothing" — the kongor failure, where `/` answered 200 and `/video_feed`
95
+ * answered nothing at all. Reporting both as "the vision server never
96
+ * answered" sent the operator looking for a process that was in fact running.
97
+ */
53
98
  async function waitForFeed(port) {
54
99
  const deadline = Date.now() + READY_TIMEOUT_MS;
100
+ let everAlive = false;
55
101
  while (Date.now() < deadline) {
56
102
  if (await feedReady(port))
57
- return true;
103
+ return 'ready';
104
+ if (!everAlive && (await serverAlive(port)))
105
+ everAlive = true;
58
106
  await sleep(READY_POLL_MS);
59
107
  }
60
- return false;
108
+ return everAlive ? 'camera-dead' : 'down';
109
+ }
110
+ /**
111
+ * Wait for the local feed; return null when ready, else the operator-facing
112
+ * reason it is not.
113
+ *
114
+ * Kept separate from the caller so the two failures can be told apart in the
115
+ * message: everything an operator would do about a server that never started
116
+ * is the wrong move for a server that is up with a dead camera.
117
+ */
118
+ export async function awaitVisionReady(port) {
119
+ const readiness = await waitForFeed(port);
120
+ if (readiness === 'ready')
121
+ return null;
122
+ if (readiness === 'camera-dead') {
123
+ return (`vision server up but camera not producing frames: http://127.0.0.1:${port}/ answers, ` +
124
+ `but /video_feed yielded nothing within ${READY_TIMEOUT_MS / 1000}s (camera status: ${await cameraStatus(port)}). ` +
125
+ 'Another process is probably still holding the camera, or the selected device is wrong — ' +
126
+ `check http://127.0.0.1:${port}/api/media/inventory, make sure you did not pass --no-preempt, ` +
127
+ "and rerun with --foreground to see the server's output");
128
+ }
129
+ return (`the vision server never started: nothing answered http://127.0.0.1:${port}/ within ${READY_TIMEOUT_MS / 1000}s — ` +
130
+ 'rerun with --foreground to see why the python process exited');
61
131
  }
62
132
  /**
63
133
  * This machine's mesh identity, or null when no node is listening.
@@ -161,6 +231,43 @@ async function registerDevice(schedulerUrl, name, host, token) {
161
231
  }
162
232
  return { ...(device ?? { name }), id: deviceId };
163
233
  }
234
+ /**
235
+ * Apply `--mic` / `--speaker` (or, with neither, whatever a previous run
236
+ * persisted on the device row) to the vision server, and persist an explicit
237
+ * choice back to the scheduler so the next run reapplies it without the flags.
238
+ */
239
+ async function selectAudio(schedulerUrl, port, device, opts, token) {
240
+ const explicit = Boolean(opts.mic || opts.speaker);
241
+ const selection = await planAudioSelection(port, { mic: opts.mic, speaker: opts.speaker }, { audioDevice: device.audio_device, audioOutputDevice: device.audio_output_device });
242
+ if (!selection.audioDevice && !selection.audioOutputDevice) {
243
+ console.log(chalk.dim(' audio: no explicit device selected — the vision server keeps the system default'));
244
+ console.log(chalk.dim(' pin one with `robopark start <robot> --mic <name|index> --speaker <name|index>`'));
245
+ return;
246
+ }
247
+ const applied = await applyAudioSelection(port, selection);
248
+ const described = [
249
+ selection.audioDevice !== undefined ? `mic=${selection.audioDevice}` : null,
250
+ selection.audioOutputDevice !== undefined ? `speaker=${selection.audioOutputDevice}` : null,
251
+ ].filter(Boolean).join(' ');
252
+ if (applied)
253
+ console.log(chalk.green(` ✓ audio devices selected (${described})${explicit ? '' : ' — restored from the device record'}`));
254
+ else
255
+ console.log(chalk.yellow(` ⚠ the vision server did not accept the audio selection (${described})`));
256
+ if (!explicit)
257
+ return;
258
+ const patched = await fetch(schedulerApiUrl(schedulerUrl, `/api/devices/${encodeURIComponent(device.id)}`, token), {
259
+ method: 'PATCH',
260
+ headers: { 'content-type': 'application/json' },
261
+ body: JSON.stringify({
262
+ audio_device: selection.audioDevice,
263
+ audio_output_device: selection.audioOutputDevice,
264
+ }),
265
+ });
266
+ if (patched.ok)
267
+ console.log(chalk.dim(' persisted on the scheduler device record — reruns need no flags'));
268
+ else
269
+ console.log(chalk.yellow(` ⚠ could not persist the audio selection: HTTP ${patched.status}`));
270
+ }
164
271
  /**
165
272
  * The character this kiosk should answer as.
166
273
  *
@@ -205,7 +312,18 @@ async function openKiosk(schedulerUrl, browserBase, name, device, opts, token) {
205
312
  // mode=production ties the call to this device so the scheduler attaches the
206
313
  // robot's video ref; kiosk=1 arms the page's motion trigger, which is what
207
314
  // starts a conversation with nobody available to press "Join".
208
- const url = characterCallUrl(browserBase, preset, 'production', { robot: device.id, kiosk: '1' });
315
+ //
316
+ // camera=off is what keeps this page off the capture device entirely: the
317
+ // vision server owns it, the control-center feed is its MJPEG stream, and a
318
+ // browser getUserMedia({video}) here would either fail or steal the camera
319
+ // back. The page then takes its motion trigger from the vision server's own
320
+ // /api/motion/status instead of a local camera.
321
+ const url = characterCallUrl(browserBase, preset, 'production', {
322
+ robot: device.id,
323
+ kiosk: '1',
324
+ camera: 'off',
325
+ vision_base: `http://127.0.0.1:${opts.port ?? DEFAULT_VISION_PORT}`,
326
+ });
209
327
  console.log(` call page: ${chalk.cyan(url)}`);
210
328
  if (opts.browser === false) {
211
329
  console.log(chalk.dim(' browser: --no-browser given — open the link above on the kiosk yourself'));
@@ -262,10 +380,51 @@ export async function roboparkStart(config, name, opts) {
262
380
  await ensureMesh(config, name, profile.token);
263
381
  else
264
382
  console.log(chalk.dim(' mesh: skipped (video does not need it) — pass --mesh to enroll'));
265
- let running = null;
266
383
  // A prior run (or --mesh enrollment, which starts the robot runtime) often
267
384
  // left the feed already live, so there may be nothing left to launch.
268
- if (await feedReady(port)) {
385
+ const alreadyLive = await feedReady(port);
386
+ // The vision server is the sole owner of this kiosk's camera and microphone.
387
+ // A USB camera on Windows cannot be opened twice, so a leftover holder — a
388
+ // previous vision agent, or the kiosk browser this command itself launched
389
+ // last run — is exactly what makes /video_feed answer nothing.
390
+ //
391
+ // A feed that is already producing frames proves nothing is competing, so it
392
+ // is left strictly alone: preempting there would kill a working camera and
393
+ // restart it for no reason.
394
+ if (opts.preempt === false) {
395
+ console.log(chalk.dim(' preempt: skipped (--no-preempt) — a leftover camera holder will block the feed'));
396
+ }
397
+ else if (alreadyLive && !opts.preemptDryRun) {
398
+ console.log(chalk.dim(' preempt: skipped — the feed is already producing frames, so nothing is competing'));
399
+ }
400
+ else {
401
+ const dryRun = Boolean(opts.preemptDryRun);
402
+ const result = preemptDevices(port, { dryRun });
403
+ console.log(chalk.dim(` preempt: ${dryRun ? 'DRY RUN — nothing will be killed' : 'terminating competing camera/audio holders'}`));
404
+ for (const target of result.targets) {
405
+ console.log(dryRun
406
+ ? chalk.yellow(` would kill pid ${target.pid} ${target.name} — ${target.reason}`)
407
+ : chalk.dim(` target pid ${target.pid} ${target.name} — ${target.reason}`));
408
+ }
409
+ for (const skip of result.skipped) {
410
+ console.log(chalk.yellow(` skipped pid ${skip.pid} ${skip.name} — ${skip.reason}`));
411
+ }
412
+ for (const killed of result.killed) {
413
+ console.log(chalk.green(` ✓ killed pid ${killed.pid} ${killed.name} (${killed.reason})`));
414
+ }
415
+ for (const fail of result.failed) {
416
+ console.log(chalk.red(` ✗ could not kill pid ${fail.pid} ${fail.name}: ${fail.detail}`));
417
+ }
418
+ if (!result.targets.length && !result.skipped.length) {
419
+ console.log(chalk.dim(' nothing competing for the camera or microphone'));
420
+ }
421
+ if (dryRun) {
422
+ console.log(chalk.yellow('\n --preempt-dry-run: stopping here without starting anything.\n'));
423
+ return;
424
+ }
425
+ }
426
+ let running = null;
427
+ if (alreadyLive) {
269
428
  console.log(chalk.dim(' vision server already answering — reusing it'));
270
429
  }
271
430
  else {
@@ -277,12 +436,13 @@ export async function roboparkStart(config, name, opts) {
277
436
  else
278
437
  await launch;
279
438
  }
280
- if (!(await waitForFeed(port))) {
281
- throw new Error(`the vision server never answered http://127.0.0.1:${port}/video_feed within ${READY_TIMEOUT_MS / 1000}s — check the camera device and rerun with --foreground to see its output`);
282
- }
439
+ const failure = await awaitVisionReady(port);
440
+ if (failure)
441
+ throw new Error(failure);
283
442
  console.log(chalk.green(` ✓ local feed ready at http://127.0.0.1:${port}/video_feed`));
284
443
  const device = await registerDevice(schedulerUrl, name, host, profile.token);
285
444
  console.log(chalk.green(` ✓ registered '${name}' at the scheduler (device ${device.id})`));
445
+ await selectAudio(schedulerUrl, port, device, opts, profile.token);
286
446
  const base = profile.schedulerUrl.replace(/\/+$/, '');
287
447
  console.log();
288
448
  console.log(` control center: ${chalk.cyan(base)}`);
@@ -1 +1 @@
1
- {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/robopark/start.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/robopark/start.ts"],"names":[],"mappings":"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"}