@iobroker/assistant-satellite 0.0.2 → 0.1.0
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/LICENSE +1 -1
- package/README.md +7 -1
- package/build/audio.d.ts +16 -2
- package/build/audio.js +42 -38
- package/build/audio.js.map +1 -1
- package/build/checks.js.map +1 -1
- package/build/cli.js.map +1 -1
- package/build/config.d.ts +2 -0
- package/build/config.js +1 -0
- package/build/config.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.js +3 -1
- package/build/index.js.map +1 -1
- package/build/models.js.map +1 -1
- package/build/probe.d.ts +16 -0
- package/build/probe.js +69 -0
- package/build/probe.js.map +1 -0
- package/build/protocol.js.map +1 -1
- package/build/satellite.d.ts +2 -0
- package/build/satellite.js +17 -2
- package/build/satellite.js.map +1 -1
- package/build/service.js.map +1 -1
- package/build/vad.js.map +1 -1
- package/build/wakeword.js.map +1 -1
- package/package.json +11 -3
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -143,6 +143,12 @@ threshold should be validated on the target device.
|
|
|
143
143
|
Placeholder for the next version (at the beginning of the line):
|
|
144
144
|
### **WORK IN PROGRESS**
|
|
145
145
|
-->
|
|
146
|
+
### 0.1.0 (2026-07-05)
|
|
147
|
+
* (@GermanBluefox) Added Wake-word probe
|
|
148
|
+
|
|
149
|
+
### 0.0.4 (2026-07-05)
|
|
150
|
+
* (@GermanBluefox) Barge-in: if the wake word fires while the reply is playing, stop playback and listen again.
|
|
151
|
+
|
|
146
152
|
### 0.0.2 (2026-07-05)
|
|
147
153
|
* (@GermanBluefox) Initial commit
|
|
148
154
|
|
|
@@ -150,7 +156,7 @@ threshold should be validated on the target device.
|
|
|
150
156
|
|
|
151
157
|
MIT License
|
|
152
158
|
|
|
153
|
-
Copyright (c)
|
|
159
|
+
Copyright (c) 2026 Denis Haev <dogafox@gmail.com>
|
|
154
160
|
|
|
155
161
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
156
162
|
of this software and associated documentation files (the "Software"), to deal
|
package/build/audio.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audio I/O with two backends:
|
|
3
|
+
* - 'alsa' : spawn `arecord`/`aplay` — robust on a Pi, no native build (Linux only).
|
|
4
|
+
* - 'ffmpeg': spawn `ffmpeg`/`ffplay` — cross-platform (Windows / macOS / Linux).
|
|
5
|
+
*
|
|
6
|
+
* Capture is always 16 kHz mono 16-bit; use a `plughw:CARD,DEV` device (ALSA) so it resamples.
|
|
7
|
+
*/
|
|
8
|
+
import { type ChildProcess } from 'node:child_process';
|
|
1
9
|
import type { Logger } from './index';
|
|
2
10
|
export type AudioBackend = 'alsa' | 'ffmpeg';
|
|
3
11
|
/** Resolve 'auto' → alsa on Linux, ffmpeg elsewhere. */
|
|
@@ -14,7 +22,13 @@ export declare class Mic {
|
|
|
14
22
|
start(onData: (pcm: Buffer) => void): void;
|
|
15
23
|
stop(): void;
|
|
16
24
|
}
|
|
17
|
-
/**
|
|
18
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Play raw mono 16-bit PCM at the given rate. Returns the child process (so playback can be cancelled
|
|
27
|
+
* for barge-in) and a `done` promise that resolves when playback finishes or is killed.
|
|
28
|
+
*/
|
|
29
|
+
export declare function playPcm(pcm: Buffer, sampleRate: number, backend: AudioBackend, device: string, log: Logger): {
|
|
30
|
+
proc: ChildProcess;
|
|
31
|
+
done: Promise<void>;
|
|
32
|
+
};
|
|
19
33
|
/** A short rising "listening" beep (mono 16-bit @ 16 kHz), synthesised once. */
|
|
20
34
|
export declare function pling(): Buffer;
|
package/build/audio.js
CHANGED
|
@@ -87,51 +87,55 @@ class Mic {
|
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
exports.Mic = Mic;
|
|
90
|
-
/**
|
|
90
|
+
/**
|
|
91
|
+
* Play raw mono 16-bit PCM at the given rate. Returns the child process (so playback can be cancelled
|
|
92
|
+
* for barge-in) and a `done` promise that resolves when playback finishes or is killed.
|
|
93
|
+
*/
|
|
91
94
|
function playPcm(pcm, sampleRate, backend, device, log) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
95
|
+
const [cmd, args] = backend === 'ffmpeg'
|
|
96
|
+
? [
|
|
97
|
+
'ffplay',
|
|
98
|
+
[
|
|
99
|
+
'-hide_banner',
|
|
100
|
+
'-loglevel',
|
|
101
|
+
'error',
|
|
102
|
+
'-nodisp',
|
|
103
|
+
'-autoexit',
|
|
104
|
+
'-f',
|
|
105
|
+
's16le',
|
|
106
|
+
'-ar',
|
|
107
|
+
String(sampleRate),
|
|
108
|
+
'-ch_layout',
|
|
109
|
+
'mono',
|
|
110
|
+
'-i',
|
|
111
|
+
'-',
|
|
112
|
+
],
|
|
113
|
+
]
|
|
114
|
+
: [
|
|
115
|
+
'aplay',
|
|
116
|
+
[
|
|
117
|
+
'-q',
|
|
118
|
+
'-t',
|
|
119
|
+
'raw',
|
|
120
|
+
'-f',
|
|
121
|
+
'S16_LE',
|
|
122
|
+
'-c',
|
|
123
|
+
'1',
|
|
124
|
+
'-r',
|
|
125
|
+
String(sampleRate),
|
|
126
|
+
...(device && device !== 'default' ? ['-D', device] : []),
|
|
127
|
+
],
|
|
128
|
+
];
|
|
129
|
+
const proc = (0, node_child_process_1.spawn)(cmd, args);
|
|
130
|
+
const done = new Promise(resolve => {
|
|
128
131
|
proc.on('close', () => resolve());
|
|
129
132
|
proc.on('error', e => {
|
|
130
133
|
log.error(`${cmd} failed: ${e.message}`);
|
|
131
134
|
resolve();
|
|
132
135
|
});
|
|
133
|
-
proc.stdin?.end(pcm);
|
|
134
136
|
});
|
|
137
|
+
proc.stdin?.end(pcm);
|
|
138
|
+
return { proc, done };
|
|
135
139
|
}
|
|
136
140
|
/** A short rising "listening" beep (mono 16-bit @ 16 kHz), synthesised once. */
|
|
137
141
|
function pling() {
|
package/build/audio.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio.js","sourceRoot":"","sources":["../src/audio.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"audio.js","sourceRoot":"","sources":["../src/audio.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Audio I/O with two backends:\n * - 'alsa' : spawn `arecord`/`aplay` — robust on a Pi, no native build (Linux only).\n * - 'ffmpeg': spawn `ffmpeg`/`ffplay` — cross-platform (Windows / macOS / Linux).\n *\n * Capture is always 16 kHz mono 16-bit; use a `plughw:CARD,DEV` device (ALSA) so it resamples.\n */\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport { AUDIO_SAMPLE_RATE } from './protocol';\nimport type { Logger } from './index';\n\nexport type AudioBackend = 'alsa' | 'ffmpeg';\n\n/** Resolve 'auto' → alsa on Linux, ffmpeg elsewhere. */\nexport function resolveBackend(pref: string): AudioBackend {\n if (pref === 'alsa' || pref === 'ffmpeg') {\n return pref;\n }\n return process.platform === 'linux' ? 'alsa' : 'ffmpeg';\n}\n\n/** ffmpeg capture input args per platform (device = dshow name / avfoundation index / ALSA name). */\nexport function ffmpegInput(device: string): string[] {\n if (process.platform === 'win32') {\n return ['-f', 'dshow', '-i', `audio=${device || 'default'}`];\n }\n if (process.platform === 'darwin') {\n return ['-f', 'avfoundation', '-i', `:${device || '0'}`];\n }\n return ['-f', 'alsa', '-i', device || 'default'];\n}\n\n/** Continuous microphone capture at 16 kHz mono 16-bit; emits raw PCM chunks. */\nexport class Mic {\n private proc: ChildProcess | null = null;\n\n constructor(\n private readonly backend: AudioBackend,\n private readonly device: string,\n private readonly log: Logger,\n ) {}\n\n start(onData: (pcm: Buffer) => void): void {\n const [cmd, args] =\n this.backend === 'ffmpeg'\n ? ([\n 'ffmpeg',\n [\n '-hide_banner',\n '-loglevel',\n 'error',\n ...ffmpegInput(this.device),\n '-ac',\n '1',\n '-ar',\n String(AUDIO_SAMPLE_RATE),\n '-f',\n 's16le',\n '-',\n ],\n ] as const)\n : ([\n 'arecord',\n [\n '-q',\n '-t',\n 'raw',\n '-f',\n 'S16_LE',\n '-c',\n '1',\n '-r',\n String(AUDIO_SAMPLE_RATE),\n ...(this.device && this.device !== 'default' ? ['-D', this.device] : []),\n ],\n ] as const);\n\n this.proc = spawn(cmd, args);\n this.proc.stdout?.on('data', (d: Buffer) => onData(d));\n this.proc.stderr?.on('data', (d: Buffer) => this.log.debug(`${cmd}: ${d.toString().trim()}`));\n this.proc.on('error', e =>\n this.log.error(\n `${cmd} failed: ${e.message} — is it installed? ${this.backend === 'ffmpeg' ? '(install ffmpeg)' : '(sudo apt install alsa-utils)'}`,\n ),\n );\n this.log.info(\n `Microphone capture started (${this.backend}: ${this.device || 'default'} @ ${AUDIO_SAMPLE_RATE} Hz).`,\n );\n }\n\n stop(): void {\n this.proc?.kill();\n this.proc = null;\n }\n}\n\n/**\n * Play raw mono 16-bit PCM at the given rate. Returns the child process (so playback can be cancelled\n * for barge-in) and a `done` promise that resolves when playback finishes or is killed.\n */\nexport function playPcm(\n pcm: Buffer,\n sampleRate: number,\n backend: AudioBackend,\n device: string,\n log: Logger,\n): { proc: ChildProcess; done: Promise<void> } {\n const [cmd, args] =\n backend === 'ffmpeg'\n ? ([\n 'ffplay',\n [\n '-hide_banner',\n '-loglevel',\n 'error',\n '-nodisp',\n '-autoexit',\n '-f',\n 's16le',\n '-ar',\n String(sampleRate),\n '-ch_layout',\n 'mono',\n '-i',\n '-',\n ],\n ] as const)\n : ([\n 'aplay',\n [\n '-q',\n '-t',\n 'raw',\n '-f',\n 'S16_LE',\n '-c',\n '1',\n '-r',\n String(sampleRate),\n ...(device && device !== 'default' ? ['-D', device] : []),\n ],\n ] as const);\n\n const proc = spawn(cmd, args);\n const done = new Promise<void>(resolve => {\n proc.on('close', () => resolve());\n proc.on('error', e => {\n log.error(`${cmd} failed: ${e.message}`);\n resolve();\n });\n });\n proc.stdin?.end(pcm);\n return { proc, done };\n}\n\n/** A short rising \"listening\" beep (mono 16-bit @ 16 kHz), synthesised once. */\nexport function pling(): Buffer {\n const rate = AUDIO_SAMPLE_RATE;\n const dur = 0.18;\n const n = Math.floor(rate * dur);\n const buf = Buffer.alloc(n * 2);\n for (let i = 0; i < n; i++) {\n const t = i / rate;\n const freq = 880 + (1320 - 880) * (i / n);\n const fade = Math.sin((Math.PI * i) / n);\n const val = Math.max(\n -32768,\n Math.min(32767, Math.round(32767 * 0.6 * fade * Math.sin(2 * Math.PI * freq * t))),\n );\n buf.writeInt16LE(val, i * 2);\n }\n return buf;\n}\n"]}
|
package/build/checks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checks.js","sourceRoot":"","sources":["../src/checks.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"checks.js","sourceRoot":"","sources":["../src/checks.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Preflight checks: run before installing the service (and via the `check` subcommand) to verify\n * everything is present — Node, systemd, root rights, audio tools, and functional mic-in / speaker-out.\n */\nimport { execFileSync } from 'node:child_process';\nimport * as fs from 'node:fs';\nimport { ffmpegInput, type AudioBackend } from './audio';\nimport type { SatelliteConfig } from './config';\nimport type { Logger } from './index';\n\nexport type CheckStatus = 'ok' | 'warn' | 'fail';\nexport interface CheckResult {\n name: string;\n status: CheckStatus;\n detail: string;\n}\n\nconst ok = (name: string, detail = ''): CheckResult => ({ name, status: 'ok', detail });\nconst warn = (name: string, detail: string): CheckResult => ({ name, status: 'warn', detail });\nconst fail = (name: string, detail: string): CheckResult => ({ name, status: 'fail', detail });\n\nfunction which(cmd: string): boolean {\n try {\n execFileSync(process.platform === 'win32' ? 'where' : 'which', [cmd], { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n}\n\nconst firstLine = (s: string): string => s.split('\\n')[0].slice(0, 140);\n\n/** Capture ~1 s from the mic and confirm real bytes come out. */\nfunction checkCapture(cfg: SatelliteConfig, backend: AudioBackend): CheckResult {\n try {\n let out: Buffer;\n if (backend === 'ffmpeg') {\n out = execFileSync(\n 'ffmpeg',\n [\n '-hide_banner',\n '-loglevel',\n 'error',\n ...ffmpegInput(cfg.micDevice),\n '-t',\n '1',\n '-ac',\n '1',\n '-ar',\n '16000',\n '-f',\n 's16le',\n '-',\n ],\n { timeout: 8000, maxBuffer: 1 << 22 },\n );\n } else {\n const args = ['-q', '-f', 'S16_LE', '-r', '16000', '-c', '1', '-d', '1', '-t', 'raw'];\n if (cfg.micDevice && cfg.micDevice !== 'default') {\n args.push('-D', cfg.micDevice);\n }\n out = execFileSync('arecord', args, { timeout: 8000, maxBuffer: 1 << 22 });\n }\n return out.length > 1000\n ? ok('audio:in', `captured ${out.length} bytes from '${cfg.micDevice}'`)\n : fail('audio:in', `captured only ${out.length} bytes — wrong device or no signal`);\n } catch (e) {\n return fail('audio:in', `capture failed (device busy/wrong?): ${firstLine((e as Error).message)}`);\n }\n}\n\n/** Play 0.2 s of silence to confirm the output device opens. */\nfunction checkPlayback(cfg: SatelliteConfig, backend: AudioBackend): CheckResult {\n const silence = Buffer.alloc(Math.round((16000 * 2) / 5)); // 0.2 s @ 16 kHz mono 16-bit\n try {\n if (backend === 'ffmpeg') {\n execFileSync(\n 'ffplay',\n [\n '-hide_banner',\n '-loglevel',\n 'error',\n '-nodisp',\n '-autoexit',\n '-f',\n 's16le',\n '-ar',\n '16000',\n '-ch_layout',\n 'mono',\n '-i',\n '-',\n ],\n { input: silence, timeout: 8000 },\n );\n } else {\n const args = ['-q', '-f', 'S16_LE', '-r', '16000', '-c', '1'];\n if (cfg.speakerDevice && cfg.speakerDevice !== 'default') {\n args.push('-D', cfg.speakerDevice);\n }\n execFileSync('aplay', args, { input: silence, timeout: 8000 });\n }\n return ok('audio:out', `output device '${cfg.speakerDevice}' opened`);\n } catch (e) {\n return fail('audio:out', `playback failed (device busy/wrong?): ${firstLine((e as Error).message)}`);\n }\n}\n\n/** Run all checks. `forService` adds the systemd/root prerequisites. */\nexport function runChecks(cfg: SatelliteConfig, backend: AudioBackend, forService: boolean): CheckResult[] {\n const results: CheckResult[] = [];\n\n const major = Number(process.versions.node.split('.')[0]);\n results.push(\n major >= 18 ? ok('node', `v${process.versions.node}`) : fail('node', `v${process.versions.node} (need ≥ 18)`),\n );\n\n if (forService) {\n results.push(\n process.platform === 'linux'\n ? ok('platform', 'linux')\n : fail('platform', `${process.platform} — systemd install is Linux-only`),\n );\n results.push(which('systemctl') ? ok('systemctl', 'found') : fail('systemctl', 'not found'));\n const root = typeof process.getuid === 'function' && process.getuid() === 0;\n results.push(root ? ok('root', 'running as root') : warn('root', 'not root — run install with sudo'));\n }\n\n for (const t of backend === 'ffmpeg' ? ['ffmpeg', 'ffplay'] : ['arecord', 'aplay']) {\n results.push(\n which(t)\n ? ok(`tool:${t}`, 'found')\n : fail(`tool:${t}`, `not found — install ${backend === 'ffmpeg' ? 'ffmpeg' : 'alsa-utils'}`),\n );\n }\n\n results.push(checkCapture(cfg, backend));\n results.push(checkPlayback(cfg, backend));\n\n results.push(\n cfg.host\n ? ok('config:server', `host ${cfg.host}:${cfg.port}`)\n : fail('config:server', 'set \"host\" so the satellite can reach the adapter'),\n );\n\n try {\n fs.mkdirSync(cfg.modelsDir, { recursive: true });\n fs.accessSync(cfg.modelsDir, fs.constants.W_OK);\n results.push(ok('models', `'${cfg.modelsDir}' writable`));\n } catch {\n results.push(warn('models', `'${cfg.modelsDir}' not writable — model download may fail`));\n }\n\n return results;\n}\n\n/** Print the results; returns false if any check failed. */\nexport function printChecks(results: CheckResult[], log: Logger): boolean {\n const label: Record<CheckStatus, string> = { ok: 'OK ', warn: 'WARN', fail: 'FAIL' };\n for (const c of results) {\n const line = `[${label[c.status]}] ${c.name}${c.detail ? ` — ${c.detail}` : ''}`;\n if (c.status === 'fail') {\n log.error(line);\n } else if (c.status === 'warn') {\n log.warn(line);\n } else {\n log.info(line);\n }\n }\n return !results.some(c => c.status === 'fail');\n}\n"]}
|
package/build/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/**\n * CLI entry point:\n * assistant-satellite [config.json] run the satellite\n * assistant-satellite install [config.json] install + start a systemd service (Linux, needs sudo)\n * assistant-satellite uninstall stop + remove the systemd service (needs sudo)\n */\nimport * as fs from 'node:fs';\nimport { Satellite, loadConfig, DEFAULT_CONFIG, type SatelliteConfig } from './index';\nimport { installService, uninstallService } from './service';\nimport { runChecks, printChecks } from './checks';\nimport { resolveBackend } from './audio';\n\n// Debug is off until we know the config's logLevel; the DEBUG env var forces it on regardless.\nlet debugEnabled = !!process.env.DEBUG;\nconst log = {\n info: (m: string): void => console.log(`[INFO] ${m}`),\n warn: (m: string): void => console.warn(`[WARN] ${m}`),\n error: (m: string): void => console.error(`[ERROR] ${m}`),\n debug: (m: string): void => {\n if (debugEnabled) {\n console.log(`[DEBUG] ${m}`);\n }\n },\n};\n\nconst [command, ...rest] = process.argv.slice(2);\nconst configArg = rest.find(a => !a.startsWith('--')) || 'config.json';\n\n// `check` — run preflight checks (rights, audio in/out, tools, config) and exit.\nif (command === 'check') {\n if (!fs.existsSync(configArg)) {\n log.error(`config not found: ${configArg}`);\n process.exit(1);\n }\n try {\n const c = loadConfig(JSON.parse(fs.readFileSync(configArg, 'utf8')) as Partial<SatelliteConfig>);\n const passed = printChecks(runChecks(c, resolveBackend(c.audioBackend), true), log);\n process.exit(passed ? 0 : 1);\n } catch (e) {\n log.error((e as Error).message);\n process.exit(1);\n }\n}\n\n// Service management subcommands (Linux/systemd). `install` runs the checks first.\nif (command === 'install' || command === '--install') {\n try {\n installService(configArg, log, rest.includes('--force'));\n process.exit(0);\n } catch (e) {\n log.error((e as Error).message);\n process.exit(1);\n }\n}\nif (command === 'uninstall' || command === '--uninstall') {\n try {\n uninstallService(log);\n process.exit(0);\n } catch (e) {\n log.error((e as Error).message);\n process.exit(1);\n }\n}\n\nconst configPath = command || 'config.json';\n\nif (!fs.existsSync(configPath)) {\n fs.writeFileSync(configPath, `${JSON.stringify(DEFAULT_CONFIG, null, 4)}\\n`);\n log.info(`No config found — wrote defaults to ${configPath}.`);\n log.info('Edit it (at least set \"host\" and \"device\"), then run again.');\n process.exit(0);\n}\n\nlet cfg: SatelliteConfig;\ntry {\n cfg = loadConfig(JSON.parse(fs.readFileSync(configPath, 'utf8')) as Partial<SatelliteConfig>);\n} catch (e) {\n log.error(`Cannot read ${configPath}: ${(e as Error).message}`);\n process.exit(1);\n}\n\nif (cfg.logLevel === 'debug') {\n debugEnabled = true;\n}\n\nconst satellite = new Satellite(cfg, { log, onStatus: s => log.debug(`status: ${s}`) });\n\nsatellite.start().catch(e => {\n log.error((e as Error).message);\n process.exit(1);\n});\n\nlet stopping = false;\nasync function shutdown(): Promise<void> {\n if (stopping) {\n return;\n }\n stopping = true;\n log.info('Shutting down …');\n await satellite.stop();\n process.exit(0);\n}\nprocess.on('SIGINT', () => void shutdown());\nprocess.on('SIGTERM', () => void shutdown());\n"]}
|
package/build/config.d.ts
CHANGED
|
@@ -30,6 +30,8 @@ export interface SatelliteConfig {
|
|
|
30
30
|
maxRecordMs: number;
|
|
31
31
|
/** Number of pre-wake 80 ms chunks prepended to the recording (so no speech is lost). */
|
|
32
32
|
preBufferChunks: number;
|
|
33
|
+
/** Barge-in: if the wake word fires while the reply is playing, stop playback and listen again. */
|
|
34
|
+
bargeIn: boolean;
|
|
33
35
|
/** Heartbeat / registration. */
|
|
34
36
|
registrationTimeoutMs: number;
|
|
35
37
|
heartbeatIntervalMs: number;
|
package/build/config.js
CHANGED
package/build/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;AAsEA,gCAEC;AA1BY,QAAA,cAAc,GAAoB;IAC3C,QAAQ,EAAE,MAAM;IAChB,MAAM,EAAE,WAAW;IACnB,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,IAAI;IACV,UAAU,EAAE,IAAI;IAChB,YAAY,EAAE,MAAM;IACpB,SAAS,EAAE,SAAS;IACpB,aAAa,EAAE,SAAS;IACxB,aAAa,EAAE,EAAE;IACjB,iBAAiB,EAAE,GAAG;IACtB,SAAS,EAAE,QAAQ;IACnB,gBAAgB,EAAE,GAAG;IACrB,SAAS,EAAE,GAAG;IACd,WAAW,EAAE,GAAG;IAChB,WAAW,EAAE,IAAI;IACjB,eAAe,EAAE,CAAC;IAClB,OAAO,EAAE,IAAI;IACb,qBAAqB,EAAE,IAAI;IAC3B,mBAAmB,EAAE,KAAK;CAC7B,CAAC;AAEF,mEAAmE;AACnE,SAAgB,UAAU,CAAC,OAAiC;IACxD,OAAO,EAAE,GAAG,sBAAc,EAAE,GAAG,OAAO,EAAE,CAAC;AAC7C,CAAC","sourcesContent":["/** Satellite configuration (loaded from config.json / CLI). */\nexport interface SatelliteConfig {\n /** Log verbosity. 'debug' also prints the wake-word/mic diagnostics. */\n logLevel: 'info' | 'debug';\n\n /** Device identity reported to the adapter. */\n device: string;\n room: string;\n\n /** Adapter (voice-server) address. */\n host: string;\n port: number;\n /** UDP port the satellite listens on for TTS/control from the adapter. */\n listenPort: number;\n\n /** Audio backend: 'auto' (alsa on Linux, ffmpeg elsewhere), or force 'alsa' / 'ffmpeg'. */\n audioBackend: 'auto' | 'alsa' | 'ffmpeg';\n /**\n * Capture/playback devices. ALSA: e.g. \"plughw:2,0\". ffmpeg mic: dshow device name (Windows),\n * avfoundation index (macOS). \"default\" or \"\" = system default.\n */\n micDevice: string;\n speakerDevice: string;\n\n /** Wake word. modelPath: path to a wakeword .onnx ('' = built-in \"hey_jarvis\"). */\n wakewordModel: string;\n wakewordThreshold: number;\n /** Directory the melspectrogram/embedding/wakeword models are downloaded to/read from. */\n modelsDir: string;\n\n /** Recording (VAD) — silence detection to end an utterance. */\n silenceThreshold: number;\n silenceMs: number;\n minRecordMs: number;\n maxRecordMs: number;\n /** Number of pre-wake 80 ms chunks prepended to the recording (so no speech is lost). */\n preBufferChunks: number;\n\n /** Barge-in: if the wake word fires while the reply is playing, stop playback and listen again. */\n bargeIn: boolean;\n\n /** Heartbeat / registration. */\n registrationTimeoutMs: number;\n heartbeatIntervalMs: number;\n}\n\nexport const DEFAULT_CONFIG: SatelliteConfig = {\n logLevel: 'info',\n device: 'satellite',\n room: '',\n host: '',\n port: 7775,\n listenPort: 7776,\n audioBackend: 'auto',\n micDevice: 'default',\n speakerDevice: 'default',\n wakewordModel: '',\n wakewordThreshold: 0.5,\n modelsDir: 'models',\n silenceThreshold: 300,\n silenceMs: 800,\n minRecordMs: 800,\n maxRecordMs: 8000,\n preBufferChunks: 5,\n bargeIn: true,\n registrationTimeoutMs: 5000,\n heartbeatIntervalMs: 10000,\n};\n\n/** Merge a partial config (from config.json) onto the defaults. */\nexport function loadConfig(partial: Partial<SatelliteConfig>): SatelliteConfig {\n return { ...DEFAULT_CONFIG, ...partial };\n}\n"]}
|
package/build/index.d.ts
CHANGED
|
@@ -18,4 +18,5 @@ export interface SatelliteHost {
|
|
|
18
18
|
}
|
|
19
19
|
export { Satellite } from './satellite';
|
|
20
20
|
export { loadConfig, DEFAULT_CONFIG, type SatelliteConfig } from './config';
|
|
21
|
+
export { probeWakeWord, type WakeProbeResult } from './probe';
|
|
21
22
|
export type { SatelliteState } from './protocol';
|
package/build/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_CONFIG = exports.loadConfig = exports.Satellite = void 0;
|
|
3
|
+
exports.probeWakeWord = exports.DEFAULT_CONFIG = exports.loadConfig = exports.Satellite = void 0;
|
|
4
4
|
var satellite_1 = require("./satellite");
|
|
5
5
|
Object.defineProperty(exports, "Satellite", { enumerable: true, get: function () { return satellite_1.Satellite; } });
|
|
6
6
|
var config_1 = require("./config");
|
|
7
7
|
Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return config_1.loadConfig; } });
|
|
8
8
|
Object.defineProperty(exports, "DEFAULT_CONFIG", { enumerable: true, get: function () { return config_1.DEFAULT_CONFIG; } });
|
|
9
|
+
var probe_1 = require("./probe");
|
|
10
|
+
Object.defineProperty(exports, "probeWakeWord", { enumerable: true, get: function () { return probe_1.probeWakeWord; } });
|
|
9
11
|
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAqBA,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAClB,mCAA4E;AAAnE,oGAAA,UAAU,OAAA;AAAE,wGAAA,cAAc,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAqBA,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAClB,mCAA4E;AAAnE,oGAAA,UAAU,OAAA;AAAE,wGAAA,cAAc,OAAA;AACnC,iCAA8D;AAArD,sGAAA,aAAa,OAAA","sourcesContent":["/**\n * \\@iobroker/assistant-satellite — public API.\n *\n * The Satellite is dependency-injected with a host (logger + status callback) so the same code runs\n * standalone (CLI) and, later, inside an ioBroker adapter wrapper — with no ioBroker dependency here.\n */\nimport type { SatelliteState } from './protocol';\n\nexport interface Logger {\n info(m: string): void;\n warn(m: string): void;\n error(m: string): void;\n debug(m: string): void;\n}\n\nexport interface SatelliteHost {\n log: Logger;\n /** Called on every state transition (idle/listening/processing/speaking). */\n onStatus?(state: SatelliteState): void;\n}\n\nexport { Satellite } from './satellite';\nexport { loadConfig, DEFAULT_CONFIG, type SatelliteConfig } from './config';\nexport { probeWakeWord, type WakeProbeResult } from './probe';\nexport type { SatelliteState } from './protocol';\n"]}
|
package/build/models.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA,oCAsBC;AAvED;;;;;;;GAOG;AACH,4CAA8B;AAC9B,gDAAkC;AAGlC,kFAAkF;AAClF,MAAM,OAAO,GAAG,mEAAmE,CAAC;AACvE,QAAA,WAAW,GAAG,GAAG,OAAO,sBAAsB,CAAC;AAC/C,QAAA,aAAa,GAAG,GAAG,OAAO,uBAAuB,CAAC;AAC/D,kFAAkF;AACrE,QAAA,SAAS,GAA2B;IAC7C,UAAU,EAAE,GAAG,OAAO,uBAAuB;IAC7C,KAAK,EAAE,GAAG,OAAO,kBAAkB;IACnC,WAAW,EAAE,GAAG,OAAO,wBAAwB;IAC/C,WAAW,EAAE,GAAG,OAAO,wBAAwB;CAClD,CAAC;AAEF,KAAK,UAAU,QAAQ,CAAC,GAAW,EAAE,IAAY,EAAE,GAAW;IAC1D,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO;IACX,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,qBAAqB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,YAAY,GAAG,iBAAiB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;IACjD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC5B,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AACrF,CAAC;AAQD;;;GAGG;AACI,KAAK,UAAU,YAAY,CAAC,SAAiB,EAAE,aAAqB,EAAE,GAAW;IACpF,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC;IAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAC;IAC/D,MAAM,QAAQ,CAAC,mBAAW,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IAC1C,MAAM,QAAQ,CAAC,qBAAa,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;IAE9C,IAAI,QAAgB,CAAC;IACrB,MAAM,IAAI,GAAG,aAAa,IAAI,YAAY,CAAC;IAC3C,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,QAAQ,GAAG,IAAI,CAAC,CAAC,oBAAoB;IACzC,CAAC;SAAM,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACrD,MAAM,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;IACxC,CAAC;SAAM,CAAC;QACJ,MAAM,GAAG,GAAG,iBAAS,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,GAAG,EAAE,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,aAAa,MAAM,CAAC,IAAI,CAAC,iBAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjG,CAAC;QACD,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC;QAChD,MAAM,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;AAC5C,CAAC","sourcesContent":["/**\n * OpenWakeWord ONNX model management. The pipeline needs three models:\n * - melspectrogram.onnx (shared) — audio → mel spectrogram\n * - embedding_model.onnx (shared) — mel → Google speech embeddings\n * - <wakeword>.onnx — embeddings → wake-word score\n *\n * Models are downloaded on first run to `modelsDir` from the openWakeWord releases.\n */\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { Logger } from './index';\n\n/** openWakeWord release assets (feature models + a few pretrained wake words). */\nconst RELEASE = 'https://github.com/dscripka/openWakeWord/releases/download/v0.5.1';\nexport const MELSPEC_URL = `${RELEASE}/melspectrogram.onnx`;\nexport const EMBEDDING_URL = `${RELEASE}/embedding_model.onnx`;\n/** Built-in wake words available as ONNX (name → asset). Default \"hey_jarvis\". */\nexport const WAKEWORDS: Record<string, string> = {\n hey_jarvis: `${RELEASE}/hey_jarvis_v0.1.onnx`,\n alexa: `${RELEASE}/alexa_v0.1.onnx`,\n hey_mycroft: `${RELEASE}/hey_mycroft_v0.1.onnx`,\n hey_rhasspy: `${RELEASE}/hey_rhasspy_v0.1.onnx`,\n};\n\nasync function download(url: string, dest: string, log: Logger): Promise<void> {\n if (fs.existsSync(dest)) {\n return;\n }\n log.info(`Downloading model ${path.basename(dest)} …`);\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`download ${url} failed: HTTP ${res.status}`);\n }\n const buf = Buffer.from(await res.arrayBuffer());\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n fs.writeFileSync(dest, buf);\n log.info(`Saved ${path.basename(dest)} (${(buf.length / 1024).toFixed(0)} KB).`);\n}\n\nexport interface ModelPaths {\n melspec: string;\n embedding: string;\n wakeword: string;\n}\n\n/**\n * Ensure the three model files exist locally, downloading the missing ones.\n * `wakewordModel` may be a name from WAKEWORDS, a URL, or a local .onnx path.\n */\nexport async function ensureModels(modelsDir: string, wakewordModel: string, log: Logger): Promise<ModelPaths> {\n const melspec = path.join(modelsDir, 'melspectrogram.onnx');\n const embedding = path.join(modelsDir, 'embedding_model.onnx');\n await download(MELSPEC_URL, melspec, log);\n await download(EMBEDDING_URL, embedding, log);\n\n let wakeword: string;\n const name = wakewordModel || 'hey_jarvis';\n if (fs.existsSync(name)) {\n wakeword = name; // a local file path\n } else if (/^https?:\\/\\//.test(name)) {\n wakeword = path.join(modelsDir, path.basename(name));\n await download(name, wakeword, log);\n } else {\n const url = WAKEWORDS[name];\n if (!url) {\n throw new Error(`unknown wake word \"${name}\" (known: ${Object.keys(WAKEWORDS).join(', ')})`);\n }\n wakeword = path.join(modelsDir, `${name}.onnx`);\n await download(url, wakeword, log);\n }\n return { melspec, embedding, wakeword };\n}\n"]}
|
package/build/probe.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SatelliteConfig } from './config';
|
|
2
|
+
import type { Logger } from './index';
|
|
3
|
+
export interface WakeProbeResult {
|
|
4
|
+
detected: boolean;
|
|
5
|
+
peakScore: number;
|
|
6
|
+
peakRms: number;
|
|
7
|
+
frames: number;
|
|
8
|
+
threshold: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Listen for `seconds` and run wake-word detection. `onProgress` is called with the running peak
|
|
12
|
+
* score/RMS so the caller can show a live indicator. Resolves when the window ends.
|
|
13
|
+
*/
|
|
14
|
+
export declare function probeWakeWord(cfg: SatelliteConfig, log: Logger, seconds: number,
|
|
15
|
+
/** Called per frame with the CURRENT score/RMS and whether the wake word has fired so far. */
|
|
16
|
+
onProgress?: (score: number, rms: number, detected: boolean) => void): Promise<WakeProbeResult>;
|
package/build/probe.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.probeWakeWord = probeWakeWord;
|
|
4
|
+
/**
|
|
5
|
+
* Wake-word probe: open the microphone for a few seconds and report whether the wake word was
|
|
6
|
+
* detected and the peak score/level seen. Used by the adapter's "Test wake word" button so users can
|
|
7
|
+
* verify detection from the GUI — works even before the satellite is fully configured (no server needed).
|
|
8
|
+
*/
|
|
9
|
+
const models_1 = require("./models");
|
|
10
|
+
const wakeword_1 = require("./wakeword");
|
|
11
|
+
const audio_1 = require("./audio");
|
|
12
|
+
const vad_1 = require("./vad");
|
|
13
|
+
const FRAME_BYTES = 1280 * 2; // 80 ms @ 16 kHz mono 16-bit
|
|
14
|
+
/**
|
|
15
|
+
* Listen for `seconds` and run wake-word detection. `onProgress` is called with the running peak
|
|
16
|
+
* score/RMS so the caller can show a live indicator. Resolves when the window ends.
|
|
17
|
+
*/
|
|
18
|
+
async function probeWakeWord(cfg, log, seconds,
|
|
19
|
+
/** Called per frame with the CURRENT score/RMS and whether the wake word has fired so far. */
|
|
20
|
+
onProgress) {
|
|
21
|
+
const models = await (0, models_1.ensureModels)(cfg.modelsDir, cfg.wakewordModel, log);
|
|
22
|
+
const wakeword = new wakeword_1.WakeWord(models, cfg.wakewordThreshold, log);
|
|
23
|
+
await wakeword.load();
|
|
24
|
+
const mic = new audio_1.Mic((0, audio_1.resolveBackend)(cfg.audioBackend), cfg.micDevice, log);
|
|
25
|
+
let remainder = Buffer.alloc(0);
|
|
26
|
+
let pumping = false;
|
|
27
|
+
let peakScore = 0;
|
|
28
|
+
let peakRms = 0;
|
|
29
|
+
let frames = 0;
|
|
30
|
+
let detected = false;
|
|
31
|
+
const pump = async () => {
|
|
32
|
+
if (pumping) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
pumping = true;
|
|
36
|
+
try {
|
|
37
|
+
while (remainder.length >= FRAME_BYTES) {
|
|
38
|
+
const frame = Buffer.from(remainder.subarray(0, FRAME_BYTES));
|
|
39
|
+
remainder = remainder.subarray(FRAME_BYTES);
|
|
40
|
+
frames++;
|
|
41
|
+
const level = (0, vad_1.rms)(frame);
|
|
42
|
+
if (level > peakRms) {
|
|
43
|
+
peakRms = level;
|
|
44
|
+
}
|
|
45
|
+
const score = await wakeword.process(frame);
|
|
46
|
+
const current = score ?? 0;
|
|
47
|
+
if (current > peakScore) {
|
|
48
|
+
peakScore = current;
|
|
49
|
+
}
|
|
50
|
+
if (wakeword.triggered(score)) {
|
|
51
|
+
detected = true;
|
|
52
|
+
}
|
|
53
|
+
onProgress?.(current, level, detected); // current frame values for a live meter
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
pumping = false;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
mic.start(d => {
|
|
61
|
+
remainder = Buffer.concat([remainder, d]);
|
|
62
|
+
void pump();
|
|
63
|
+
});
|
|
64
|
+
await new Promise(res => setTimeout(res, Math.max(1, seconds) * 1000));
|
|
65
|
+
mic.stop();
|
|
66
|
+
await new Promise(res => setTimeout(res, 200)); // let the last frames drain
|
|
67
|
+
return { detected, peakScore, peakRms, frames, threshold: cfg.wakewordThreshold };
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe.js","sourceRoot":"","sources":["../src/probe.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Wake-word probe: open the microphone for a few seconds and report whether the wake word was\n * detected and the peak score/level seen. Used by the adapter's \"Test wake word\" button so users can\n * verify detection from the GUI — works even before the satellite is fully configured (no server needed).\n */\nimport { ensureModels } from './models';\nimport { WakeWord } from './wakeword';\nimport { Mic, resolveBackend } from './audio';\nimport { rms } from './vad';\nimport type { SatelliteConfig } from './config';\nimport type { Logger } from './index';\n\nconst FRAME_BYTES = 1280 * 2; // 80 ms @ 16 kHz mono 16-bit\n\nexport interface WakeProbeResult {\n detected: boolean;\n peakScore: number;\n peakRms: number;\n frames: number;\n threshold: number;\n}\n\n/**\n * Listen for `seconds` and run wake-word detection. `onProgress` is called with the running peak\n * score/RMS so the caller can show a live indicator. Resolves when the window ends.\n */\nexport async function probeWakeWord(\n cfg: SatelliteConfig,\n log: Logger,\n seconds: number,\n /** Called per frame with the CURRENT score/RMS and whether the wake word has fired so far. */\n onProgress?: (score: number, rms: number, detected: boolean) => void,\n): Promise<WakeProbeResult> {\n const models = await ensureModels(cfg.modelsDir, cfg.wakewordModel, log);\n const wakeword = new WakeWord(models, cfg.wakewordThreshold, log);\n await wakeword.load();\n const mic = new Mic(resolveBackend(cfg.audioBackend), cfg.micDevice, log);\n\n let remainder = Buffer.alloc(0);\n let pumping = false;\n let peakScore = 0;\n let peakRms = 0;\n let frames = 0;\n let detected = false;\n\n const pump = async (): Promise<void> => {\n if (pumping) {\n return;\n }\n pumping = true;\n try {\n while (remainder.length >= FRAME_BYTES) {\n const frame = Buffer.from(remainder.subarray(0, FRAME_BYTES));\n remainder = remainder.subarray(FRAME_BYTES);\n frames++;\n const level = rms(frame);\n if (level > peakRms) {\n peakRms = level;\n }\n const score = await wakeword.process(frame);\n const current = score ?? 0;\n if (current > peakScore) {\n peakScore = current;\n }\n if (wakeword.triggered(score)) {\n detected = true;\n }\n onProgress?.(current, level, detected); // current frame values for a live meter\n }\n } finally {\n pumping = false;\n }\n };\n\n mic.start(d => {\n remainder = Buffer.concat([remainder, d]);\n void pump();\n });\n await new Promise<void>(res => setTimeout(res, Math.max(1, seconds) * 1000));\n mic.stop();\n await new Promise<void>(res => setTimeout(res, 200)); // let the last frames drain\n\n return { detected, peakScore, peakRms, frames, threshold: cfg.wakewordThreshold };\n}\n"]}
|
package/build/protocol.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AA0BH,sCAEC;AAGD,kCAEC;AAGD,oCAEC;AApCY,QAAA,YAAY,GAAG,IAAI,CAAC;AACpB,QAAA,UAAU,GAAG,IAAI,CAAC;AAClB,QAAA,QAAQ,GAAG,IAAI,CAAC;AAE7B,4FAA4F;AAC/E,QAAA,iBAAiB,GAAG,KAAK,CAAC;AAkBvC,gEAAgE;AAChE,SAAgB,aAAa,CAAC,GAAgB;IAC1C,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,oBAAY,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AAClG,CAAC;AAED,uDAAuD;AACvD,SAAgB,WAAW,CAAC,GAAW;IACnC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,kBAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,mGAAmG;AACnG,SAAgB,YAAY,CAAC,IAAY;IACrC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;AACxD,CAAC"}
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AA0BH,sCAEC;AAGD,kCAEC;AAGD,oCAEC;AApCY,QAAA,YAAY,GAAG,IAAI,CAAC;AACpB,QAAA,UAAU,GAAG,IAAI,CAAC;AAClB,QAAA,QAAQ,GAAG,IAAI,CAAC;AAE7B,4FAA4F;AAC/E,QAAA,iBAAiB,GAAG,KAAK,CAAC;AAkBvC,gEAAgE;AAChE,SAAgB,aAAa,CAAC,GAAgB;IAC1C,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,oBAAY,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AAClG,CAAC;AAED,uDAAuD;AACvD,SAAgB,WAAW,CAAC,GAAW;IACnC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,kBAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,mGAAmG;AACnG,SAAgB,YAAY,CAAC,IAAY;IACrC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;AACxD,CAAC","sourcesContent":["/**\n * Voice-satellite UDP wire protocol — must match the adapter's\n * `ioBroker.assistant/src/lib/voice/protocol.ts` (and the Hannah satellite).\n *\n * One UDP socket, first byte is the packet type:\n * 0x01 CONTROL — UTF-8 JSON (both directions)\n * 0x02 AUDIO — raw 16 kHz mono 16-bit signed LE PCM (satellite → server)\n * 0x03 TTS — raw mono 16-bit signed LE PCM (server → satellite)\n *\n * ⚠️ KEEP IN SYNC with the adapter copy.\n */\n\nexport const TYPE_CONTROL = 0x01;\nexport const TYPE_AUDIO = 0x02;\nexport const TYPE_TTS = 0x03;\n\n/** Audio streamed to the server is always 16 kHz, mono, 16-bit signed little-endian PCM. */\nexport const AUDIO_SAMPLE_RATE = 16000;\n\n/** Control messages the satellite sends to the server. */\nexport type SatToServer =\n | { type: 'register'; device: string; room?: string; listen_port?: number }\n | { type: 'heartbeat'; device: string }\n | { type: 'audio_end'; device: string };\n\nexport type SatelliteState = 'idle' | 'listening' | 'processing' | 'speaking';\n\n/** Control messages the satellite receives from the server. */\nexport type ServerToSat =\n | { type: 'registered'; ok: boolean }\n | { type: 'heartbeat_ack' }\n | { type: 'reregister' }\n | { type: 'tts_end'; sample_rate: number }\n | { type: 'status'; state: SatelliteState };\n\n/** Prefix a control JSON message with the CONTROL type byte. */\nexport function encodeControl(msg: SatToServer): Buffer {\n return Buffer.concat([Buffer.from([TYPE_CONTROL]), Buffer.from(JSON.stringify(msg), 'utf8')]);\n}\n\n/** Prefix a raw PCM chunk with the AUDIO type byte. */\nexport function encodeAudio(pcm: Buffer): Buffer {\n return Buffer.concat([Buffer.from([TYPE_AUDIO]), pcm]);\n}\n\n/** Split an incoming datagram into its type byte and payload (a view onto the original buffer). */\nexport function decodePacket(data: Buffer): { type: number; payload: Buffer } {\n return { type: data[0], payload: data.subarray(1) };\n}\n"]}
|
package/build/satellite.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export declare class Satellite {
|
|
|
11
11
|
private mic;
|
|
12
12
|
private readonly backend;
|
|
13
13
|
private plingPcm;
|
|
14
|
+
/** Current reply playback process (for barge-in); null when nothing is playing. */
|
|
15
|
+
private playbackProc;
|
|
14
16
|
private heartbeatTimer;
|
|
15
17
|
private micRemainder;
|
|
16
18
|
private pumping;
|
package/build/satellite.js
CHANGED
|
@@ -62,6 +62,8 @@ class Satellite {
|
|
|
62
62
|
mic = null;
|
|
63
63
|
backend;
|
|
64
64
|
plingPcm = Buffer.alloc(0);
|
|
65
|
+
/** Current reply playback process (for barge-in); null when nothing is playing. */
|
|
66
|
+
playbackProc = null;
|
|
65
67
|
heartbeatTimer = null;
|
|
66
68
|
// mic frame assembly
|
|
67
69
|
micRemainder = Buffer.alloc(0);
|
|
@@ -276,6 +278,12 @@ class Satellite {
|
|
|
276
278
|
}
|
|
277
279
|
if (this.wakeword.triggered(score)) {
|
|
278
280
|
this.log.info(`Wake word detected (score ${score.toFixed(3)}).`);
|
|
281
|
+
// Barge-in: if a reply is currently playing, stop it so the user can interrupt.
|
|
282
|
+
if (this.cfg.bargeIn && this.playbackProc) {
|
|
283
|
+
this.log.info('Barge-in: stopping playback.');
|
|
284
|
+
this.playbackProc.kill();
|
|
285
|
+
this.playbackProc = null;
|
|
286
|
+
}
|
|
279
287
|
this.wakeword.reset();
|
|
280
288
|
await this.startRecording();
|
|
281
289
|
}
|
|
@@ -283,7 +291,7 @@ class Satellite {
|
|
|
283
291
|
async startRecording() {
|
|
284
292
|
this.setStatus('listening');
|
|
285
293
|
this.ttsDiscard = true; // drop any late TTS from a previous turn
|
|
286
|
-
await (0, audio_1.playPcm)(this.plingPcm, protocol_1.AUDIO_SAMPLE_RATE, this.backend, this.cfg.speakerDevice, this.log);
|
|
294
|
+
await (0, audio_1.playPcm)(this.plingPcm, protocol_1.AUDIO_SAMPLE_RATE, this.backend, this.cfg.speakerDevice, this.log).done;
|
|
287
295
|
this.ttsDiscard = false;
|
|
288
296
|
this.ttsChunks = [];
|
|
289
297
|
// Drop everything captured up to now (the beep echo + any inference backlog) so recording runs
|
|
@@ -363,7 +371,14 @@ class Satellite {
|
|
|
363
371
|
return;
|
|
364
372
|
}
|
|
365
373
|
this.log.info(`Playing reply (${(pcm.length / 2 / sampleRate).toFixed(1)} s @ ${sampleRate} Hz).`);
|
|
366
|
-
|
|
374
|
+
const { proc, done } = (0, audio_1.playPcm)(pcm, sampleRate, this.backend, this.cfg.speakerDevice, this.log);
|
|
375
|
+
this.playbackProc = proc; // tracked so the wake word can barge-in
|
|
376
|
+
try {
|
|
377
|
+
await done;
|
|
378
|
+
}
|
|
379
|
+
finally {
|
|
380
|
+
this.playbackProc = null;
|
|
381
|
+
}
|
|
367
382
|
}
|
|
368
383
|
// ── senders / status ───────────────────────────────────────────────────
|
|
369
384
|
sendAudio(pcm) {
|
package/build/satellite.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"satellite.js","sourceRoot":"","sources":["../src/satellite.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"satellite.js","sourceRoot":"","sources":["../src/satellite.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Satellite orchestration: resolve the adapter address → register → listen for the wake word →\n * stream the utterance → play the spoken reply. Protocol-compatible with the Hannah satellite.\n */\nimport * as dgram from 'node:dgram';\nimport {\n AUDIO_SAMPLE_RATE,\n TYPE_AUDIO,\n TYPE_CONTROL,\n TYPE_TTS,\n decodePacket,\n encodeAudio,\n encodeControl,\n type SatToServer,\n type SatelliteState,\n} from './protocol';\nimport type { ChildProcess } from 'node:child_process';\nimport { Mic, playPcm, pling, resolveBackend, type AudioBackend } from './audio';\nimport { SilenceDetector, rms } from './vad';\nimport { WakeWord } from './wakeword';\nimport { ensureModels } from './models';\nimport type { SatelliteConfig } from './config';\nimport type { SatelliteHost, Logger } from './index';\n\n/** 1280 samples (80 ms) of 16 kHz mono 16-bit PCM per processing frame. */\nconst FRAME_BYTES = 1280 * 2;\nconst FRAME_MS = 80;\n/** Missed heartbeat ACKs before the satellite assumes the adapter is gone and re-registers. */\nconst MAX_HEARTBEAT_MISSES = 3;\nconst RECONNECT_MAX_BACKOFF_MS = 30_000;\n\nconst sleep = (ms: number): Promise<void> => new Promise(res => setTimeout(res, ms));\n\nexport class Satellite {\n private readonly log: Logger;\n private socket: dgram.Socket | null = null;\n private serverHost = '';\n private serverPort = 0;\n\n private wakeword!: WakeWord;\n private mic: Mic | null = null;\n private readonly backend: AudioBackend;\n private plingPcm: Buffer = Buffer.alloc(0);\n /** Current reply playback process (for barge-in); null when nothing is playing. */\n private playbackProc: ChildProcess | null = null;\n private heartbeatTimer: NodeJS.Timeout | null = null;\n\n // mic frame assembly\n private micRemainder: Buffer = Buffer.alloc(0);\n private pumping = false;\n private micBytesLogged = false;\n\n // wake-word diagnostics (periodic summary)\n private wakeFrames = 0;\n private wakeMaxScore = 0;\n private wakeMaxRms = 0;\n\n // recording state\n private recording = false;\n private silence: SilenceDetector | null = null;\n private preBuffer: Buffer[] = [];\n private recFrames = 0;\n private recPeakRms = 0;\n\n // tts receiver\n private ttsChunks: Buffer[] = [];\n private ttsDiscard = false;\n\n private registerResolve: (() => void) | null = null;\n private running = false;\n private heartbeatMisses = 0;\n private awaitingHeartbeatAck = false;\n private reconnecting = false;\n\n constructor(\n private readonly cfg: SatelliteConfig,\n private readonly host: SatelliteHost,\n ) {\n this.log = host.log;\n this.backend = resolveBackend(cfg.audioBackend);\n }\n\n async start(): Promise<void> {\n this.running = true;\n const addr = this.resolveAddress();\n this.serverHost = addr.host;\n this.serverPort = addr.port;\n this.log.info(`Adapter address: ${this.serverHost}:${this.serverPort}`);\n\n await this.openSocket();\n\n const models = await ensureModels(this.cfg.modelsDir, this.cfg.wakewordModel, this.log);\n this.wakeword = new WakeWord(models, this.cfg.wakewordThreshold, this.log);\n await this.wakeword.load();\n this.plingPcm = pling();\n\n // Retry until the adapter answers, so the satellite survives the adapter being down at boot.\n await this.registerWithRetry();\n this.heartbeatTimer = setInterval(() => this.heartbeatTick(), this.cfg.heartbeatIntervalMs);\n\n this.mic = new Mic(this.backend, this.cfg.micDevice, this.log);\n this.mic.start(d => this.onMicData(d));\n this.setStatus('idle');\n this.log.info(`Satellite '${this.cfg.device}' ready. Listening for the wake word …`);\n }\n\n async stop(): Promise<void> {\n this.running = false;\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n this.mic?.stop();\n this.mic = null;\n const socket = this.socket;\n this.socket = null;\n if (socket) {\n await new Promise<void>(res => socket.close(() => res()));\n }\n }\n\n // ── setup ──────────────────────────────────────────────────────────────\n\n private resolveAddress(): { host: string; port: number } {\n if (!this.cfg.host) {\n throw new Error('No adapter address: set \"host\" (and \"port\") in the config.');\n }\n return { host: this.cfg.host, port: this.cfg.port };\n }\n\n private openSocket(): Promise<void> {\n return new Promise((resolve, reject) => {\n const socket = dgram.createSocket('udp4');\n this.socket = socket;\n socket.on('message', d => this.onMessage(d));\n socket.on('error', e => this.log.error(`UDP error: ${e.message}`));\n socket.once('error', reject);\n socket.bind(this.cfg.listenPort, () => {\n this.log.info(`Listening for TTS on UDP ${this.cfg.listenPort}.`);\n resolve();\n });\n });\n }\n\n /** Register, retrying with exponential backoff until the adapter acknowledges (or we stop). */\n private async registerWithRetry(): Promise<void> {\n let backoff = 1000;\n while (this.running) {\n try {\n await this.register();\n this.awaitingHeartbeatAck = false;\n this.heartbeatMisses = 0;\n return;\n } catch (e) {\n this.log.warn(`${(e as Error).message} — retrying in ${Math.round(backoff / 1000)} s …`);\n await sleep(backoff);\n backoff = Math.min(backoff * 2, RECONNECT_MAX_BACKOFF_MS);\n }\n }\n }\n\n /** Triggered when heartbeats stop being acknowledged: re-register (adapter probably restarted). */\n private async reconnect(): Promise<void> {\n if (this.reconnecting || !this.running) {\n return;\n }\n this.reconnecting = true;\n this.heartbeatMisses = 0;\n this.awaitingHeartbeatAck = false;\n this.log.warn('Adapter unreachable — re-registering …');\n try {\n await this.registerWithRetry();\n this.log.info('Re-registered with the adapter.');\n } finally {\n this.reconnecting = false;\n }\n }\n\n private heartbeatTick(): void {\n if (this.reconnecting) {\n return;\n }\n if (this.awaitingHeartbeatAck) {\n this.heartbeatMisses++;\n this.log.warn(`Heartbeat not acknowledged (${this.heartbeatMisses}/${MAX_HEARTBEAT_MISSES}).`);\n if (this.heartbeatMisses >= MAX_HEARTBEAT_MISSES) {\n void this.reconnect();\n return;\n }\n }\n this.awaitingHeartbeatAck = true;\n this.sendControl({ type: 'heartbeat', device: this.cfg.device });\n }\n\n private register(): Promise<void> {\n return new Promise((resolve, reject) => {\n this.registerResolve = resolve;\n this.sendControl({\n type: 'register',\n device: this.cfg.device,\n room: this.cfg.room,\n listen_port: this.cfg.listenPort,\n });\n this.log.info(`Registration sent to ${this.serverHost}:${this.serverPort} (device '${this.cfg.device}').`);\n setTimeout(() => {\n if (this.registerResolve) {\n this.registerResolve = null;\n reject(new Error(`registration timed out after ${this.cfg.registrationTimeoutMs} ms`));\n }\n }, this.cfg.registrationTimeoutMs);\n });\n }\n\n // ── microphone → wake word → recording ─────────────────────────────────\n\n private onMicData(chunk: Buffer): void {\n if (!this.micBytesLogged) {\n this.micBytesLogged = true;\n this.log.info(`Microphone is producing audio (first chunk ${chunk.length} bytes).`);\n }\n this.micRemainder = Buffer.concat([this.micRemainder, chunk]);\n if (!this.pumping) {\n void this.pump();\n }\n }\n\n private async pump(): Promise<void> {\n this.pumping = true;\n try {\n while (this.micRemainder.length >= FRAME_BYTES) {\n const frame = Buffer.from(this.micRemainder.subarray(0, FRAME_BYTES));\n this.micRemainder = this.micRemainder.subarray(FRAME_BYTES);\n await this.handleFrame(frame);\n }\n } catch (e) {\n this.log.error(`frame processing error: ${(e as Error).message}`);\n } finally {\n this.pumping = false;\n }\n }\n\n private async handleFrame(frame: Buffer): Promise<void> {\n if (this.recording) {\n this.sendAudio(frame);\n this.recFrames++;\n const level = rms(frame);\n if (level > this.recPeakRms) {\n this.recPeakRms = level;\n }\n if (this.silence!.push(frame)) {\n this.endRecording();\n }\n return;\n }\n\n // Wake-word listening: keep a rolling pre-buffer so speech during inference is not lost.\n this.preBuffer.push(frame);\n if (this.preBuffer.length > this.cfg.preBufferChunks) {\n this.preBuffer.shift();\n }\n const score = await this.wakeword.process(frame);\n\n // Periodic diagnostics: every ~2 s report how many frames ran and the peak score, so you can\n // watch the score rise while saying the wake word and tune `wakewordThreshold`.\n this.wakeFrames++;\n if (score !== null && score > this.wakeMaxScore) {\n this.wakeMaxScore = score;\n }\n const level = rms(frame);\n if (level > this.wakeMaxRms) {\n this.wakeMaxRms = level;\n }\n if (this.wakeFrames >= 25) {\n this.log.debug(\n `wake: ${this.wakeFrames} frames, peak mic RMS ${this.wakeMaxRms.toFixed(0)}, ` +\n `peak score ${this.wakeMaxScore.toFixed(3)} (threshold ${this.cfg.wakewordThreshold})`,\n );\n this.wakeFrames = 0;\n this.wakeMaxScore = 0;\n this.wakeMaxRms = 0;\n }\n\n if (this.wakeword.triggered(score)) {\n this.log.info(`Wake word detected (score ${(score as number).toFixed(3)}).`);\n // Barge-in: if a reply is currently playing, stop it so the user can interrupt.\n if (this.cfg.bargeIn && this.playbackProc) {\n this.log.info('Barge-in: stopping playback.');\n this.playbackProc.kill();\n this.playbackProc = null;\n }\n this.wakeword.reset();\n await this.startRecording();\n }\n }\n\n private async startRecording(): Promise<void> {\n this.setStatus('listening');\n this.ttsDiscard = true; // drop any late TTS from a previous turn\n await playPcm(this.plingPcm, AUDIO_SAMPLE_RATE, this.backend, this.cfg.speakerDevice, this.log).done;\n this.ttsDiscard = false;\n this.ttsChunks = [];\n\n // Drop everything captured up to now (the beep echo + any inference backlog) so recording runs\n // in real time — otherwise the silence detector races through buffered quiet frames and ends the\n // utterance before you finish speaking (→ the adapter's STT gets silence → \"(empty)\").\n this.micRemainder = Buffer.alloc(0);\n this.preBuffer = [];\n this.recFrames = 0;\n this.recPeakRms = 0;\n this.silence = new SilenceDetector(\n this.cfg.silenceThreshold,\n Math.round(this.cfg.silenceMs / FRAME_MS),\n Math.round(this.cfg.minRecordMs / FRAME_MS),\n Math.round(this.cfg.maxRecordMs / FRAME_MS),\n );\n this.recording = true;\n this.log.info('Beep done — listening for your command …');\n }\n\n private endRecording(): void {\n this.recording = false;\n this.silence = null;\n this.sendControl({ type: 'audio_end', device: this.cfg.device });\n const maxFrames = Math.round(this.cfg.maxRecordMs / FRAME_MS);\n const reason = this.recFrames >= maxFrames ? 'max length' : 'silence';\n this.log.info(\n `Recording finished: ${this.recFrames} frames (${this.recFrames * FRAME_MS} ms), ` +\n `peak RMS ${this.recPeakRms.toFixed(0)}, ended on ${reason} — audio_end sent.`,\n );\n }\n\n // ── incoming UDP (control + TTS) ───────────────────────────────────────\n\n private onMessage(data: Buffer): void {\n if (!data.length) {\n return;\n }\n const { type, payload } = decodePacket(data);\n if (type === TYPE_AUDIO) {\n return; // satellites do not receive audio\n }\n if (type === TYPE_TTS) {\n if (!this.ttsDiscard) {\n this.ttsChunks.push(Buffer.from(payload));\n }\n return;\n }\n if (type !== TYPE_CONTROL) {\n return;\n }\n let msg: { type?: string; ok?: boolean; state?: SatelliteState; sample_rate?: number };\n try {\n msg = JSON.parse(payload.toString('utf8'));\n } catch {\n return;\n }\n switch (msg.type) {\n case 'registered':\n if (msg.ok && this.registerResolve) {\n this.log.info('Registration confirmed (ACK).');\n this.registerResolve();\n this.registerResolve = null;\n }\n break;\n case 'reregister':\n this.register().catch(e => this.log.warn(`re-register failed: ${(e as Error).message}`));\n break;\n case 'status':\n if (msg.state) {\n this.setStatus(msg.state);\n }\n break;\n case 'tts_end':\n void this.playTts(msg.sample_rate || AUDIO_SAMPLE_RATE);\n break;\n case 'heartbeat_ack':\n this.awaitingHeartbeatAck = false;\n this.heartbeatMisses = 0;\n break;\n }\n }\n\n private async playTts(sampleRate: number): Promise<void> {\n const pcm = Buffer.concat(this.ttsChunks);\n this.ttsChunks = [];\n if (!pcm.length) {\n return;\n }\n this.log.info(`Playing reply (${(pcm.length / 2 / sampleRate).toFixed(1)} s @ ${sampleRate} Hz).`);\n const { proc, done } = playPcm(pcm, sampleRate, this.backend, this.cfg.speakerDevice, this.log);\n this.playbackProc = proc; // tracked so the wake word can barge-in\n try {\n await done;\n } finally {\n this.playbackProc = null;\n }\n }\n\n // ── senders / status ───────────────────────────────────────────────────\n\n private sendAudio(pcm: Buffer): void {\n this.socket?.send(encodeAudio(pcm), this.serverPort, this.serverHost);\n }\n\n private sendControl(msg: SatToServer): void {\n this.socket?.send(encodeControl(msg), this.serverPort, this.serverHost);\n }\n\n private setStatus(state: SatelliteState): void {\n this.host.onStatus?.(state);\n }\n}\n"]}
|
package/build/service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Self-install as a systemd service: `assistant-satellite install [config.json]`.\n * Generates /etc/systemd/system/assistant-satellite.service pointing at this node binary + cli.js +\n * the given config, then daemon-reload + enable --now. Needs root (re-run with sudo).\n */\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { execFileSync } from 'node:child_process';\nimport { loadConfig, type SatelliteConfig } from './config';\nimport { resolveBackend } from './audio';\nimport { runChecks, printChecks } from './checks';\nimport type { Logger } from './index';\n\nconst SERVICE_NAME = 'assistant-satellite';\nconst SERVICE_PATH = `/etc/systemd/system/${SERVICE_NAME}.service`;\n\nfunction run(cmd: string, args: string[], log: Logger): void {\n log.debug(`$ ${cmd} ${args.join(' ')}`);\n execFileSync(cmd, args, { stdio: 'inherit' });\n}\n\nfunction requireLinux(): void {\n if (process.platform !== 'linux') {\n throw new Error('Service install/uninstall is only supported on Linux (systemd).');\n }\n}\n\nexport function installService(configPath: string, log: Logger, force = false): void {\n requireLinux();\n const absConfig = path.resolve(configPath);\n if (!fs.existsSync(absConfig)) {\n throw new Error(`config not found: ${absConfig} — run once to create/edit it, then install.`);\n }\n\n // Preflight: verify rights, audio in/out, tools, config before writing the unit.\n let cfg: SatelliteConfig;\n try {\n cfg = loadConfig(JSON.parse(fs.readFileSync(absConfig, 'utf8')) as Partial<SatelliteConfig>);\n } catch (e) {\n throw new Error(`cannot read ${absConfig}: ${(e as Error).message}`);\n }\n log.info('Preflight checks:');\n const passed = printChecks(runChecks(cfg, resolveBackend(cfg.audioBackend), true), log);\n if (!passed && !force) {\n throw new Error('preflight checks failed — fix the above, or re-run with --force to install anyway.');\n }\n\n const nodeBin = process.execPath;\n const cliPath = path.join(__dirname, 'cli.js');\n const workingDir = path.dirname(absConfig);\n // Run the service as the invoking user (sudo → the real user), not root, so audio access is normal.\n const user = process.env.SUDO_USER || os.userInfo().username;\n\n const unit =\n `[Unit]\\n` +\n `Description=ioBroker assistant satellite\\n` +\n `After=network-online.target sound.target\\n` +\n `Wants=network-online.target\\n\\n` +\n `[Service]\\n` +\n `Type=simple\\n` +\n `WorkingDirectory=${workingDir}\\n` +\n `ExecStart=${nodeBin} ${cliPath} ${absConfig}\\n` +\n `Restart=always\\n` +\n `RestartSec=5\\n` +\n `User=${user}\\n` +\n `SupplementaryGroups=audio\\n\\n` +\n `[Install]\\n` +\n `WantedBy=multi-user.target\\n`;\n\n try {\n fs.writeFileSync(SERVICE_PATH, unit);\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code === 'EACCES') {\n throw new Error(`cannot write ${SERVICE_PATH} — re-run with sudo.`);\n }\n throw e;\n }\n log.info(`Wrote ${SERVICE_PATH} (runs as User=${user}).`);\n run('systemctl', ['daemon-reload'], log);\n run('systemctl', ['enable', '--now', SERVICE_NAME], log);\n log.info(`Service '${SERVICE_NAME}' installed and started.`);\n log.info(` logs: journalctl -u ${SERVICE_NAME} -f`);\n log.info(` restart: sudo systemctl restart ${SERVICE_NAME}`);\n log.info(` remove: sudo ${nodeBin} ${cliPath} uninstall`);\n}\n\nexport function uninstallService(log: Logger): void {\n requireLinux();\n try {\n run('systemctl', ['disable', '--now', SERVICE_NAME], log);\n } catch {\n /* not enabled/running — ignore */\n }\n try {\n fs.unlinkSync(SERVICE_PATH);\n log.info(`Removed ${SERVICE_PATH}.`);\n } catch (e) {\n const code = (e as NodeJS.ErrnoException).code;\n if (code === 'EACCES') {\n throw new Error(`cannot remove ${SERVICE_PATH} — re-run with sudo.`);\n }\n if (code !== 'ENOENT') {\n throw e;\n }\n }\n run('systemctl', ['daemon-reload'], log);\n log.info(`Service '${SERVICE_NAME}' removed.`);\n}\n"]}
|
package/build/vad.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vad.js","sourceRoot":"","sources":["../src/vad.ts"],"names":[],"mappings":";AAAA,qFAAqF;;;AAGrF,kBAWC;AAZD,6DAA6D;AAC7D,SAAgB,GAAG,CAAC,GAAW;IAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACrC,IAAI,CAAC,CAAC,EAAE,CAAC;QACL,OAAO,CAAC,CAAC;IACb,CAAC;IACD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACjC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAa,eAAe;IAKH;IACA;IACA;IACA;IAPb,YAAY,GAAG,CAAC,CAAC;IACjB,cAAc,GAAG,CAAC,CAAC;IAE3B,YACqB,SAAiB,EACjB,aAAqB,EACrB,SAAiB,EACjB,SAAiB;QAHjB,cAAS,GAAT,SAAS,CAAQ;QACjB,kBAAa,GAAb,aAAa,CAAQ;QACrB,cAAS,GAAT,SAAS,CAAQ;QACjB,cAAS,GAAT,SAAS,CAAQ;IACnC,CAAC;IAEJ,+FAA+F;IAC/F,IAAI,CAAC,GAAW;QACZ,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACxC,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAC5B,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,aAAa,CAAC;QACnD,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,OAAO,KAAK,CAAC;IACjB,CAAC;CACJ;AA3BD,0CA2BC"}
|
|
1
|
+
{"version":3,"file":"vad.js","sourceRoot":"","sources":["../src/vad.ts"],"names":[],"mappings":";AAAA,qFAAqF;;;AAGrF,kBAWC;AAZD,6DAA6D;AAC7D,SAAgB,GAAG,CAAC,GAAW;IAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACrC,IAAI,CAAC,CAAC,EAAE,CAAC;QACL,OAAO,CAAC,CAAC;IACb,CAAC;IACD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACjC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAa,eAAe;IAKH;IACA;IACA;IACA;IAPb,YAAY,GAAG,CAAC,CAAC;IACjB,cAAc,GAAG,CAAC,CAAC;IAE3B,YACqB,SAAiB,EACjB,aAAqB,EACrB,SAAiB,EACjB,SAAiB;QAHjB,cAAS,GAAT,SAAS,CAAQ;QACjB,kBAAa,GAAb,aAAa,CAAQ;QACrB,cAAS,GAAT,SAAS,CAAQ;QACjB,cAAS,GAAT,SAAS,CAAQ;IACnC,CAAC;IAEJ,+FAA+F;IAC/F,IAAI,CAAC,GAAW;QACZ,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACxC,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAC5B,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,aAAa,CAAC;QACnD,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,OAAO,KAAK,CAAC;IACjB,CAAC;CACJ;AA3BD,0CA2BC","sourcesContent":["/** Simple RMS-energy voice-activity detection (ported from the Hannah satellite). */\n\n/** RMS energy (0..32768) of a 16-bit signed LE PCM frame. */\nexport function rms(pcm: Buffer): number {\n const n = Math.floor(pcm.length / 2);\n if (!n) {\n return 0;\n }\n let sum = 0;\n for (let i = 0; i < n; i++) {\n const s = pcm.readInt16LE(i * 2);\n sum += s * s;\n }\n return Math.sqrt(sum / n);\n}\n\n/**\n * Tracks trailing silence across frames to decide when an utterance ends.\n * Silence detection only kicks in after `minFrames` (so a short pause at the very start\n * does not cut speech off).\n */\nexport class SilenceDetector {\n private silentFrames = 0;\n private recordedFrames = 0;\n\n constructor(\n private readonly threshold: number,\n private readonly silenceFrames: number,\n private readonly minFrames: number,\n private readonly maxFrames: number,\n ) {}\n\n /** Feed one frame; returns true when recording should stop (silence reached or max length). */\n push(pcm: Buffer): boolean {\n this.recordedFrames++;\n if (this.recordedFrames >= this.maxFrames) {\n return true;\n }\n if (this.recordedFrames < this.minFrames) {\n return false;\n }\n if (rms(pcm) < this.threshold) {\n this.silentFrames++;\n return this.silentFrames >= this.silenceFrames;\n }\n this.silentFrames = 0;\n return false;\n }\n}\n"]}
|
package/build/wakeword.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wakeword.js","sourceRoot":"","sources":["../src/wakeword.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"wakeword.js","sourceRoot":"","sources":["../src/wakeword.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * OpenWakeWord inference in Node via onnxruntime-node.\n *\n * Pipeline (streaming): 16 kHz mono int16 audio → melspectrogram model → sliding embedding model\n * (Google speech embeddings) → wake-word classifier → score in [0,1].\n *\n * Shapes follow the openWakeWord models:\n * melspec: in [1, samples] (int16 values as float32) → out [1,1,F,32]; then mel = mel/10 + 2\n * embedding: in [1,76,32,1] → out [1,1,1,96]; window of 76 mel frames, hop 8\n * wakeword: in [1,16,96] → out [1,1] ; last 16 embeddings\n *\n * ⚠️ The exact frame counts (mel frames per chunk, warm-up) can vary by model version — validate the\n * detection threshold on the target device and adjust `wakewordThreshold`.\n */\nimport * as ort from 'onnxruntime-node';\nimport type { ModelPaths } from './models';\nimport type { Logger } from './index';\n\nconst MEL_BINS = 32;\nconst EMB_WINDOW = 76; // mel frames per embedding\nconst EMB_HOP = 8; // mel frames advanced per embedding\nconst WW_FRAMES = 16; // embeddings per wake-word inference\nconst EMB_DIM = 96;\n\nexport class WakeWord {\n private melspec!: ort.InferenceSession;\n private embedding!: ort.InferenceSession;\n private classifier!: ort.InferenceSession;\n\n private melBuffer: number[][] = []; // rows of 32 mel bins\n private melProcessed = 0; // mel frames already turned into embeddings\n private embBuffer: number[][] = []; // rows of 96 embedding dims\n private melShapeLogged = false;\n private embShapeLogged = false;\n\n constructor(\n private readonly models: ModelPaths,\n private readonly threshold: number,\n private readonly log: Logger,\n ) {}\n\n async load(): Promise<void> {\n this.melspec = await ort.InferenceSession.create(this.models.melspec);\n this.embedding = await ort.InferenceSession.create(this.models.embedding);\n this.classifier = await ort.InferenceSession.create(this.models.wakeword);\n this.log.info('Wake-word models loaded.');\n this.log.info(\n ` melspec IO: in=[${this.melspec.inputNames.join(', ')}] out=[${this.melspec.outputNames.join(', ')}]`,\n );\n this.log.info(\n ` embedding IO: in=[${this.embedding.inputNames.join(', ')}] out=[${this.embedding.outputNames.join(', ')}]`,\n );\n this.log.info(\n ` classifier IO: in=[${this.classifier.inputNames.join(', ')}] out=[${this.classifier.outputNames.join(', ')}]`,\n );\n }\n\n /** Reset the streaming buffers (call after a detection so it re-arms cleanly). */\n reset(): void {\n this.melBuffer = [];\n this.melProcessed = 0;\n this.embBuffer = [];\n }\n\n /**\n * Feed one audio chunk (16-bit signed LE PCM, ideally ~1280 samples = 80 ms) and return the\n * current wake-word score, or null if not enough context yet.\n */\n async process(pcm: Buffer): Promise<number | null> {\n await this.appendMel(pcm);\n await this.appendEmbeddings();\n if (this.embBuffer.length < WW_FRAMES) {\n return null;\n }\n return this.classify();\n }\n\n /** True when the given score crosses the configured detection threshold. */\n triggered(score: number | null): boolean {\n return score !== null && score >= this.threshold;\n }\n\n private async appendMel(pcm: Buffer): Promise<void> {\n const n = Math.floor(pcm.length / 2);\n const audio = new Float32Array(n);\n for (let i = 0; i < n; i++) {\n audio[i] = pcm.readInt16LE(i * 2); // int16 value as float (openWakeWord convention)\n }\n const inName = this.melspec.inputNames[0];\n const outName = this.melspec.outputNames[0];\n const out = await this.melspec.run({ [inName]: new ort.Tensor('float32', audio, [1, n]) });\n const t = out[outName];\n const data = t.data as Float32Array;\n if (!this.melShapeLogged) {\n this.log.info(`melspec output dims for ${n} samples: [${t.dims.join(',')}] (expected [1,1,F,32])`);\n this.melShapeLogged = true;\n }\n // dims [1,1,F,32]\n const frames = Number(t.dims[2]);\n for (let f = 0; f < frames; f++) {\n const row = new Array<number>(MEL_BINS);\n for (let b = 0; b < MEL_BINS; b++) {\n row[b] = data[f * MEL_BINS + b] / 10 + 2; // openWakeWord mel transform\n }\n this.melBuffer.push(row);\n }\n }\n\n private async appendEmbeddings(): Promise<void> {\n const inName = this.embedding.inputNames[0];\n const outName = this.embedding.outputNames[0];\n while (this.melProcessed + EMB_WINDOW <= this.melBuffer.length) {\n const flat = new Float32Array(EMB_WINDOW * MEL_BINS);\n for (let f = 0; f < EMB_WINDOW; f++) {\n const row = this.melBuffer[this.melProcessed + f];\n for (let b = 0; b < MEL_BINS; b++) {\n flat[f * MEL_BINS + b] = row[b];\n }\n }\n const out = await this.embedding.run({\n [inName]: new ort.Tensor('float32', flat, [1, EMB_WINDOW, MEL_BINS, 1]),\n });\n if (!this.embShapeLogged) {\n this.log.info(`embedding output dims: [${out[outName].dims.join(',')}] (expected [1,1,1,96])`);\n this.embShapeLogged = true;\n }\n const emb = out[outName].data as Float32Array; // [1,1,1,96]\n this.embBuffer.push(Array.from(emb.slice(0, EMB_DIM)));\n this.melProcessed += EMB_HOP;\n }\n // Trim consumed mel frames to keep memory bounded.\n if (this.melProcessed > EMB_WINDOW) {\n const drop = this.melProcessed - EMB_WINDOW;\n this.melBuffer.splice(0, drop);\n this.melProcessed -= drop;\n }\n if (this.embBuffer.length > WW_FRAMES * 4) {\n this.embBuffer.splice(0, this.embBuffer.length - WW_FRAMES * 4);\n }\n }\n\n private async classify(): Promise<number> {\n const inName = this.classifier.inputNames[0];\n const outName = this.classifier.outputNames[0];\n const window = this.embBuffer.slice(-WW_FRAMES);\n const flat = new Float32Array(WW_FRAMES * EMB_DIM);\n for (let f = 0; f < WW_FRAMES; f++) {\n for (let d = 0; d < EMB_DIM; d++) {\n flat[f * EMB_DIM + d] = window[f][d];\n }\n }\n const out = await this.classifier.run({\n [inName]: new ort.Tensor('float32', flat, [1, WW_FRAMES, EMB_DIM]),\n });\n return (out[outName].data as Float32Array)[0];\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iobroker/assistant-satellite",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Standalone voice satellite for the ioBroker.assistant adapter (wake word + mic streaming + TTS playback over the Hannah UDP protocol). Runs on a bare Pi via npx, no ioBroker required.",
|
|
5
5
|
"author": "ioBroker",
|
|
6
6
|
"publishConfig": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"LICENSE"
|
|
32
32
|
],
|
|
33
33
|
"scripts": {
|
|
34
|
-
"build": "tsc -p tsconfig.json",
|
|
34
|
+
"build": "tsc -p tsconfig.build.json",
|
|
35
35
|
"start": "node build/cli.js",
|
|
36
36
|
"test": "echo \"no tests yet\" && exit 0",
|
|
37
37
|
"test:package": "echo \"not required\" && exit 0",
|
|
@@ -54,5 +54,13 @@
|
|
|
54
54
|
"@iobroker/eslint-config": "^2.3.4",
|
|
55
55
|
"@types/node": "^20.19.43",
|
|
56
56
|
"typescript": "~6.0.3"
|
|
57
|
-
}
|
|
57
|
+
},
|
|
58
|
+
"repository": {
|
|
59
|
+
"type": "git",
|
|
60
|
+
"url": "git+https://github.com/ioBroker/assistant-satellite.git"
|
|
61
|
+
},
|
|
62
|
+
"bugs": {
|
|
63
|
+
"url": "https://github.com/ioBroker/assistant-satellite/issues"
|
|
64
|
+
},
|
|
65
|
+
"homepage": "https://github.com/ioBroker/assistant-satellite"
|
|
58
66
|
}
|