depot/ops/nixos/totoro/home-assistant.nix

312 lines
8.9 KiB
Nix

{ depot, lib, pkgs, config, ... }:
let
inherit (depot.ops) secrets;
in {
services.zigbee2mqtt = {
enable = true;
package = pkgs.zigbee2mqtt;
settings = {
homeassistant = true;
serial.port = "/dev/serial/by-id/usb-ITead_Sonoff_Zigbee_3.0_USB_Dongle_Plus_eca6e9ba6596ed11ac206b4ce259fb3e-if00-port0";
mqtt = {
server = "mqtt://localhost:1883";
user = "zigbee2mqtt";
password = "zigbee2mqtt";
};
frontend = {
port = 8099;
host = config.my.ip.tailscale6;
};
};
};
services.mosquitto = let
localhostUsers = {
zigbee2mqtt = {
password = "zigbee2mqtt";
acl = [
"readwrite zigbee2mqtt/#"
"readwrite homeassistant/#"
];
};
matrix2mqtt = {
password = "matrix2mqtt";
acl = [
"readwrite matrix2mqtt/#"
"readwrite homeassistant/#"
];
};
homeassistant = {
password = "homeassistant";
acl = [
"readwrite matrix2mqtt/#"
"readwrite zigbee2mqtt/#"
"readwrite homeassistant/#"
];
};
};
in {
enable = true;
listeners = [{
address = "127.0.0.1";
port = 1883;
users = localhostUsers;
} {
address = "::1";
port = 1883;
users = localhostUsers;
}];
};
services.home-assistant = {
enable = true;
configWritable = true;
lovelaceConfigWritable = true;
config = {
homeassistant = {
name = "117 Malden Road";
time_zone = "Europe/London";
external_url = "https://ha.lukegb.com";
internal_url = "https://ha.lukegb.com";
};
notify = [{
name = "pushover-luke";
platform = "pushover";
}];
http = {
use_x_forwarded_for = true;
trusted_proxies = [ "::1" "127.0.0.1" ];
};
lifx.light = {};
light = [{
platform = "group";
name = "Bedroom Lights";
entities = map (x: "light.overhead_${x.side}_${x.n}") (lib.cartesianProduct { side = [ "left" "right" ]; n = [ "1" "2" "3" "4" ]; });
}];
cast = {};
plex = {};
default_config = {};
broadlink = {};
homekit = {};
mqtt = {};
smartthings = {};
google_assistant = {
project_id = "malden-homeassistant";
service_account = secrets.homeAssistant.googleServiceAccount;
report_state = true;
exposed_domains = [
"light"
];
};
scene = let
bedroomOverhead = x: ({
color_mode = "color_temp";
brightness = 255;
color_temp = 316;
} // x);
entityDefs = ring: overhead: let o = bedroomOverhead { state = overhead; }; in {
"light.overhead_left_1" = o;
"light.overhead_left_2" = o;
"light.overhead_left_3" = o;
"light.overhead_left_4" = o;
"light.overhead_right_1" = o;
"light.overhead_right_2" = o;
"light.overhead_right_3" = o;
"light.overhead_right_4" = o;
};
in [{
name = "Bedroom Reset";
entities = entityDefs "off" "on";
} {
name = "Bedroom Off";
entities = entityDefs "off" "off";
}];
automation = let
base = extra: alias: webhook_id: ({
inherit alias;
trigger = [{
inherit webhook_id;
platform = "webhook";
}];
} // extra);
toggleEntity = entity_id: base {
action = [{
service = "homeassistant.toggle";
target.entity_id = entity_id;
}];
};
playPauseEntity = entity_id: base {
action = [{
service = "media_player.media_play_pause";
target.entity_id = entity_id;
}];
};
scene = scene_entity_id: base {
action = [{
service = "scene.turn_on";
target.entity_id = scene_entity_id;
data.transition = 1.0;
}];
};
in [
(toggleEntity "light.bedroom_lights" "Desk LHS Switch press - toggle room" "flic_desk_lhs")
(scene "scene.bedroom_reset" "Desk LHS Switch hold - reset room" "flic_desk_lhs_hold")
(toggleEntity "light.bedside_lamp" "Desk RHS Switch press - toggle bedside" "flic_desk_rhs")
(toggleEntity "light.bedroom_lights" "Bed LHS Switch press - toggle room" "flic_bed_lhs")
(scene "scene.bedroom_reset" "Bed LHS Switch dblpress - reset room" "flic_bed_lhs_dbl")
(scene "scene.bedroom_off" "Bed LHS Switch dblpress - reset room" "flic_bed_lhs_hold")
(playPauseEntity "media_player.nebula" "Bed RHS Switch press - play/pause nebula" "flic_bed_rhs")
(toggleEntity "light.bedroom_lights" "Bedroom Door Switch press - toggle room" "flic_bedroom_door")
(scene "scene.bedroom_off" "Bedroom Door Switch dblpress - room off" "flic_bedroom_door_dbl")
(scene "scene.bedroom_off" "Bedroom Door Switch hold - room off" "flic_bedroom_door_hold")
];
};
lovelaceConfig = {
title = "117 Malden Road";
views = [{
title = "Luke's Bedroom";
badges = let
scene = scene: cfg: lib.mkMerge [{
type = "entity";
show_name = true;
show_state = false;
show_icon = true;
entity = "scene.${scene}";
tap_action.action = "toggle";
} cfg];
in [(scene "bedroom_off" {
icon = "mdi:ceiling-light-outline";
}) (scene "bedroom_reset" {
icon = "mdi:ceiling-light-multiple";
})];
cards = [{
type = "grid";
square = false;
columns = 1;
cards = [{
type = "light";
entity = "light.bedroom_lights";
} {
type = "entities";
entities = [{
name = "Mosquito Repellent";
entity = "switch.lukes_bedroom_mosquitto_repellent";
}];
}];
} {
type = "grid";
square = false;
columns = 1;
cards = [{
type = "media-control";
entity = "media_player.nebula_3";
} {
type = "media-control";
entity = "media_player.shield_2";
}];
} {
type = "grid";
square = false;
columns = 1;
cards = [{
title = "Projector";
type = "entities";
entities = [{
name = "source";
entity = "select.hdmi_matrix_hdmi_1_projector";
} {
name = "Power (CEC)";
entity = "switch.hdmi_matrix_hdmi_1_projector_cec_power";
icon = "mdi:power";
}];
} {
title = "Sound Bar";
type = "entities";
entities = [{
name = "Source";
entity = "select.hdmi_matrix_hdmi_2_sound_bar";
} {
name = "Power (Samsung SmartThings)";
entity = "switch.samsung_soundbar_q930b";
icon = "mdi:power";
} {
name = "Power (CEC)";
entity = "switch.hdmi_matrix_hdmi_2_sound_bar_cec_power";
icon = "mdi:power";
}];
} {
title = "Side Monitor";
type = "entities";
entities = [{
name = "Source";
entity = "select.hdmi_matrix_hdmi_3_desk_monitor";
} {
name = "Power";
entity = "switch.hdmi_matrix_hdmi_3_desk_monitor_cec_power";
icon = "mdi:power";
}];
}];
}];
}];
};
};
services.nginx.virtualHosts."ha.lukegb.com" = {
forceSSL = true;
locations."/" = {
proxyPass = "http://localhost:8123/";
proxyWebsockets = true;
};
};
my.vault.acmeCertificates."ha.lukegb.com" = {
hostnames = [ "ha.lukegb.com" ];
nginxVirtualHosts = [ "ha.lukegb.com" ];
};
services.node-red = {
enable = true;
withNpmAndGcc = true;
port = 1880;
};
systemd.services.matrix2mqtt = {
wantedBy = [ "multi-user.target" ];
unitConfig = {
StartLimitIntervalSec = "0";
};
serviceConfig = {
ExecStart = "${depot.rust.matrix2mqtt}/bin/matrix2mqtt";
User = "matrix2mqtt";
PrivateTmp = true;
PrivateDevices = true;
RestrictNamespaces = true;
RestrictRealtime = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
ProtectHostname = true;
ProtectHome = true;
ProtectProc = "invisible";
ProcSubset = "pid";
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectClock = true;
CapabilityBoundingSet = "";
LockPersonality = true;
PrivateUsers = true;
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_NETLINK";
DynamicUser = true;
Restart = "always";
RestartSec = "100ms";
RestartSteps = 10;
RestartMaxDelaySec = "1min";
};
};
}