mirror of
https://github.com/anotherhadi/nixy.git
synced 2026-10-05 11:18:24 +02:00
Add signal notifications & apps
Signed-off-by: Hadi <[email protected]>
This commit is contained in:
@@ -1,41 +0,0 @@
|
||||
{config, ...}: {
|
||||
services.home-assistant = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
configWritable = true;
|
||||
extraComponents = [
|
||||
"default_config"
|
||||
"met"
|
||||
"esphome"
|
||||
"hue"
|
||||
"matter"
|
||||
"thread"
|
||||
];
|
||||
config = {
|
||||
default_config = {};
|
||||
http = {
|
||||
trusted_proxies = ["127.0.0.1" "::1"];
|
||||
use_x_forwarded_for = true;
|
||||
};
|
||||
scene = "!include scenes.yaml";
|
||||
automation = "!include automations.yaml";
|
||||
script = "!include scripts.yaml";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.home-assistant.preStart = ''
|
||||
for f in scenes.yaml automations.yaml scripts.yaml; do
|
||||
path="${config.services.home-assistant.configDir}/$f"
|
||||
[ -f "$path" ] || echo "[]" > "$path"
|
||||
done
|
||||
'';
|
||||
|
||||
services.matter-server = {
|
||||
enable = true;
|
||||
extraArgs.primary-interface = config.var.networkInterface;
|
||||
};
|
||||
|
||||
networking.firewall.allowedUDPPorts = [5353];
|
||||
|
||||
services.cloudflared.tunnels."${config.var.tunnelId}".ingress."hass.${config.var.domain}" = "http://localhost:${toString config.services.home-assistant.config.http.server_port}";
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
nixyTheme = import ./theme.nix {inherit config pkgs;};
|
||||
plugins = import ./plugins.nix {inherit pkgs;};
|
||||
|
||||
signalRecipients = [
|
||||
"h"
|
||||
"d"
|
||||
];
|
||||
in {
|
||||
sops.secrets =
|
||||
{signal_sender_number.owner = "hass";}
|
||||
// lib.genAttrs signalRecipients (_: {owner = "hass";});
|
||||
|
||||
sops.templates."home-assistant-secrets.yaml" = {
|
||||
path = "${config.services.home-assistant.configDir}/secrets.yaml";
|
||||
owner = "hass";
|
||||
restartUnits = ["home-assistant.service"];
|
||||
content =
|
||||
"signal_sender: \"${config.sops.placeholder.signal_sender_number}\"\n"
|
||||
+ lib.concatMapStrings (n: "${n}: \"${config.sops.placeholder.${n}}\"\n") signalRecipients;
|
||||
};
|
||||
|
||||
services.home-assistant = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
configWritable = true;
|
||||
extraComponents = [
|
||||
"default_config"
|
||||
"met"
|
||||
"esphome"
|
||||
"hue"
|
||||
"matter"
|
||||
"thread"
|
||||
"sonos"
|
||||
"apple_tv"
|
||||
"signal_messenger"
|
||||
"manual"
|
||||
"meteo_france"
|
||||
"remote_calendar"
|
||||
];
|
||||
customComponents = plugins.customComponents;
|
||||
customLovelaceModules = plugins.customLovelaceModules;
|
||||
config = {
|
||||
default_config = {};
|
||||
http = {
|
||||
trusted_proxies = ["127.0.0.1" "::1"];
|
||||
use_x_forwarded_for = true;
|
||||
};
|
||||
scene = "!include scenes.yaml";
|
||||
automation = "!include automations.yaml";
|
||||
script = "!include scripts.yaml";
|
||||
frontend.themes = nixyTheme;
|
||||
notify =
|
||||
(map (n: {
|
||||
name = "signal_${n}";
|
||||
platform = "signal_messenger";
|
||||
url = config.services.signal-cli-rest-api.url;
|
||||
number = "!secret signal_sender";
|
||||
recipients = ["!secret ${n}"];
|
||||
})
|
||||
signalRecipients)
|
||||
++ [
|
||||
{
|
||||
name = "signal_all";
|
||||
platform = "signal_messenger";
|
||||
url = config.services.signal-cli-rest-api.url;
|
||||
number = "!secret signal_sender";
|
||||
recipients = map (n: "!secret ${n}") signalRecipients;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.home-assistant.preStart = ''
|
||||
for f in scenes.yaml automations.yaml scripts.yaml; do
|
||||
path="${config.services.home-assistant.configDir}/$f"
|
||||
[ -f "$path" ] || echo "[]" > "$path"
|
||||
done
|
||||
'';
|
||||
|
||||
services.matter-server = {
|
||||
enable = true;
|
||||
extraArgs.primary-interface = config.var.networkInterface;
|
||||
};
|
||||
|
||||
networking.firewall.allowedUDPPorts = [5353];
|
||||
|
||||
services.cloudflared.tunnels."${config.var.tunnelId}".ingress."hass.${config.var.domain}" = "http://localhost:${toString config.services.home-assistant.config.http.server_port}";
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
# Custom (non-core) Home Assistant integrations built from source.
|
||||
{pkgs, ...}: let
|
||||
idfm-api = pkgs.home-assistant.python3Packages.buildPythonPackage rec {
|
||||
pname = "idfm-api";
|
||||
version = "1.3.1";
|
||||
pyproject = true;
|
||||
src = pkgs.fetchurl {
|
||||
url = "https://files.pythonhosted.org/packages/source/i/idfm-api/idfm_api-${version}.tar.gz";
|
||||
hash = "sha256-j9whladp+nTUd6dnB0EybOiG2xQ7OyLf6LN3MpzjZv0=";
|
||||
};
|
||||
build-system = [pkgs.home-assistant.python3Packages.setuptools];
|
||||
dependencies = with pkgs.home-assistant.python3Packages; [aiohttp async-timeout];
|
||||
doCheck = false;
|
||||
};
|
||||
|
||||
idfm = pkgs.buildHomeAssistantComponent {
|
||||
owner = "droso-hass";
|
||||
domain = "idfm";
|
||||
version = "2.3.1";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "droso-hass";
|
||||
repo = "idfm";
|
||||
tag = "v2.3.1";
|
||||
hash = "sha256-Zlgd6TXxipcfUcdOyOpLcchM9DO84jCCtREFgbGRcY4=";
|
||||
};
|
||||
dependencies = [idfm-api];
|
||||
};
|
||||
|
||||
atomic-calendar-revive = pkgs.stdenvNoCC.mkDerivation {
|
||||
pname = "atomic-calendar-revive";
|
||||
version = "10.3.1";
|
||||
src = pkgs.fetchurl {
|
||||
url = "https://github.com/totaldebug/atomic-calendar-revive/releases/download/v10.3.1/atomic-calendar-revive.js";
|
||||
hash = "sha256-F4vXHQRAsiaK/ylL4X5d70TBxukMAqeQixb6XE68yZo=";
|
||||
};
|
||||
dontUnpack = true;
|
||||
installPhase = ''
|
||||
mkdir $out
|
||||
cp $src $out/atomic-calendar-revive.js
|
||||
'';
|
||||
};
|
||||
in {
|
||||
customComponents = [idfm];
|
||||
customLovelaceModules = [atomic-calendar-revive];
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
b = config.stylix.base16Scheme;
|
||||
hex = shade: "#${shade}";
|
||||
rgbTriplet = shade: let
|
||||
d = c:
|
||||
if c == "a"
|
||||
then 10
|
||||
else if c == "b"
|
||||
then 11
|
||||
else if c == "c"
|
||||
then 12
|
||||
else if c == "d"
|
||||
then 13
|
||||
else if c == "e"
|
||||
then 14
|
||||
else if c == "f"
|
||||
then 15
|
||||
else pkgs.lib.toInt c;
|
||||
h = pkgs.lib.toLower shade;
|
||||
byte = pos: toString (d (builtins.substring pos 1 h) * 16 + d (builtins.substring (pos + 1) 1 h));
|
||||
in "${byte 0}, ${byte 2}, ${byte 4}";
|
||||
in {
|
||||
"Nixy" = {
|
||||
# Main interface colors
|
||||
"primary-color" = hex b.base0D;
|
||||
"accent-color" = "var(--primary-color)";
|
||||
"primary-background-color" = hex b.base00;
|
||||
"secondary-background-color" = hex b.base01;
|
||||
"divider-color" = hex b.base02;
|
||||
# Text
|
||||
"primary-text-color" = hex b.base05;
|
||||
"text-primary-color" = "var(--primary-text-color)";
|
||||
"secondary-text-color" = hex b.base04;
|
||||
"disabled-text-color" = hex b.base03;
|
||||
# Header / sidebar
|
||||
"app-header-background-color" = hex b.base01;
|
||||
"app-header-text-color" = "var(--primary-text-color)";
|
||||
"app-header-selection-bar-color" = "var(--primary-color)";
|
||||
"app-header-edit-background-color" = hex b.base02;
|
||||
"sidebar-icon-color" = "var(--secondary-text-color)";
|
||||
"sidebar-text-color" = "var(--primary-text-color)";
|
||||
"sidebar-background-color" = hex b.base01;
|
||||
"sidebar-selected-icon-color" = "var(--primary-color)";
|
||||
"sidebar-selected-text-color" = "var(--primary-color)";
|
||||
# Buttons / icons / state
|
||||
"paper-item-icon-color" = "var(--secondary-text-color)";
|
||||
"paper-item-icon-active-color" = "var(--primary-color)";
|
||||
"mdc-button-outline-color" = "var(--primary-color)";
|
||||
"state-icon-color" = "var(--paper-item-icon-color)";
|
||||
"state-icon-active-color" = "var(--paper-item-icon-active-color)";
|
||||
"state-icon-unavailable-color" = "var(--disabled-text-color)";
|
||||
# Sliders
|
||||
"paper-slider-knob-color" = "var(--primary-color)";
|
||||
"paper-slider-knob-start-color" = "var(--primary-color)";
|
||||
"paper-slider-pin-color" = "var(--primary-color)";
|
||||
"paper-slider-active-color" = "var(--primary-color)";
|
||||
"paper-slider-secondary-color" = "var(--secondary-background-color)";
|
||||
# Labels / badges
|
||||
"label-badge-background-color" = "var(--secondary-background-color)";
|
||||
"label-badge-text-color" = "var(--primary-text-color)";
|
||||
"label-badge-red" = hex b.base08;
|
||||
"label-badge-green" = hex b.base0B;
|
||||
"label-badge-blue" = hex b.base0D;
|
||||
"label-badge-yellow" = hex b.base0A;
|
||||
"label-badge-gray" = "var(--secondary-text-color)";
|
||||
# Cards / surfaces
|
||||
"card-background-color" = hex b.base01;
|
||||
"ha-card-background" = "var(--card-background-color)";
|
||||
"ha-card-border-color" = hex b.base02;
|
||||
"paper-dialog-background-color" = "var(--card-background-color)";
|
||||
"paper-listbox-background-color" = "var(--card-background-color)";
|
||||
"paper-card-background-color" = "var(--card-background-color)";
|
||||
"table-row-background-color" = "var(--primary-background-color)";
|
||||
"table-row-alternative-background-color" = "var(--secondary-background-color)";
|
||||
"data-table-background-color" = "var(--primary-background-color)";
|
||||
"material-background-color" = "var(--primary-background-color)";
|
||||
"material-secondary-background-color" = "var(--secondary-background-color)";
|
||||
"markdown-code-background-color" = hex b.base01;
|
||||
"code-editor-background-color" = hex b.base01;
|
||||
# Switches / toggles
|
||||
"switch-checked-button-color" = "var(--primary-color)";
|
||||
"switch-checked-track-color" = "var(--primary-color)";
|
||||
"switch-unchecked-button-color" = "var(--secondary-text-color)";
|
||||
"switch-unchecked-track-color" = "var(--disabled-text-color)";
|
||||
"paper-toggle-button-checked-button-color" = "var(--switch-checked-button-color)";
|
||||
"paper-toggle-button-checked-bar-color" = "var(--switch-checked-track-color)";
|
||||
"paper-toggle-button-unchecked-button-color" = "var(--switch-unchecked-button-color)";
|
||||
"paper-toggle-button-unchecked-bar-color" = "var(--switch-unchecked-track-color)";
|
||||
"mdc-checkbox-unchecked-color" = "var(--secondary-text-color)";
|
||||
"mdc-checkbox-disable-color" = "var(--disabled-text-color)";
|
||||
"mdc-theme-primary" = "var(--primary-color)";
|
||||
"mdc-theme-secondary" = "var(--primary-color)";
|
||||
"mdc-theme-background" = "var(--primary-background-color)";
|
||||
"mdc-theme-surface" = "var(--card-background-color)";
|
||||
"mdc-theme-on-primary" = hex b.base00;
|
||||
"mdc-theme-on-secondary" = hex b.base00;
|
||||
"mdc-theme-on-surface" = "var(--primary-text-color)";
|
||||
"mdc-theme-text-primary-on-background" = "var(--primary-text-color)";
|
||||
"mdc-theme-text-secondary-on-background" = "var(--secondary-text-color)";
|
||||
"mdc-theme-text-hint-on-background" = "var(--secondary-text-color)";
|
||||
"mdc-theme-text-disabled-on-background" = "var(--disabled-text-color)";
|
||||
"mdc-theme-text-icon-on-background" = "var(--secondary-text-color)";
|
||||
"mdc-select-fill-color" = "var(--secondary-background-color)";
|
||||
"mdc-select-ink-color" = "var(--primary-text-color)";
|
||||
"mdc-select-label-ink-color" = "var(--secondary-text-color)";
|
||||
"mdc-select-idle-line-color" = "var(--secondary-text-color)";
|
||||
"mdc-select-dropdown-icon-color" = "var(--secondary-text-color)";
|
||||
"mdc-select-hover-line-color" = "var(--primary-color)";
|
||||
"mdc-list-item-graphic-color" = "var(--secondary-text-color)";
|
||||
"mdc-text-field-fill-color" = "var(--mdc-select-fill-color)";
|
||||
"mdc-text-field-ink-color" = "var(--primary-text-color)";
|
||||
"mdc-text-field-label-ink-color" = "var(--secondary-text-color)";
|
||||
"mdc-text-field-idle-line-color" = "var(--secondary-text-color)";
|
||||
"input-fill-color" = "var(--secondary-background-color)";
|
||||
"input-dropdown-icon-color" = "var(--secondary-text-color)";
|
||||
"input-ink-color" = "var(--primary-text-color)";
|
||||
"input-label-ink-color" = "var(--secondary-text-color)";
|
||||
"input-idle-line-color" = "var(--secondary-text-color)";
|
||||
"input-hover-line-color" = "var(--primary-color)";
|
||||
"rgb-primary-text-color" = rgbTriplet b.base05;
|
||||
"rgb-primary-color" = rgbTriplet b.base0D;
|
||||
"rgb-accent-color" = rgbTriplet b.base0D;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{lib, ...}: let
|
||||
port = 8080;
|
||||
in {
|
||||
options.services.signal-cli-rest-api.url = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
readOnly = true;
|
||||
default = "http://127.0.0.1:${toString port}";
|
||||
description = "URL of the local signal-cli-rest-api instance.";
|
||||
};
|
||||
|
||||
config = {
|
||||
virtualisation.docker.enable = true;
|
||||
|
||||
systemd.tmpfiles.rules = ["d /var/lib/signal-cli-rest-api 0750 root root -"];
|
||||
|
||||
virtualisation.oci-containers = {
|
||||
backend = "docker";
|
||||
containers.signal-cli-rest-api = {
|
||||
image = "bbernhard/signal-cli-rest-api:0.98";
|
||||
# json-rpc keeps one persistent signal-cli daemon instead of spawning
|
||||
# a fresh process per API call; native mode serializes calls behind a
|
||||
# file lock and each spawn takes ~40s, causing timeouts under any
|
||||
# concurrent access (e.g. Home Assistant retries).
|
||||
environment.MODE = "json-rpc";
|
||||
ports = ["127.0.0.1:${toString port}:8080"];
|
||||
volumes = ["/var/lib/signal-cli-rest-api:/home/.local/share/signal-cli"];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user