mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-26 19:16:47 +03:00
Merge pull request #261931 from mweinelt/homeassistant-satellite
homeassistant-satellite: init at 2.3.0
This commit is contained in:
commit
410ccec99c
7 changed files with 331 additions and 1 deletions
|
@ -80,6 +80,8 @@
|
||||||
|
|
||||||
- [Jool](https://nicmx.github.io/Jool/en/index.html), a kernelspace NAT64 and SIIT implementation, providing translation between IPv4 and IPv6. Available as [networking.jool.enable](#opt-networking.jool.enable).
|
- [Jool](https://nicmx.github.io/Jool/en/index.html), a kernelspace NAT64 and SIIT implementation, providing translation between IPv4 and IPv6. Available as [networking.jool.enable](#opt-networking.jool.enable).
|
||||||
|
|
||||||
|
- [Home Assistant Satellite], a streaming audio satellite for Home Assistant voice pipelines, where you can reuse existing mic/speaker hardware. Available as [services.homeassistant-satellite](#opt-services.homeassistant-satellite.enable).
|
||||||
|
|
||||||
- [Apache Guacamole](https://guacamole.apache.org/), a cross-platform, clientless remote desktop gateway. Available as [services.guacamole-server](#opt-services.guacamole-server.enable) and [services.guacamole-client](#opt-services.guacamole-client.enable) services.
|
- [Apache Guacamole](https://guacamole.apache.org/), a cross-platform, clientless remote desktop gateway. Available as [services.guacamole-server](#opt-services.guacamole-server.enable) and [services.guacamole-client](#opt-services.guacamole-client.enable) services.
|
||||||
|
|
||||||
- [pgBouncer](https://www.pgbouncer.org), a PostgreSQL connection pooler. Available as [services.pgbouncer](#opt-services.pgbouncer.enable).
|
- [pgBouncer](https://www.pgbouncer.org), a PostgreSQL connection pooler. Available as [services.pgbouncer](#opt-services.pgbouncer.enable).
|
||||||
|
|
|
@ -558,6 +558,7 @@
|
||||||
./services/home-automation/esphome.nix
|
./services/home-automation/esphome.nix
|
||||||
./services/home-automation/evcc.nix
|
./services/home-automation/evcc.nix
|
||||||
./services/home-automation/home-assistant.nix
|
./services/home-automation/home-assistant.nix
|
||||||
|
./services/home-automation/homeassistant-satellite.nix
|
||||||
./services/home-automation/zigbee2mqtt.nix
|
./services/home-automation/zigbee2mqtt.nix
|
||||||
./services/logging/SystemdJournal2Gelf.nix
|
./services/logging/SystemdJournal2Gelf.nix
|
||||||
./services/logging/awstats.nix
|
./services/logging/awstats.nix
|
||||||
|
|
|
@ -136,7 +136,7 @@ in
|
||||||
ProtectKernelTunables = true;
|
ProtectKernelTunables = true;
|
||||||
ProtectControlGroups = true;
|
ProtectControlGroups = true;
|
||||||
ProtectProc = "invisible";
|
ProtectProc = "invisible";
|
||||||
ProcSubset = "pid";
|
ProcSubset = "all"; # reads /proc/cpuinfo
|
||||||
RestrictAddressFamilies = [
|
RestrictAddressFamilies = [
|
||||||
"AF_INET"
|
"AF_INET"
|
||||||
"AF_INET6"
|
"AF_INET6"
|
||||||
|
|
|
@ -0,0 +1,225 @@
|
||||||
|
{ config
|
||||||
|
, lib
|
||||||
|
, pkgs
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.homeassistant-satellite;
|
||||||
|
|
||||||
|
inherit (lib)
|
||||||
|
escapeShellArg
|
||||||
|
escapeShellArgs
|
||||||
|
mkOption
|
||||||
|
mdDoc
|
||||||
|
mkEnableOption
|
||||||
|
mkIf
|
||||||
|
mkPackageOptionMD
|
||||||
|
types
|
||||||
|
;
|
||||||
|
|
||||||
|
inherit (builtins)
|
||||||
|
toString
|
||||||
|
;
|
||||||
|
|
||||||
|
# override the package with the relevant vad dependencies
|
||||||
|
package = cfg.package.overridePythonAttrs (oldAttrs: {
|
||||||
|
propagatedBuildInputs = oldAttrs.propagatedBuildInputs
|
||||||
|
++ lib.optional (cfg.vad == "webrtcvad") cfg.package.optional-dependencies.webrtc
|
||||||
|
++ lib.optional (cfg.vad == "silero") cfg.package.optional-dependencies.silerovad
|
||||||
|
++ lib.optional (cfg.pulseaudio.enable) cfg.package.optional-dependencies.pulseaudio;
|
||||||
|
});
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
meta.buildDocsInSandbox = false;
|
||||||
|
|
||||||
|
options.services.homeassistant-satellite = with types; {
|
||||||
|
enable = mkEnableOption (mdDoc "Home Assistant Satellite");
|
||||||
|
|
||||||
|
package = mkPackageOptionMD pkgs "homeassistant-satellite" { };
|
||||||
|
|
||||||
|
user = mkOption {
|
||||||
|
type = str;
|
||||||
|
example = "alice";
|
||||||
|
description = mdDoc ''
|
||||||
|
User to run homeassistant-satellite under.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
group = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "users";
|
||||||
|
description = mdDoc ''
|
||||||
|
Group to run homeassistant-satellite under.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
host = mkOption {
|
||||||
|
type = str;
|
||||||
|
example = "home-assistant.local";
|
||||||
|
description = mdDoc ''
|
||||||
|
Hostname on which your Home Assistant instance can be reached.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = port;
|
||||||
|
example = 8123;
|
||||||
|
description = mdDoc ''
|
||||||
|
Port on which your Home Assistance can be reached.
|
||||||
|
'';
|
||||||
|
apply = toString;
|
||||||
|
};
|
||||||
|
|
||||||
|
protocol = mkOption {
|
||||||
|
type = enum [ "http" "https" ];
|
||||||
|
default = "http";
|
||||||
|
example = "https";
|
||||||
|
description = mdDoc ''
|
||||||
|
The transport protocol used to connect to Home Assistant.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
tokenFile = mkOption {
|
||||||
|
type = path;
|
||||||
|
example = "/run/keys/hass-token";
|
||||||
|
description = mdDoc ''
|
||||||
|
Path to a file containing a long-lived access token for your Home Assistant instance.
|
||||||
|
'';
|
||||||
|
apply = escapeShellArg;
|
||||||
|
};
|
||||||
|
|
||||||
|
sounds = {
|
||||||
|
awake = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = null;
|
||||||
|
description = mdDoc ''
|
||||||
|
Audio file to play when the wake word is detected.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
done = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = null;
|
||||||
|
description = mdDoc ''
|
||||||
|
Audio file to play when the voice command is done.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
vad = mkOption {
|
||||||
|
type = enum [ "disabled" "webrtcvad" "silero" ];
|
||||||
|
default = "disabled";
|
||||||
|
example = "silero";
|
||||||
|
description = mdDoc ''
|
||||||
|
Voice activity detection model. With `disabled` sound will be transmitted continously.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
pulseaudio = {
|
||||||
|
enable = mkEnableOption "recording/playback via PulseAudio or PipeWire";
|
||||||
|
|
||||||
|
socket = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = null;
|
||||||
|
example = "/run/user/1000/pulse/native";
|
||||||
|
description = mdDoc ''
|
||||||
|
Path or hostname to connect with the PulseAudio server.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
duckingVolume = mkOption {
|
||||||
|
type = nullOr float;
|
||||||
|
default = null;
|
||||||
|
example = 0.4;
|
||||||
|
description = mdDoc ''
|
||||||
|
Reduce output volume (between 0 and 1) to this percentage value while recording.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
echoCancellation = mkEnableOption "acoustic echo cancellation";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraArgs = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
default = [ ];
|
||||||
|
description = mdDoc ''
|
||||||
|
Extra arguments to pass to the commandline.
|
||||||
|
'';
|
||||||
|
apply = escapeShellArgs;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
systemd.services."homeassistant-satellite" = {
|
||||||
|
description = "Home Assistant Satellite";
|
||||||
|
after = [
|
||||||
|
"network-online.target"
|
||||||
|
];
|
||||||
|
wants = [
|
||||||
|
"network-online.target"
|
||||||
|
];
|
||||||
|
wantedBy = [
|
||||||
|
"multi-user.target"
|
||||||
|
];
|
||||||
|
path = with pkgs; [
|
||||||
|
ffmpeg-headless
|
||||||
|
] ++ lib.optionals (!cfg.pulseaudio.enable) [
|
||||||
|
alsa-utils
|
||||||
|
];
|
||||||
|
serviceConfig = {
|
||||||
|
User = cfg.user;
|
||||||
|
Group = cfg.group;
|
||||||
|
# https://github.com/rhasspy/hassio-addons/blob/master/assist_microphone/rootfs/etc/s6-overlay/s6-rc.d/assist_microphone/run
|
||||||
|
ExecStart = ''
|
||||||
|
${package}/bin/homeassistant-satellite \
|
||||||
|
--host ${cfg.host} \
|
||||||
|
--port ${cfg.port} \
|
||||||
|
--protocol ${cfg.protocol} \
|
||||||
|
--token-file ${cfg.tokenFile} \
|
||||||
|
--vad ${cfg.vad} \
|
||||||
|
${lib.optionalString cfg.pulseaudio.enable "--pulseaudio"}${lib.optionalString (cfg.pulseaudio.socket != null) "=${cfg.pulseaudio.socket}"} \
|
||||||
|
${lib.optionalString (cfg.pulseaudio.enable && cfg.pulseaudio.duckingVolume != null) "--ducking-volume=${toString cfg.pulseaudio.duckingVolume}"} \
|
||||||
|
${lib.optionalString (cfg.pulseaudio.enable && cfg.pulseaudio.echoCancellation) "--echo-cancel"} \
|
||||||
|
${lib.optionalString (cfg.sounds.awake != null) "--awake-sound=${toString cfg.sounds.awake}"} \
|
||||||
|
${lib.optionalString (cfg.sounds.done != null) "--done-sound=${toString cfg.sounds.done}"} \
|
||||||
|
${cfg.extraArgs}
|
||||||
|
'';
|
||||||
|
CapabilityBoundingSet = "";
|
||||||
|
DeviceAllow = "";
|
||||||
|
DevicePolicy = "closed";
|
||||||
|
LockPersonality = true;
|
||||||
|
MemoryDenyWriteExecute = false; # onnxruntime/capi/onnxruntime_pybind11_state.so: cannot enable executable stack as shared object requires: Operation not permitted
|
||||||
|
PrivateDevices = true;
|
||||||
|
PrivateUsers = true;
|
||||||
|
ProtectHome = false; # Would deny access to local pulse/pipewire server
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
ProtectProc = "invisible";
|
||||||
|
ProcSubset = "all"; # Error in cpuinfo: failed to parse processor information from /proc/cpuinfo
|
||||||
|
Restart = "always";
|
||||||
|
RestrictAddressFamilies = [
|
||||||
|
"AF_INET"
|
||||||
|
"AF_INET6"
|
||||||
|
"AF_UNIX"
|
||||||
|
];
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
SupplementaryGroups = [
|
||||||
|
"audio"
|
||||||
|
];
|
||||||
|
SystemCallArchitectures = "native";
|
||||||
|
SystemCallFilter = [
|
||||||
|
"@system-service"
|
||||||
|
"~@privileged"
|
||||||
|
];
|
||||||
|
UMask = "0077";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
56
pkgs/by-name/ho/homeassistant-satellite/package.nix
Normal file
56
pkgs/by-name/ho/homeassistant-satellite/package.nix
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
{ lib
|
||||||
|
, python3
|
||||||
|
, fetchFromGitHub
|
||||||
|
}:
|
||||||
|
|
||||||
|
python3.pkgs.buildPythonApplication rec {
|
||||||
|
pname = "homeassistant-satellite";
|
||||||
|
version = "2.3.0";
|
||||||
|
pyproject = true;
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "synesthesiam";
|
||||||
|
repo = "homeassistant-satellite";
|
||||||
|
rev = "v${version}";
|
||||||
|
hash = "sha256-iosutOpkpt0JJIMyALuQSDLj4jk57ITShVyPYlQgMFg=";
|
||||||
|
};
|
||||||
|
|
||||||
|
nativeBuildInputs = with python3.pkgs; [
|
||||||
|
setuptools
|
||||||
|
wheel
|
||||||
|
];
|
||||||
|
|
||||||
|
propagatedBuildInputs = with python3.pkgs; [
|
||||||
|
aiohttp
|
||||||
|
];
|
||||||
|
|
||||||
|
passthru.optional-dependencies = {
|
||||||
|
pulseaudio = with python3.pkgs; [
|
||||||
|
pasimple
|
||||||
|
pulsectl
|
||||||
|
];
|
||||||
|
silerovad = with python3.pkgs; [
|
||||||
|
numpy
|
||||||
|
onnxruntime
|
||||||
|
];
|
||||||
|
webrtc = with python3.pkgs; [
|
||||||
|
webrtc-noise-gain
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
pythonImportsCheck = [
|
||||||
|
"homeassistant_satellite"
|
||||||
|
];
|
||||||
|
|
||||||
|
# no tests
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
changelog = "https://github.com/synesthesiam/homeassistant-satellite/blob/v${version}/CHANGELOG.md";
|
||||||
|
description = "Streaming audio satellite for Home Assistant";
|
||||||
|
homepage = "https://github.com/synesthesiam/homeassistant-satellite";
|
||||||
|
license = licenses.mit;
|
||||||
|
maintainers = with maintainers; [ hexa ];
|
||||||
|
mainProgram = "homeassistant-satellite";
|
||||||
|
};
|
||||||
|
}
|
44
pkgs/development/python-modules/pasimple/default.nix
Normal file
44
pkgs/development/python-modules/pasimple/default.nix
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
{ lib
|
||||||
|
, buildPythonPackage
|
||||||
|
, fetchFromGitHub
|
||||||
|
, setuptools
|
||||||
|
, pulseaudio
|
||||||
|
}:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "pasimple";
|
||||||
|
version = "0.0.2";
|
||||||
|
pyproject = true;
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "henrikschnor";
|
||||||
|
repo = "pasimple";
|
||||||
|
rev = "v${version}";
|
||||||
|
hash = "sha256-Z271FdBCqPFcQzVqGidL74nO85rO9clNvP4czAHmdEw=";
|
||||||
|
};
|
||||||
|
|
||||||
|
postPatch = ''
|
||||||
|
substituteInPlace pasimple/pa_simple.py --replace \
|
||||||
|
"_libpulse_simple = ctypes.CDLL('libpulse-simple.so.0')" \
|
||||||
|
"_libpulse_simple = ctypes.CDLL('${lib.getLib pulseaudio}/lib/libpulse-simple.so.0')"
|
||||||
|
'';
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
setuptools
|
||||||
|
];
|
||||||
|
|
||||||
|
pythonImportsCheck = [
|
||||||
|
"pasimple"
|
||||||
|
"pasimple.pa_simple"
|
||||||
|
];
|
||||||
|
|
||||||
|
# no tests
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "A python wrapper for the \"PulseAudio simple API\". Supports playing and recording audio via PulseAudio and PipeWire";
|
||||||
|
homepage = "https://github.com/henrikschnor/pasimple";
|
||||||
|
license = licenses.mit;
|
||||||
|
maintainers = with maintainers; [ hexa ];
|
||||||
|
};
|
||||||
|
}
|
|
@ -8732,6 +8732,8 @@ self: super: with self; {
|
||||||
parver = callPackage ../development/python-modules/parver { };
|
parver = callPackage ../development/python-modules/parver { };
|
||||||
arpeggio = callPackage ../development/python-modules/arpeggio { };
|
arpeggio = callPackage ../development/python-modules/arpeggio { };
|
||||||
|
|
||||||
|
pasimple = callPackage ../development/python-modules/pasimple { };
|
||||||
|
|
||||||
passlib = callPackage ../development/python-modules/passlib { };
|
passlib = callPackage ../development/python-modules/passlib { };
|
||||||
|
|
||||||
paste = callPackage ../development/python-modules/paste { };
|
paste = callPackage ../development/python-modules/paste { };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue