python312Packages.dissect-extfs: 3.11 -> 3.12
[NixPkgs.git] / nixos / modules / services / home-automation / wyoming / piper.nix
bloba26fe8e84f609c6e0b23cc63854a16ad6666575e
1 { config
2 , lib
3 , pkgs
4 , ...
5 }:
7 let
8   cfg = config.services.wyoming.piper;
10   inherit (lib)
11     escapeShellArgs
12     mkOption
13     mkEnableOption
14     mkPackageOption
15     types
16     ;
18   inherit (builtins)
19     toString
20     ;
25   meta.buildDocsInSandbox = false;
27   options.services.wyoming.piper = with types; {
28     package = mkPackageOption pkgs "wyoming-piper" { };
30     servers = mkOption {
31       default = {};
32       description = ''
33         Attribute set of piper instances to spawn.
34       '';
35       type = types.attrsOf (types.submodule (
36         { ... }: {
37           options = {
38             enable = mkEnableOption "Wyoming Piper server";
40             piper = mkPackageOption pkgs "piper-tts" { };
42             voice = mkOption {
43               type = str;
44               example = "en-us-ryan-medium";
45               description = ''
46                 Name of the voice model to use. See the following website for samples:
47                 https://rhasspy.github.io/piper-samples/
48               '';
49             };
51             uri = mkOption {
52               type = strMatching "^(tcp|unix)://.*$";
53               example = "tcp://0.0.0.0:10200";
54               description = ''
55                 URI to bind the wyoming server to.
56               '';
57             };
59             speaker = mkOption {
60               type = ints.unsigned;
61               default = 0;
62               description = ''
63                 ID of a specific speaker in a multi-speaker model.
64               '';
65               apply = toString;
66             };
68             noiseScale = mkOption {
69               type = float;
70               default = 0.667;
71               description = ''
72                 Generator noise value.
73               '';
74               apply = toString;
75             };
77             noiseWidth = mkOption {
78               type = float;
79               default = 0.333;
80               description = ''
81                 Phoneme width noise value.
82               '';
83               apply = toString;
84             };
86             lengthScale = mkOption {
87               type = float;
88               default = 1.0;
89               description = ''
90                 Phoneme length value.
91               '';
92               apply = toString;
93             };
95             extraArgs = mkOption {
96               type = listOf str;
97               default = [ ];
98               description = ''
99                 Extra arguments to pass to the server commandline.
100               '';
101               apply = escapeShellArgs;
102             };
103           };
104         }
105       ));
106     };
107   };
109   config = let
110     inherit (lib)
111       mapAttrs'
112       mkIf
113       nameValuePair
114     ;
115   in mkIf (cfg.servers != {}) {
116     systemd.services = mapAttrs' (server: options:
117       nameValuePair "wyoming-piper-${server}" {
118         inherit (options) enable;
119         description = "Wyoming Piper server instance ${server}";
120         wants = [
121           "network-online.target"
122         ];
123         after = [
124           "network-online.target"
125         ];
126         wantedBy = [
127           "multi-user.target"
128         ];
129         serviceConfig = {
130           DynamicUser = true;
131           User = "wyoming-piper";
132           StateDirectory = "wyoming/piper";
133           # https://github.com/home-assistant/addons/blob/master/piper/rootfs/etc/s6-overlay/s6-rc.d/piper/run
134           ExecStart = ''
135             ${cfg.package}/bin/wyoming-piper \
136               --data-dir $STATE_DIRECTORY \
137               --download-dir $STATE_DIRECTORY \
138               --uri ${options.uri} \
139               --piper ${options.piper}/bin/piper \
140               --voice ${options.voice} \
141               --speaker ${options.speaker} \
142               --length-scale ${options.lengthScale} \
143               --noise-scale ${options.noiseScale} \
144               --noise-w ${options.noiseWidth} ${options.extraArgs}
145           '';
146           CapabilityBoundingSet = "";
147           DeviceAllow = "";
148           DevicePolicy = "closed";
149           LockPersonality = true;
150           MemoryDenyWriteExecute = true;
151           PrivateDevices = true;
152           PrivateUsers = true;
153           ProtectHome = true;
154           ProtectHostname = true;
155           ProtectKernelLogs = true;
156           ProtectKernelModules = true;
157           ProtectKernelTunables = true;
158           ProtectControlGroups = true;
159           ProtectProc = "invisible";
160           ProcSubset = "pid";
161           RestrictAddressFamilies = [
162             "AF_INET"
163             "AF_INET6"
164             "AF_UNIX"
165           ];
166           RestrictNamespaces = true;
167           RestrictRealtime = true;
168           SystemCallArchitectures = "native";
169           SystemCallFilter = [
170             "@system-service"
171             "~@privileged"
172           ];
173           UMask = "0077";
174         };
175       }) cfg.servers;
176   };