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.
- package/dist/robopark/audio-select.js +128 -0
- package/dist/robopark/audio-select.js.map +1 -0
- package/dist/robopark/device-preempt.js +185 -0
- package/dist/robopark/device-preempt.js.map +1 -0
- package/dist/robopark/start.js +174 -14
- package/dist/robopark/start.js.map +1 -1
- package/dist/robopark-cli.js +4 -0
- package/dist/robopark-cli.js.map +1 -1
- package/package.json +1 -1
- package/scheduler/static/voice-join.html +48 -2
- package/ui/standalone/.next/BUILD_ID +1 -1
- package/ui/standalone/.next/app-build-manifest.json +50 -50
- package/ui/standalone/.next/app-path-routes-manifest.json +15 -15
- package/ui/standalone/.next/build-manifest.json +2 -2
- package/ui/standalone/.next/server/app-paths-manifest.json +15 -15
- package/ui/standalone/.next/server/functions-config-manifest.json +1 -1
- package/ui/standalone/.next/server/pages/500.html +1 -1
- package/ui/standalone/public/voice-join.html +48 -2
- /package/ui/standalone/.next/static/{8E9-VDckMmTbkbuwnaatU → 2zW74Q0KZAsncyNMwT9yQ}/_buildManifest.js +0 -0
- /package/ui/standalone/.next/static/{8E9-VDckMmTbkbuwnaatU → 2zW74Q0KZAsncyNMwT9yQ}/_ssgManifest.js +0 -0
|
@@ -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":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAkB1B,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY;IAC/C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,sBAAsB,EAAE;YACtE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;SACnC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QACzB,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAmB,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAc,EACd,OAA2B,EAC3B,IAA8B;IAE9B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC;QACxD,OAAO,KAAK;YACV,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE;YACf,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,UAAU,KAAK,+DAA+D,EAAE,CAAC;IACpH,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC;IAC1E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC3D,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAClF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC/D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,KAAK,EAAE,IAAI,KAAK,aAAa,OAAO,CAAC,MAAM,IAAI,IAAI,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,2BAA2B,EAAE,CAAC;IAClJ,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM;QAC3B,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAClD,CAAC,CAAC,kGAAkG,CAAC;IACvG,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,aAAa,KAAK,iBAAiB,MAAM,EAAE,EAAE,CAAC;AAC1E,CAAC;AAED,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAAY,EAAE,SAAyB;IAC/E,MAAM,IAAI,GAA2B,EAAE,CAAC;IACxC,IAAI,SAAS,CAAC,WAAW,KAAK,SAAS;QAAE,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC,WAAW,CAAC;IACnF,IAAI,SAAS,CAAC,iBAAiB,KAAK,SAAS;QAAE,IAAI,CAAC,mBAAmB,GAAG,SAAS,CAAC,iBAAiB,CAAC;IACtG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,mBAAmB,EAAE;YACnE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAC1B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;SACnC,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,EAAE,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAY,EACZ,KAAyC,EACzC,MAA0E;IAE1E,MAAM,SAAS,GAAmB,EAAE,CAAC;IACrC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACjC,yEAAyE;QACzE,IAAI,MAAM,CAAC,WAAW;YAAE,SAAS,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC3E,IAAI,MAAM,CAAC,iBAAiB;YAAE,SAAS,CAAC,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAC7F,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,SAAS,GAAG,CAAC,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IACrD,IAAI,SAAS,CAAC,YAAY,IAAI,SAAS,CAAC,YAAY,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,iEAAiE,SAAS,CAAC,YAAY,CAAC,KAAK,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC;QACzI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,wGAAwG,CAAC,CAAC,CAAC;IACnI,CAAC;IAED,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;QACd,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,WAAW,IAAI,EAAE,EAAE,YAAY,CAAC,CAAC;QAC1F,IAAI,QAAQ,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACpD,IAAI,QAAQ,CAAC,OAAO;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC3E,SAAS,CAAC,WAAW,GAAG,QAAQ,CAAC,EAAE,CAAC;IACtC,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC,YAAY,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC;QAC5F,IAAI,QAAQ,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACpD,IAAI,QAAQ,CAAC,OAAO;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC3E,SAAS,CAAC,iBAAiB,GAAG,QAAQ,CAAC,EAAE,CAAC;IAC5C,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -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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"}
|
package/dist/robopark/start.js
CHANGED
|
@@ -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
|
|
34
|
+
* True once the local vision server actually delivers a frame on /video_feed.
|
|
33
35
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
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
|
-
|
|
44
|
-
|
|
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
|
|
103
|
+
return 'ready';
|
|
104
|
+
if (!everAlive && (await serverAlive(port)))
|
|
105
|
+
everAlive = true;
|
|
58
106
|
await sleep(READY_POLL_MS);
|
|
59
107
|
}
|
|
60
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
281
|
-
|
|
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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"}
|