diff --git a/hosts/pi/default.nix b/hosts/pi/default.nix index eb3c631..b4ed9c7 100644 --- a/hosts/pi/default.nix +++ b/hosts/pi/default.nix @@ -7,12 +7,7 @@ ../server.nix ]; - nixpkgs = { - hostPlatform = "aarch64-linux"; - overlays = [ - (import ./../../overlays/ha-floorplan.nix) - ]; - }; + nixpkgs.hostPlatform = "aarch64-linux"; hardware = { raspberry-pi."4" = { diff --git a/modules/services/home-assistant/default.nix b/modules/services/home-assistant/default.nix index 12b0fbe..7cbbac6 100644 --- a/modules/services/home-assistant/default.nix +++ b/modules/services/home-assistant/default.nix @@ -3,9 +3,15 @@ let cfg = config.modules.services.home-assistant; in { + imports = [ + ./floorplan/default.nix + ./mqtt.nix + ]; + options.modules.services.home-assistant.enable = lib.mkEnableOption "home-assistant"; config = lib.mkIf cfg.enable { + age.secrets."files/services/home-assistant/secrets.yaml" = { file = "${self.inputs.secrets}/files/services/home-assistant/secrets.yaml.age"; path = "${config.services.home-assistant.configDir}/secrets.yaml"; @@ -13,12 +19,6 @@ in { group = "hass"; }; - modules.services.borgmatic.directories = [ - "/var/lib/mosquitto" - "/var/lib/zigbee2mqtt" - ]; - - services.home-assistant = { enable = true; @@ -61,10 +61,6 @@ in { }; lovelace = { resources = [ - { - url = "/local/nixos-lovelace-modules/floorplan.js"; - type = "module"; - } { url = "/local/nixos-lovelace-modulels/mushroom.js"; type = "module"; @@ -73,7 +69,6 @@ in { }; media_player = [ ]; mobile_app = { }; - mqtt = { }; onkyo = { }; open_meteo = { }; recorder = { @@ -86,6 +81,8 @@ in { zeroconf = { }; }; + configDir = "/etc/home-assistant"; + extraComponents = [ "air_quality" "airly" @@ -183,11 +180,6 @@ in { "modern_forms" "mold_indicator" "moon" - "mqtt" - "mqtt_eventstream" - "mqtt_json" - "mqtt_room" - "mqtt_statestream" "mysensors" "network" "nmap_tracker" @@ -276,7 +268,6 @@ in { customLovelaceModules = with pkgs.home-assistant-custom-lovelace-modules; [ bubble-card button-card - ha-floorplan mushroom sankey-chart universal-remote-card @@ -284,6 +275,12 @@ in { ]; }; + systemd.services.home-assistant.preStart = lib.mkForce ""; + + modules.services.borgmatic.directories = [ + config.services.home-assistant.configDir + ]; + services.nginx = { enable = true; virtualHosts."home.mesh.vimium.net" = { @@ -297,57 +294,5 @@ in { }; }; }; - - services.mosquitto = { - enable = true; - listeners = [{ - acl = [ "pattern readwrite #" ]; - omitPasswordAuth = true; - port = 1883; - settings = { - allow_anonymous = true; - }; - }]; - }; - - age.secrets."files/services/zigbee2mqtt/secret.yaml" = { - file = "${self.inputs.secrets}/files/services/zigbee2mqtt/secret.yaml.age"; - path = "${config.services.zigbee2mqtt.dataDir}/secret.yaml"; - owner = "zigbee2mqtt"; - group = "zigbee2mqtt"; - }; - - services.zigbee2mqtt = { - package = pkgs.unstable.zigbee2mqtt; - enable = true; - dataDir = "/var/lib/zigbee2mqtt"; - settings = { - homeassistant = lib.optionalAttrs config.services.home-assistant.enable { - discovery_topic = "homeassistant"; - status_topic = "hass/status"; - legacy_entity_attributes = true; - legacy_triggers = true; - }; - availability = true; - frontend = true; - device_options = { - retain = true; - }; - serial = { - port = "/dev/serial/by-id/usb-Silicon_Labs_Sonoff_Zigbee_3.0_USB_Dongle_Plus_0001-if00-port0"; - }; - advanced = { - channel = 20; - network_key = "!secret.yaml network_key"; - pan_id = 13001; - ext_pan_id = [ 79 1 73 47 250 136 124 222 ]; - transmit_power = 20; - }; - mqtt = { - version = 5; - server = "mqtt://localhost:1883"; - }; - }; - }; }; } diff --git a/modules/services/home-assistant/floorplan/default.nix b/modules/services/home-assistant/floorplan/default.nix new file mode 100644 index 0000000..4d45879 --- /dev/null +++ b/modules/services/home-assistant/floorplan/default.nix @@ -0,0 +1,92 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.modules.services.home-assistant; +in { + config = lib.mkIf cfg.enable { + services.home-assistant = { + config.lovelace.resources = [{ + url = "/local/nixos-lovelace-modules/floorplan.js"; + type = "module"; + }]; + customLovelaceModules = [ + pkgs.ha-floorplan + ]; + }; + + environment.etc."home-assistant/www/floorplan/style.css".source = ./style.css; + environment.etc."home-assistant/www/floorplan/config.yaml".text = builtins.toJSON { + image = { + location = "/local/floorplan/beetham.svg"; + cache = false; + }; + stylesheet = { + location = "/local/floorplan/style.css"; + cache = false; + }; + + defaults = { + hover_action = "hover-info"; + hold_action = "toggle"; + tap_action = "more-info"; + }; + + rules = [ + { + name = "Rooms"; + entities = [ + { + entity = "light.bedroom_lamps"; + element = "area.bedroom"; + } + { + entity = "light.hallway_spots"; + element = "area.hallway"; + } + { + entity = "light.living_room_lamps"; + element = "area.livingroom"; + } + { + entity = "light.office_lamps"; + element = "area.office"; + } + ]; + tap_action = "light.toggle"; + state_action = { + service = "floorplan.class_set"; + service_data = '' + if (entity.state === "on") { + return "light-on"; + } + return "light-off"; + ''; + }; + } + { + name = "Temperature"; + entities = [ + "sensor.motion_sensor_temperature" + ]; + state_action = [ + { + service = "floorplan.text_set"; + service_data = '' + if (!isNaN(entity.state)) { + return Math.round(entity.state * 10) / 10 + "°"; + } + return "Unknown"; + ''; + } + { + service = "floorplan.class_set"; + service_data = { + class = "static-temp"; + }; + } + ]; + } + ]; + }; + }; +} diff --git a/modules/services/home-assistant/floorplan/style.css b/modules/services/home-assistant/floorplan/style.css new file mode 100644 index 0000000..a4e59ba --- /dev/null +++ b/modules/services/home-assistant/floorplan/style.css @@ -0,0 +1,27 @@ +#floorplan { + padding: 10px; +} + +svg, svg * { + vector-effect: non-scaling-stroke !important; + pointer-events: all !important; +} + +path[id*="area."].light-on { + opacity: 0 !important; +} + +path[id*="area."] { + opacity: 0.5 !important; + transition: opacity .25s; + -moz-transition: opacity .25s; + -webkit-transition: opacity .25s; +} + +svg tspan { + fill: var(--primary-text-color); +} + +.static-temp, .static-temp tspan { + fill: #ffffff; +} diff --git a/modules/services/home-assistant/mqtt.nix b/modules/services/home-assistant/mqtt.nix new file mode 100644 index 0000000..ea0b366 --- /dev/null +++ b/modules/services/home-assistant/mqtt.nix @@ -0,0 +1,75 @@ +{ config, lib, pkgs, self, ... }: + +let + cfg = config.modules.services.home-assistant; +in { + config = lib.mkIf cfg.enable { + services.mosquitto = { + enable = true; + listeners = [{ + acl = [ "pattern readwrite #" ]; + omitPasswordAuth = true; + port = 1883; + settings = { + allow_anonymous = true; + }; + }]; + }; + + age.secrets."files/services/zigbee2mqtt/secret.yaml" = { + file = "${self.inputs.secrets}/files/services/zigbee2mqtt/secret.yaml.age"; + path = "${config.services.zigbee2mqtt.dataDir}/secret.yaml"; + owner = "zigbee2mqtt"; + group = "zigbee2mqtt"; + }; + + services.zigbee2mqtt = { + package = pkgs.unstable.zigbee2mqtt; + enable = true; + dataDir = "/var/lib/zigbee2mqtt"; + settings = { + homeassistant = lib.optionalAttrs config.services.home-assistant.enable { + discovery_topic = "homeassistant"; + status_topic = "hass/status"; + legacy_entity_attributes = true; + legacy_triggers = true; + }; + availability = true; + frontend = true; + device_options = { + retain = true; + }; + serial = { + port = "/dev/serial/by-id/usb-Silicon_Labs_Sonoff_Zigbee_3.0_USB_Dongle_Plus_0001-if00-port0"; + }; + advanced = { + channel = 20; + network_key = "!secret.yaml network_key"; + pan_id = 13001; + ext_pan_id = [ 79 1 73 47 250 136 124 222 ]; + transmit_power = 20; + }; + mqtt = { + version = 5; + server = "mqtt://localhost:1883"; + }; + }; + }; + + modules.services.borgmatic.directories = [ + config.services.mosquitto.dataDir + config.services.zigbee2mqtt.dataDir + ]; + + services.home-assistant = { + config.mqtt = {}; + extraComponents = [ + "mqtt" + "mqtt_eventstream" + "mqtt_json" + "mqtt_room" + "mqtt_statestream" + ]; + }; + }; +} diff --git a/overlays/ha-floorplan.nix b/overlays/ha-floorplan.nix deleted file mode 100644 index 822cef7..0000000 --- a/overlays/ha-floorplan.nix +++ /dev/null @@ -1,6 +0,0 @@ -final: prev: -{ - home-assistant-custom-lovelace-modules = prev.home-assistant-custom-lovelace-modules // { - ha-floorplan = prev.callPackage ../pkgs/ha-floorplan/package.nix { }; - }; -}