parent
aedeec6600
commit
e0795c6f43
8 changed files with 278 additions and 37 deletions
|
@ -35,6 +35,7 @@ in {
|
||||||
clusterIP = config.services.pcsd.virtualIps.caddy-vip.ip;
|
clusterIP = config.services.pcsd.virtualIps.caddy-vip.ip;
|
||||||
nosIP = "10.0.0.121";
|
nosIP = "10.0.0.121";
|
||||||
serviviIP = "10.0.0.249";
|
serviviIP = "10.0.0.249";
|
||||||
|
homieIP = "100.64.0.10";
|
||||||
|
|
||||||
tlsConf = ''
|
tlsConf = ''
|
||||||
tls {
|
tls {
|
||||||
|
@ -53,6 +54,7 @@ in {
|
||||||
// (builtins.removeAttrs extraConf ["extraConfig"]);
|
// (builtins.removeAttrs extraConf ["extraConfig"]);
|
||||||
in {
|
in {
|
||||||
# Public
|
# Public
|
||||||
|
"Home-Assistant" = mkPublicReverseProxy "homie" "${homieIP}:8123" {};
|
||||||
"Vaultwarden" = mkPublicReverseProxy "vault" "${nosIP}:8781" {};
|
"Vaultwarden" = mkPublicReverseProxy "vault" "${nosIP}:8781" {};
|
||||||
"Hauk" = mkPublicReverseProxy "hauk" "${nosIP}:3003" {};
|
"Hauk" = mkPublicReverseProxy "hauk" "${nosIP}:3003" {};
|
||||||
"Headscale" = mkPublicReverseProxy "headscale" "${clusterIP}:8085" {};
|
"Headscale" = mkPublicReverseProxy "headscale" "${clusterIP}:8085" {};
|
||||||
|
|
|
@ -11,6 +11,8 @@ in {
|
||||||
imports = [
|
imports = [
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
|
|
||||||
|
./modules/home-assistant.nix
|
||||||
|
|
||||||
self.nixosModules.kmscon
|
self.nixosModules.kmscon
|
||||||
self.nixosModules.server
|
self.nixosModules.server
|
||||||
];
|
];
|
||||||
|
|
81
devices/homie/modules/home-assistant.nix
Normal file
81
devices/homie/modules/home-assistant.nix
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
{
|
||||||
|
self,
|
||||||
|
wakewords-src,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
imports = [self.nixosModules.wyoming-plus];
|
||||||
|
|
||||||
|
services = {
|
||||||
|
home-assistant = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
extraComponents = [
|
||||||
|
"esphome"
|
||||||
|
"holiday"
|
||||||
|
"met"
|
||||||
|
"spotify"
|
||||||
|
"upnp"
|
||||||
|
"wyoming"
|
||||||
|
"yamaha_musiccast"
|
||||||
|
];
|
||||||
|
|
||||||
|
config = {
|
||||||
|
http = {
|
||||||
|
server_host = "0.0.0.0";
|
||||||
|
trusted_proxies = ["100.64.0.8" "100.64.0.9"];
|
||||||
|
use_x_forwarded_for = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Wanted defaults
|
||||||
|
assist_pipeline = {};
|
||||||
|
config = {};
|
||||||
|
conversation = {};
|
||||||
|
dhcp = {};
|
||||||
|
history = {};
|
||||||
|
image_upload = {};
|
||||||
|
logbook = {};
|
||||||
|
mobile_app = {};
|
||||||
|
my = {};
|
||||||
|
sun = {};
|
||||||
|
automation = {};
|
||||||
|
zeroconf = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
esphome = {
|
||||||
|
enable = true;
|
||||||
|
address = "localhost";
|
||||||
|
port = 6052;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Needs manual setting in GUI
|
||||||
|
wyoming = {
|
||||||
|
piper.servers."en" = {
|
||||||
|
enable = true;
|
||||||
|
uri = "tcp://127.0.0.1:10200";
|
||||||
|
|
||||||
|
# see https://github.com/rhasspy/rhasspy3/blob/master/programs/tts/piper/script/download.py
|
||||||
|
voice = "en-us-ryan-low";
|
||||||
|
speaker = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
faster-whisper.servers."en" = {
|
||||||
|
enable = true;
|
||||||
|
uri = "tcp://127.0.0.1:10300";
|
||||||
|
|
||||||
|
# see https://github.com/rhasspy/rhasspy3/blob/master/programs/asr/faster-whisper/script/download.py
|
||||||
|
model = "small-int8";
|
||||||
|
language = "en";
|
||||||
|
device = "cpu";
|
||||||
|
};
|
||||||
|
|
||||||
|
openwakeword-docker = {
|
||||||
|
enable = true;
|
||||||
|
uri = "127.0.0.1:10400";
|
||||||
|
|
||||||
|
customModelsDirectories = ["${wakewords-src}/en/yo_homie"];
|
||||||
|
preloadModels = ["yo_homie"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
58
flake.lock
generated
58
flake.lock
generated
|
@ -360,24 +360,6 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-utils_2": {
|
|
||||||
"inputs": {
|
|
||||||
"systems": "systems"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1710146030,
|
|
||||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flakegen": {
|
"flakegen": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": [
|
"systems": [
|
||||||
|
@ -491,7 +473,9 @@
|
||||||
},
|
},
|
||||||
"headscale": {
|
"headscale": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils_2",
|
"flake-utils": [
|
||||||
|
"flake-utils"
|
||||||
|
],
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
]
|
]
|
||||||
|
@ -1585,11 +1569,12 @@
|
||||||
"sioyek-theme-src": "sioyek-theme-src",
|
"sioyek-theme-src": "sioyek-theme-src",
|
||||||
"sops-nix": "sops-nix",
|
"sops-nix": "sops-nix",
|
||||||
"subsync": "subsync",
|
"subsync": "subsync",
|
||||||
"systems": "systems_2",
|
"systems": "systems",
|
||||||
"trash-d-src": "trash-d-src",
|
"trash-d-src": "trash-d-src",
|
||||||
"ts-for-gir-src": "ts-for-gir-src",
|
"ts-for-gir-src": "ts-for-gir-src",
|
||||||
"vimplugin-easytables-src": "vimplugin-easytables-src",
|
"vimplugin-easytables-src": "vimplugin-easytables-src",
|
||||||
"vimplugin-ts-error-translator-src": "vimplugin-ts-error-translator-src"
|
"vimplugin-ts-error-translator-src": "vimplugin-ts-error-translator-src",
|
||||||
|
"wakewords-src": "wakewords-src"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scss-reset": {
|
"scss-reset": {
|
||||||
|
@ -1709,21 +1694,6 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"systems": {
|
"systems": {
|
||||||
"locked": {
|
|
||||||
"lastModified": 1681028828,
|
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems_2": {
|
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1689347949,
|
"lastModified": 1689347949,
|
||||||
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
|
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
|
||||||
|
@ -1891,6 +1861,22 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"wakewords-src": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1721909332,
|
||||||
|
"narHash": "sha256-DdxK5Km4d9hQ2V27FjQNNdORd1HqBEByIwuz5RogDT8=",
|
||||||
|
"owner": "fwartner",
|
||||||
|
"repo": "home-assistant-wakewords-collection",
|
||||||
|
"rev": "18ba1c5d1877cd08622955f59609a53f3a2ff920",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "fwartner",
|
||||||
|
"repo": "home-assistant-wakewords-collection",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"xdph": {
|
"xdph": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"hyprland-protocols": "hyprland-protocols",
|
"hyprland-protocols": "hyprland-protocols",
|
||||||
|
|
11
flake.nix
11
flake.nix
|
@ -102,7 +102,10 @@
|
||||||
type = "github";
|
type = "github";
|
||||||
};
|
};
|
||||||
headscale = {
|
headscale = {
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs = {
|
||||||
|
flake-utils.follows = "flake-utils";
|
||||||
|
nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
owner = "juanfont";
|
owner = "juanfont";
|
||||||
repo = "headscale";
|
repo = "headscale";
|
||||||
rev = "022fb24cd92035470496d50d86bf8c9ee74b1e7e";
|
rev = "022fb24cd92035470496d50d86bf8c9ee74b1e7e";
|
||||||
|
@ -363,6 +366,12 @@
|
||||||
repo = "ts-error-translator.nvim";
|
repo = "ts-error-translator.nvim";
|
||||||
type = "github";
|
type = "github";
|
||||||
};
|
};
|
||||||
|
wakewords-src = {
|
||||||
|
flake = false;
|
||||||
|
owner = "fwartner";
|
||||||
|
repo = "home-assistant-wakewords-collection";
|
||||||
|
type = "github";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
outputs = inputs: inputs.flakegen ./outputs.nix inputs;
|
outputs = inputs: inputs.flakegen ./outputs.nix inputs;
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,6 +170,13 @@ let
|
||||||
};
|
};
|
||||||
|
|
||||||
srcs = [
|
srcs = [
|
||||||
|
# Home-assistant
|
||||||
|
{
|
||||||
|
name = "wakewords-src";
|
||||||
|
owner = "fwartner";
|
||||||
|
repo = "home-assistant-wakewords-collection";
|
||||||
|
}
|
||||||
|
|
||||||
# Nvim plugins
|
# Nvim plugins
|
||||||
{
|
{
|
||||||
name = "vimplugin-easytables-src";
|
name = "vimplugin-easytables-src";
|
||||||
|
|
|
@ -7,4 +7,5 @@ self: {
|
||||||
nvidia = import ./nvidia;
|
nvidia = import ./nvidia;
|
||||||
plymouth = import ./plymouth;
|
plymouth = import ./plymouth;
|
||||||
server = import ./server;
|
server = import ./server;
|
||||||
|
wyoming-plus = import ./wyoming-plus self;
|
||||||
}
|
}
|
||||||
|
|
153
nixosModules/wyoming-plus/default.nix
Normal file
153
nixosModules/wyoming-plus/default.nix
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
self: {
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit
|
||||||
|
(lib)
|
||||||
|
attrNames
|
||||||
|
escapeShellArgs
|
||||||
|
flatten
|
||||||
|
filterAttrs
|
||||||
|
listToAttrs
|
||||||
|
map
|
||||||
|
mkEnableOption
|
||||||
|
mkForce
|
||||||
|
mkIf
|
||||||
|
mkOption
|
||||||
|
nameValuePair
|
||||||
|
optionals
|
||||||
|
splitString
|
||||||
|
types
|
||||||
|
;
|
||||||
|
|
||||||
|
flatMap = f: list: flatten (map f list);
|
||||||
|
|
||||||
|
cfg = config.services.wyoming.openwakeword-docker;
|
||||||
|
in {
|
||||||
|
imports = [self.nixosModules.docker];
|
||||||
|
|
||||||
|
options.services.wyoming.openwakeword-docker = {
|
||||||
|
enable = mkEnableOption "Wyoming openWakeWord server";
|
||||||
|
|
||||||
|
image = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.dockerTools.pullImage {
|
||||||
|
imageName = "docker.io/rhasspy/wyoming-openwakeword";
|
||||||
|
imageDigest = "sha256:88df83cfdaa5a0dd068f79662d06b81479ec7b59a4bea59751ff5d6f68bad24a";
|
||||||
|
sha256 = "1c2yhrhhj1wpd5bcc3zaz1gv8mw8dw5m76cjf42nhf2sgwp2hsjl";
|
||||||
|
finalImageName = "docker.io/rhasspy/wyoming-openwakeword";
|
||||||
|
finalImageTag = "latest";
|
||||||
|
};
|
||||||
|
description = ''
|
||||||
|
The image that docker will use.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
uri = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "0.0.0.0:10400";
|
||||||
|
example = "192.0.2.1:5000";
|
||||||
|
description = ''
|
||||||
|
URI to bind the wyoming server to.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
customModelsDirectories = mkOption {
|
||||||
|
type = types.listOf types.path;
|
||||||
|
default = [];
|
||||||
|
description = ''
|
||||||
|
Paths to directories with custom wake word models (*.tflite model files).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
preloadModels = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [
|
||||||
|
"ok_nabu"
|
||||||
|
];
|
||||||
|
example = [
|
||||||
|
# wyoming_openwakeword/models/*.tflite
|
||||||
|
"alexa"
|
||||||
|
"hey_jarvis"
|
||||||
|
"hey_mycroft"
|
||||||
|
"hey_rhasspy"
|
||||||
|
"ok_nabu"
|
||||||
|
];
|
||||||
|
description = ''
|
||||||
|
List of wake word models to preload after startup.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
threshold = mkOption {
|
||||||
|
type = types.float;
|
||||||
|
default = 0.5;
|
||||||
|
description = ''
|
||||||
|
Activation threshold (0-1), where higher means fewer activations.
|
||||||
|
|
||||||
|
See trigger level for the relationship between activations and
|
||||||
|
wake word detections.
|
||||||
|
'';
|
||||||
|
apply = toString;
|
||||||
|
};
|
||||||
|
|
||||||
|
triggerLevel = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 1;
|
||||||
|
description = ''
|
||||||
|
Number of activations before a detection is registered.
|
||||||
|
|
||||||
|
A higher trigger level means fewer detections.
|
||||||
|
'';
|
||||||
|
apply = toString;
|
||||||
|
};
|
||||||
|
|
||||||
|
extraArgs = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [];
|
||||||
|
description = ''
|
||||||
|
Extra arguments to pass to the server commandline.
|
||||||
|
'';
|
||||||
|
apply = escapeShellArgs;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
systemd.services = let
|
||||||
|
unitNames = attrNames (
|
||||||
|
filterAttrs (_: v: v.device == "cpu") config.services.wyoming.faster-whisper.servers
|
||||||
|
);
|
||||||
|
in
|
||||||
|
listToAttrs (map (x:
|
||||||
|
nameValuePair "wyoming-faster-whisper-${x}" {
|
||||||
|
serviceConfig.ProcSubset = mkForce "all";
|
||||||
|
})
|
||||||
|
unitNames);
|
||||||
|
|
||||||
|
khepri = mkIf cfg.enable {
|
||||||
|
compositions."openwakeword" = {
|
||||||
|
networks.default = {};
|
||||||
|
|
||||||
|
services."openwakeword" = {
|
||||||
|
image = cfg.image;
|
||||||
|
restart = "always";
|
||||||
|
networks = ["default"];
|
||||||
|
|
||||||
|
volumes = map (dir: "${toString dir}:${toString dir}") cfg.customModelsDirectories;
|
||||||
|
cmd =
|
||||||
|
(flatMap (model: ["--preload-model" model]) cfg.preloadModels)
|
||||||
|
++ (flatMap (dir: ["--custom-model-dir" (toString dir)]) cfg.customModelsDirectories)
|
||||||
|
++ ["--threshold" cfg.threshold]
|
||||||
|
++ ["--trigger-level" cfg.triggerLevel]
|
||||||
|
++ optionals (cfg.extraArgs != "") (splitString " " cfg.extraArgs);
|
||||||
|
|
||||||
|
ports = ["${cfg.uri}:10400"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# For accurate stack trace
|
||||||
|
_file = ./default.nix;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue