312 lines
8.9 KiB
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";
|
|
};
|
|
};
|
|
}
|