8 cfg = config.services.wyoming.satellite;
24 finalPackage = cfg.package.overridePythonAttrs (oldAttrs: {
25 propagatedBuildInputs = oldAttrs.propagatedBuildInputs
26 # for audio enhancements like auto-gain, noise suppression
27 ++ cfg.package.optional-dependencies.webrtc
28 # vad is currently optional, because it is broken on aarch64-linux
29 ++ optionals cfg.vad.enable cfg.package.optional-dependencies.silerovad;
34 meta.buildDocsInSandbox = false;
36 options.services.wyoming.satellite = with types; {
37 enable = mkEnableOption "Wyoming Satellite";
39 package = mkPackageOption pkgs "wyoming-satellite" { };
45 User to run wyoming-satellite under.
53 Group to run wyoming-satellite under.
59 default = "tcp://0.0.0.0:10700";
61 URI where wyoming-satellite will bind its socket.
67 default = config.networking.hostName;
68 defaultText = literalExpression ''
69 config.networking.hostName
72 Name of the satellite.
81 Area to the satellite.
88 default = "arecord -r 16000 -c 1 -f S16_LE -t raw";
90 Program to run for audio input.
95 type = ints.between 0 31;
99 Automatic gain control in dbFS, with 31 being the loudest value. Set to 0 to disable.
103 noiseSuppression = mkOption {
104 type = ints.between 0 4;
108 Noise suppression level with 4 being the maximum suppression,
109 which may cause audio distortion. Set to 0 to disable.
117 default = "aplay -r 22050 -c 1 -f S16_LE -t raw";
119 Program to run for sound output.
129 Path to audio file in WAV format to play when wake word is detected.
137 Path to audio file in WAV format to play when voice command recording has ended.
147 Whether to enable voice activity detection.
149 Enabling will result in only streaming audio, when speech gets
155 extraArgs = mkOption {
159 Extra arguments to pass to the executable.
161 Check `wyoming-satellite --help` for possible options.
166 config = mkIf cfg.enable {
167 systemd.services."wyoming-satellite" = {
168 description = "Wyoming Satellite";
170 "network-online.target"
174 "network-online.target"
184 optionalParam = param: argument: optionals (!elem argument [ null 0 false ]) [
188 export XDG_RUNTIME_DIR=/run/user/$UID
190 (getExe finalPackage)
193 "--mic-command" cfg.microphone.command
195 ++ optionalParam "--mic-auto-gain" cfg.microphone.autoGain
196 ++ optionalParam "--mic-noise-suppression" cfg.microphone.noiseSuppression
197 ++ optionalParam "--area" cfg.area
198 ++ optionalParam "--snd-command" cfg.sound.command
199 ++ optionalParam "--awake-wav" cfg.sounds.awake
200 ++ optionalParam "--done-wav" cfg.sounds.done
201 ++ optional cfg.vad.enable "--vad"
207 # https://github.com/rhasspy/hassio-addons/blob/master/assist_microphone/rootfs/etc/s6-overlay/s6-rc.d/assist_microphone/run
208 CapabilityBoundingSet = "";
210 DevicePolicy = "closed";
211 LockPersonality = true;
212 MemoryDenyWriteExecute = false; # onnxruntime/capi/onnxruntime_pybind11_state.so: cannot enable executable stack as shared object requires: Operation not permitted
213 PrivateDevices = true;
215 ProtectHome = false; # Would deny access to local pulse/pipewire server
216 ProtectHostname = true;
217 ProtectKernelLogs = true;
218 ProtectKernelModules = true;
219 ProtectKernelTunables = true;
220 ProtectControlGroups = true;
221 ProtectProc = "invisible";
222 ProcSubset = "all"; # Error in cpuinfo: failed to parse processor information from /proc/cpuinfo
224 RestrictAddressFamilies = [
230 RestrictNamespaces = true;
231 RestrictRealtime = true;
232 SupplementaryGroups = [
235 SystemCallArchitectures = "native";