diff --git a/flake.nix b/flake.nix index f2fd060..c7f4f5b 100644 --- a/flake.nix +++ b/flake.nix @@ -246,6 +246,24 @@ chaotic.nixosModules.default ]; }; + + # home assistant + "jallen-hass" = nixpkgs-unstable.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + nixos-hardware.nixosModules.raspberry-pi-4 + impermanence.nixosModules.impermanence + ./hosts/homeassistant/configuration.nix + sops-nix.nixosModules.sops + + home-manager.nixosModules.home-manager + { + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + home-manager.users.hass = import ./hosts/hass/home.nix; + } + ]; + }; }; darwinConfigurations = { diff --git a/hosts/homeassistant/automations.yaml b/hosts/homeassistant/automations.yaml new file mode 100644 index 0000000..64b436c --- /dev/null +++ b/hosts/homeassistant/automations.yaml @@ -0,0 +1,576 @@ +- id: '1692388103102' + alias: Weekly Backup + description: Create a full backup every Sunday at 3 am and store it on the NAS + trigger: + - platform: time + at: 03:00:00 + condition: + - condition: time + weekday: + - sun + action: + - service: hassio.backup_full + data: + compressed: true + mode: single +- id: '1692389901297' + alias: Livingroom Lights + description: '' + trigger: + - platform: device + domain: mqtt + device_id: 37d42431de65199af00220b43dae04c1 + type: action + subtype: on_press + id: 'on' + - platform: device + domain: mqtt + device_id: 37d42431de65199af00220b43dae04c1 + type: action + subtype: off_press + id: 'off' + - platform: device + domain: mqtt + device_id: 37d42431de65199af00220b43dae04c1 + type: action + subtype: up_press + id: up + - platform: device + domain: mqtt + device_id: 37d42431de65199af00220b43dae04c1 + type: action + subtype: down_press + id: down + - platform: device + domain: mqtt + device_id: 37d42431de65199af00220b43dae04c1 + type: action + subtype: on_hold + id: hold + condition: [] + action: + - choose: + - conditions: + - condition: trigger + id: + - 'on' + sequence: + - data: + brightness_pct: 100 + color_temp_kelvin: 5000 + transition: 1 + target: + entity_id: light.livingroom_lights + action: light.turn_on + - conditions: + - condition: trigger + id: + - 'off' + sequence: + - data: + transition: 1 + target: + entity_id: light.livingroom_lights + action: light.turn_off + - conditions: + - condition: trigger + id: + - hold + sequence: + - data: + brightness_pct: 100 + rgb_color: + - 255 + - 38 + - 0 + transition: 1 + target: + entity_id: light.livingroom_lights + action: light.turn_on + - conditions: + - condition: trigger + id: + - dim up + sequence: + - data: + brightness_step_pct: 20 + target: + entity_id: light.livingroom_lights + action: light.turn_on + - conditions: + - condition: trigger + id: + - dim down + sequence: + - data: + brightness_step_pct: -20 + target: + entity_id: light.livingroom_lights + action: light.turn_on + mode: single +- id: '1692390365798' + alias: Bedroom Lights + description: '' + triggers: + - domain: mqtt + device_id: a492c0abb8f14e0888df08101f77f484 + type: action + subtype: off_press + id: 'off' + trigger: device + - domain: mqtt + device_id: a492c0abb8f14e0888df08101f77f484 + type: action + subtype: on_press + id: 'on' + trigger: device + - domain: mqtt + device_id: a492c0abb8f14e0888df08101f77f484 + type: action + subtype: up_press + id: up + trigger: device + - domain: mqtt + device_id: a492c0abb8f14e0888df08101f77f484 + type: action + subtype: down_press + id: down + trigger: device + - domain: mqtt + device_id: a492c0abb8f14e0888df08101f77f484 + type: action + subtype: on_hold + id: hold on + trigger: device + conditions: [] + actions: + - choose: + - conditions: + - condition: trigger + id: + - 'on' + sequence: + - data: + brightness_pct: 100 + color_temp_kelvin: 5000 + transition: 1 + target: + entity_id: light.bedroom_lights + action: light.turn_on + - conditions: + - condition: trigger + id: + - 'off' + sequence: + - data: + transition: 1 + target: + entity_id: + - light.bedroom_lights + action: light.turn_off + - conditions: + - condition: trigger + id: + - up + sequence: + - device_id: 171fa001578683249ff26f2d85817fef + domain: light + entity_id: 55d41329665f60a55a732c5bbececd22 + type: brightness_increase + - device_id: c92fea3d569ca668e6617a189f917a28 + domain: light + entity_id: 0c8630c2b37ae9615f9cf815aaebf40f + type: brightness_increase + - conditions: + - condition: trigger + id: + - down + sequence: + - device_id: 171fa001578683249ff26f2d85817fef + domain: light + entity_id: 55d41329665f60a55a732c5bbececd22 + type: brightness_decrease + - device_id: c92fea3d569ca668e6617a189f917a28 + domain: light + entity_id: 0c8630c2b37ae9615f9cf815aaebf40f + type: brightness_decrease + - conditions: + - condition: trigger + id: + - hold on + sequence: + - metadata: {} + data: + rgb_color: + - 255 + - 0 + - 0 + brightness_pct: 100 + target: + entity_id: light.bedroom_lights + action: light.turn_on + mode: single +- id: '1694441037420' + alias: Air Purifier Schedule + description: '' + trigger: + - platform: time + at: 07:00:00 + id: fan off + - platform: time + at: '23:00:00' + id: fan on + condition: [] + action: + - choose: + - conditions: + - condition: trigger + id: + - fan on + sequence: + - service: fan.set_percentage + data: + percentage: 100 + target: + entity_id: fan.bedroom_air_purifier + - conditions: + - condition: trigger + id: + - fan off + sequence: + - service: fan.set_preset_mode + data: + preset_mode: auto + target: + entity_id: fan.bedroom_air_purifier + mode: single +- id: '1705949582146' + alias: Ice Maker Power Schedule + description: '' + trigger: + - platform: time_pattern + hours: '*' + minutes: '0' + seconds: '0' + condition: [] + action: + - type: toggle + device_id: 41c66532e23aadc4c6ac95e520e5d345 + entity_id: bd17ac75a91e62ed7e6b148cfe33d43d + domain: switch + - alias: Set Ice Maker Light to Dim + device_id: 41c66532e23aadc4c6ac95e520e5d345 + domain: select + entity_id: 8f4f90c62b00df9008d14f7ce8967199 + type: select_option + option: 'On' + mode: single +- id: '1708978401738' + alias: Soundbar + description: '' + trigger: [] + condition: [] + action: + - service: media_player.turn_on + metadata: {} + data: {} + target: + entity_id: media_player.soundbar + - service: media_player.select_source + metadata: {} + data: + source: wifi + target: + entity_id: media_player.soundbar + - service: media_player.play_media + metadata: {} + data: + media_content_id: media-source://radio_browser/2eff3a1f-b821-4267-9f37-f8d7e72061e4 + media_content_type: audio/mpeg + target: + entity_id: media_player.soundbar + mode: single +- id: '1711147285926' + alias: Grow Light Schedule + description: '' + trigger: + - platform: time + at: 07:00:00 + id: day + - platform: time + at: '20:00:00' + id: night + condition: [] + action: + - choose: + - conditions: + - condition: trigger + id: + - day + sequence: + - service: switch.turn_on + metadata: {} + data: {} + target: + entity_id: switch.grow_lights + - conditions: + - condition: trigger + id: + - night + sequence: + - service: switch.turn_off + metadata: {} + data: {} + target: + entity_id: switch.grow_lights + mode: single +- id: '1723142554607' + alias: Restart Luci's Box + description: for some reason this box sucks and needs to get reboot periodically + trigger: + - platform: time_pattern + hours: '*' + condition: [] + action: + - type: turn_off + device_id: e7f8974c31567dddbbffb036fe8381bc + entity_id: e1e71e4acdfcbb6c4afdc174807ad8be + domain: switch + - delay: + hours: 0 + minutes: 0 + seconds: 1 + milliseconds: 0 + - type: turn_on + device_id: e7f8974c31567dddbbffb036fe8381bc + entity_id: e1e71e4acdfcbb6c4afdc174807ad8be + domain: switch + - type: turn_on + device_id: d5eb3c182a1ef2a231b94b09c26aed45 + entity_id: 7106df7ebde274ac4bc2b197d5c45bea + domain: fan + - device_id: d5eb3c182a1ef2a231b94b09c26aed45 + domain: number + entity_id: 59a7cd3cb2883bf6002f789c2ff4824c + type: set_value + value: 3 + mode: single +- id: '1724707092916' + alias: HASS Updates + description: '' + use_blueprint: + path: edwardtfn/auto_update_scheduled.yaml + input: + schedule_entity: schedule.updates + restart_bool: true +- id: '1724707291994' + alias: IOT Battery Checker + description: '' + use_blueprint: + path: sbyx/low-battery-level-detection-notification-for-all-battery-sensors.yaml + input: + exclude: + entity_id: [] + device_id: + - 66e9cee67a740e8925dae5fc9ce940f0 + - df76e3a3e48b49e13bd3006350826740 + actions: + - action: notify.persistent_notification + metadata: {} + data: + message: Device Battery Low +- id: '1729708621620' + alias: Closet Lights + description: '' + triggers: + - type: present + device_id: 0924cbdcd24416e768caa52301db59f7 + entity_id: e9f0acef50550033cd96155bd501b7c3 + domain: binary_sensor + trigger: device + for: + hours: 0 + minutes: 0 + seconds: 0 + id: Present + - type: not_present + device_id: 0924cbdcd24416e768caa52301db59f7 + entity_id: e9f0acef50550033cd96155bd501b7c3 + domain: binary_sensor + trigger: device + for: + hours: 0 + minutes: 0 + seconds: 0 + id: empty + conditions: [] + actions: + - choose: + - conditions: + - condition: trigger + id: + - Present + sequence: + - action: light.turn_on + metadata: {} + data: + transition: 3 + brightness_pct: 100 + kelvin: 5008 + target: + device_id: + - e25128ac8fcf62af66a039cde3104760 + - ddcfd5ea4fc5f5a88e18325b01c615db + - conditions: + - condition: trigger + id: + - empty + sequence: + - action: light.turn_off + metadata: {} + data: + transition: 3 + target: + device_id: + - e25128ac8fcf62af66a039cde3104760 + - ddcfd5ea4fc5f5a88e18325b01c615db + mode: single +- id: '1729881464325' + alias: Bedroom Closet + description: '' + triggers: + - type: present + device_id: 28e7f211c72409fe244183219abf6ffa + entity_id: aa474f323868586cef62070654f36936 + domain: binary_sensor + trigger: device + id: Present + - type: not_present + device_id: 28e7f211c72409fe244183219abf6ffa + entity_id: aa474f323868586cef62070654f36936 + domain: binary_sensor + trigger: device + id: empty + conditions: [] + actions: + - choose: + - conditions: + - condition: trigger + id: + - Present + sequence: + - type: turn_on + device_id: f5936d6143b7927433e9c0430c79acab + entity_id: f6ec42c9db2c191866a335a346b1ec44 + domain: switch + - conditions: + - condition: trigger + id: + - empty + sequence: + - type: turn_off + device_id: f5936d6143b7927433e9c0430c79acab + entity_id: f6ec42c9db2c191866a335a346b1ec44 + domain: switch + mode: single +- id: '1740179328446' + alias: Living Room Lights + description: '' + triggers: + - domain: mqtt + device_id: f7482a462dc7cc05b4ceaa0d882dc469 + type: action + subtype: off_press + trigger: device + id: 'off' + - domain: mqtt + device_id: f7482a462dc7cc05b4ceaa0d882dc469 + type: action + subtype: on_press + trigger: device + id: 'on' + - domain: mqtt + device_id: f7482a462dc7cc05b4ceaa0d882dc469 + type: action + subtype: up_press + trigger: device + id: up + - domain: mqtt + device_id: f7482a462dc7cc05b4ceaa0d882dc469 + type: action + subtype: down_press + trigger: device + id: down + - domain: mqtt + device_id: f7482a462dc7cc05b4ceaa0d882dc469 + type: action + subtype: on_hold + trigger: device + id: hold on + conditions: [] + actions: + - choose: + - conditions: + - condition: trigger + id: + - 'on' + sequence: + - data: + brightness_pct: 100 + color_temp_kelvin: 5000 + transition: 1 + action: light.turn_on + target: + entity_id: light.livingroom_lights + - conditions: + - condition: trigger + id: + - 'off' + sequence: + - data: + transition: 1 + action: light.turn_off + target: + entity_id: light.livingroom_lights + - conditions: + - condition: trigger + id: + - up + sequence: + - device_id: 8bc2033b03d5a474ca3204c5ca53e308 + domain: light + entity_id: 4a3cc9043ff985e9271683e1916bd9e1 + type: brightness_increase + - device_id: 8f4f51aed9b3b4284f520af25358efd9 + domain: light + entity_id: f45e74498c4b6bae65aaf5adf67e29d6 + type: brightness_increase + - conditions: + - condition: trigger + id: + - down + sequence: + - device_id: 8bc2033b03d5a474ca3204c5ca53e308 + domain: light + entity_id: 4a3cc9043ff985e9271683e1916bd9e1 + type: brightness_decrease + - device_id: 8bc2033b03d5a474ca3204c5ca53e308 + domain: light + entity_id: 4a3cc9043ff985e9271683e1916bd9e1 + type: brightness_decrease + - conditions: + - condition: trigger + id: + - hold on + sequence: + - metadata: {} + data: + rgb_color: + - 255 + - 0 + - 0 + brightness_pct: 100 + action: light.turn_on + target: + entity_id: light.livingroom_lights + mode: single diff --git a/hosts/homeassistant/configuration.nix b/hosts/homeassistant/configuration.nix new file mode 100644 index 0000000..438b791 --- /dev/null +++ b/hosts/homeassistant/configuration.nix @@ -0,0 +1,68 @@ +# Edit this configuration file to define what should be installed on +# your system. Help is available in the configuration.nix(5) man page, on +# https://search.nixos.org/options and in the NixOS manual (`nixos-help`). + +{ config, lib, pkgs, ... }: + +let + user = "hass"; + password = "$y$j9T$EkPXmsmIMFFZ.WRrBYCxS1$P0kwo6e4.WM5DsqUcEqWC3MrZp5KfCjxffraMFZWu06"; + SSID = "Joey's Jungle 5G"; + SSIDpassword = config.sops.templates."wifi-password".content; + interface = "wlan0"; + timezone = "America/Chicago"; + hostname = "jallen-hass"; +in +{ + imports = [ + # Include the results of the hardware scan. + ./boot.nix + ./hardware-configuration.nix + ./impermanence.nix + # ./sops.nix + # ./ups-monitor.nix + ../default.nix + ]; + + # Enable nix flakes and nix-command tools + nix.settings.experimental-features = [ + "nix-command" + "flakes" + ]; + + nix.settings.trusted-users = [ "@wheel" ]; + + # Set your time zone. + time.timeZone = timezone; + + networking = { + networkmanager.enable = lib.mkForce true; + hostName = hostname; + wireless = { + enable = false; + networks."${SSID}".psk = SSIDpassword; + interfaces = [ interface ]; + }; + }; + + environment.systemPackages = with pkgs; [ + vim + htop + git + ]; + + services.openssh.enable = true; + + users = { + mutableUsers = false; + users."${user}" = { + isNormalUser = true; + initialHashedPassword = password; + extraGroups = [ + "wheel" + "docker" + ]; + shell = pkgs.zsh; + }; + }; +} diff --git a/hosts/homeassistant/default.nix b/hosts/homeassistant/default.nix new file mode 100644 index 0000000..c3338e0 --- /dev/null +++ b/hosts/homeassistant/default.nix @@ -0,0 +1,188 @@ +{ config, pkgs, ... }: +let + # "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" + ha-bambulab = pkgs.stdenv.mkDerivation { + pname = "ha-bambulab"; + version = "v2.1.5"; # Update with correct version + + src = pkgs.fetchFromGitHub { + owner = "greghesp"; # Update with correct owner + repo = "ha-bambulab"; # Update with correct repo name + rev = "v2.1.5"; # Or specific tag/commit + sha256 = "sha256-giaQiCVblo3pgnZKCql6focjJJmLGLOSiar8tcEKrNc="; # Replace with actual hash + }; + + installPhase = '' + mkdir -p $out/custom_components + cp -r custom_components/bambu_lab $out/custom_components/ + ''; + }; + ha-gehome = pkgs.stdenv.mkDerivation { + pname = "ha-gehome"; + version = "v2025.2.1"; # Update with correct version + + src = pkgs.fetchFromGitHub { + owner = "simbaja"; # Update with correct owner + repo = "ha_gehome"; # Update with correct repo name + rev = "v2025.2.1"; # Or specific tag/commit + sha256 = "sha256-nb+KrJoWqvhqH6E7A22xXwQzTYp7yn+hl9WRDXn95Cc="; # Replace with actual hash + }; + + installPhase = '' + mkdir -p $out/custom_components + cp -r custom_components/ge_home $out/custom_components/ + ''; + }; + ha-mail-and-packages = pkgs.stdenv.mkDerivation { + pname = "Home-Assistant-Mail-And-Packages"; + version = "0.4.2"; # Update with correct version + + src = pkgs.fetchFromGitHub { + owner = "moralmunky"; # Update with correct owner + repo = "Home-Assistant-Mail-And-Packages"; # Update with correct repo name + rev = "0.4.2"; # Or specific tag/commit + sha256 = "sha256-5LBTlRlkSUx8DOY+F7UvUs4dzjZKdBdgnDUdK6DBdew="; # Replace with actual hash + }; + + installPhase = '' + mkdir -p $out/custom_components + cp -r custom_components/mail_and_packages $out/custom_components/ + ''; + }; + ha-overseerr = pkgs.stdenv.mkDerivation { + pname = "ha-overseerr"; + version = "0.1.42"; # Update with correct version + + src = pkgs.fetchFromGitHub { + owner = "vaparr"; # Update with correct owner + repo = "ha-overseerr"; # Update with correct repo name + rev = "0.1.42"; # Or specific tag/commit + sha256 = "sha256-UvUowCgfay9aRV+iC/AQ9vvJzhGZbH+/1kVjxPFBKcI="; # Replace with actual hash + }; + + installPhase = '' + mkdir -p $out/custom_components + cp -r custom_components/overseerr $out/custom_components/ + ''; + }; + ha-petlibro = pkgs.stdenv.mkDerivation { + pname = "ha-petlibro"; + version = "v1.0.21.1"; # Update with correct version + + src = pkgs.fetchzip { + url = "https://github.com/jjjonesjr33/petlibro/archive/refs/tags/v1.0.21.1.zip"; + sha256 = "sha256-3EckyAgWxlZeqy9g13yP2nKCcjnyVIp8EdiE/A1pNu4="; # Replace with actual hash + }; + + installPhase = '' + mkdir -p $out/custom_components + cp -r custom_components/petlibro $out/custom_components/ + ''; + }; + ha-wyzeapi = pkgs.stdenv.mkDerivation { + pname = "ha-wyzeapi"; + version = "0.1.32"; # Update with correct version + + src = pkgs.fetchzip { + url = "https://github.com/SecKatie/ha-wyzeapi/archive/refs/tags/0.1.32.zip"; + sha256 = "sha256-3xUynZBEHuO2hKLYCb2sBpJAe0JF/8uKqR304Y7JQmE="; # Replace with actual hash + }; + + installPhase = '' + mkdir -p $out/custom_components + cp -r custom_components/wyzeapi $out/custom_components/ + ''; + }; +in +{ + services.home-assistant = { + enable = true; + openFirewall = true; + extraComponents = [ + # Components required to complete the onboarding + "analytics" + "google_translate" + "met" + "radio_browser" + "shopping_list" + # Recommended for fast zlib compression + # https://www.home-assistant.io/integrations/isal + "isal" + "subaru" + "vesync" + ]; + customComponents = with pkgs.home-assistant-custom-components; [ + auth-header + ]; + # use postgresql instead of sqlite + extraPackages = ps: with ps; [ psycopg2 numpy hassil pyturbojpeg ]; + + config = { + # Includes dependencies for a basic setup + # https://www.home-assistant.io/integrations/default_config/ + default_config = {}; + + cloud = false; + + frontend = { + themes = "!include_dir_merge_named themes"; + }; + + "automation ui" = "!include automations.yaml"; + "scene ui" = "!include scenes.yaml"; + "script ui" = "!include scripts.yaml"; + + http = { + use_x_forwarded_for = true; + trusted_proxies = [ + "172.30.33.0/24" + "10.0.1.18" + ]; + }; + + recorder = { + db_url = "postgresql://@/hass"; + purge_keep_days = 180; + }; + + auth_header = { + debug = false; + }; + + # https://www.home-assistant.io/integrations/ota_updater/ + zha.zigpy_config.ota.z2m_remote_index = "https://raw.githubusercontent.com/Koenkk/zigbee-OTA/master/index.json"; + }; + }; + + # https://www.home-assistant.io/integrations/automation/ + # systemd.tmpfiles.rules = [ + # "f ${config.services.home-assistant.configDir}/automations.yaml 0755 hass hass" + # ]; + + # This bypasses the component validation and places it directly in HA's data directory + system.activationScripts.installCustomComponents = '' + mkdir -p ${config.services.home-assistant.configDir}/custom_components + cp -r ${ha-bambulab}/custom_components/bambu_lab ${config.services.home-assistant.configDir}/custom_components/ + cp -r ${ha-gehome}/custom_components/ge_home ${config.services.home-assistant.configDir}/custom_components/ + cp -r ${ha-mail-and-packages}/custom_components/mail_and_packages ${config.services.home-assistant.configDir}/custom_components/ + cp -r ${ha-overseerr}/custom_components/overseerr ${config.services.home-assistant.configDir}/custom_components/ + cp -r ${ha-petlibro}/custom_components/petlibro ${config.services.home-assistant.configDir}/custom_components/ + cp -r ${ha-wyzeapi}/custom_components/wyzeapi ${config.services.home-assistant.configDir}/custom_components/ + + ln -sf /etc/nixos/hosts/nas/apps/homeassistant/automations.yaml ${config.services.home-assistant.configDir}/automations.yaml + chown hass:hass ${config.services.home-assistant.configDir}/automations.yaml + ln -sf /etc/nixos/hosts/nas/apps/homeassistant/scenes.yaml ${config.services.home-assistant.configDir}/scenes.yaml + chown hass:hass ${config.services.home-assistant.configDir}/scenes.yaml + ln -sf /etc/nixos/hosts/nas/apps/homeassistant/scripts.yaml ${config.services.home-assistant.configDir}/scripts.yaml + chown hass:hass ${config.services.home-assistant.configDir}/scripts.yaml + ''; + + services.postgresql = { + enable = true; + ensureDatabases = [ "hass" ]; + ensureUsers = [{ + name = "hass"; + ensureDBOwnership = true; + }]; + }; +} \ No newline at end of file diff --git a/hosts/homeassistant/hardware-configuration.nix b/hosts/homeassistant/hardware-configuration.nix new file mode 100644 index 0000000..d560431 --- /dev/null +++ b/hosts/homeassistant/hardware-configuration.nix @@ -0,0 +1,70 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "none"; + fsType = "tmpfs"; + }; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/AB0D-A6A2"; + fsType = "vfat"; + options = [ "fmask=0022" "dmask=0022" ]; + }; + + fileSystems."/nix" = + { device = "/dev/disk/by-uuid/a6ef033d-c305-42d9-88b2-5591008b2a11"; + fsType = "btrfs"; + options = [ "subvol=nix" ]; + }; + + fileSystems."/etc" = + { device = "/dev/disk/by-uuid/a6ef033d-c305-42d9-88b2-5591008b2a11"; + fsType = "btrfs"; + options = [ "subvol=etc" ]; + }; + + fileSystems."/var/log" = + { device = "/dev/disk/by-uuid/a6ef033d-c305-42d9-88b2-5591008b2a11"; + fsType = "btrfs"; + options = [ "subvol=log" ]; + }; + + fileSystems."/root" = + { device = "/dev/disk/by-uuid/a6ef033d-c305-42d9-88b2-5591008b2a11"; + fsType = "btrfs"; + options = [ "subvol=root" ]; + }; + + fileSystems."/home" = + { device = "/dev/disk/by-uuid/a6ef033d-c305-42d9-88b2-5591008b2a11"; + fsType = "btrfs"; + options = [ "subvol=home" ]; + }; + + swapDevices = + [ { device = "/dev/disk/by-uuid/d631d42b-b70a-4579-bfb4-57412ae7c682"; } + ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.eno1.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} \ No newline at end of file diff --git a/hosts/homeassistant/home.nix b/hosts/homeassistant/home.nix new file mode 100644 index 0000000..546a622 --- /dev/null +++ b/hosts/homeassistant/home.nix @@ -0,0 +1,66 @@ +{ lib, pkgs, ... }: +let + shellAliases = { + ll = "ls -alh"; + update-boot = "sudo nixos-rebuild boot --max-jobs 10 --build-host admin@10.0.1.18"; + update-switch = "sudo nixos-rebuild switch --max-jobs 10 --build-host admin@10.0.1.18"; + update-flake = "sudo nix flake update ~/nix-config"; + update-nas = "nixos-rebuild switch --use-remote-sudo --target-host admin@10.0.1.18 --build-host admin@10.0.1.18 --flake ~/nix-config#jallen-nas"; + nas-ssh = "kitten ssh admin@10.0.1.18"; + ducks = "du -cksh * | sort -hr | head -n 15"; + }; + + gitAliases = { + co = "checkout"; + ci = "commit"; + cia = "commit --amend"; + s = "status"; + st = "status"; + b = "branch"; + p = "pull --rebase"; + pu = "push"; + }; +in +{ + + home.username = "hass"; + home.homeDirectory = "/home/hass"; + home.stateVersion = "23.11"; + programs.home-manager.enable = true; + + programs = { + fish.enable = false; + mangohud.enable = true; + java.enable = true; + + zsh = { + enable = true; + enableCompletion = true; + autosuggestion.enable = true; + syntaxHighlighting.enable = true; + + shellAliases = shellAliases; + + oh-my-zsh = { + enable = true; + plugins = [ "git" ]; + theme = "fishy"; + }; + }; + }; + + programs.git = { + enable = true; + userName = "mjallen18"; + userEmail = "matt.l.jallen@gmail.com"; + aliases = gitAliases; + }; + + programs.command-not-found.enable = true; + + home.packages = with pkgs; [ + age + fastfetch + firefox + ]; +} diff --git a/hosts/homeassistant/impermanence.nix b/hosts/homeassistant/impermanence.nix new file mode 100644 index 0000000..0badb51 --- /dev/null +++ b/hosts/homeassistant/impermanence.nix @@ -0,0 +1,54 @@ +{ ... }: +{ + # Set up impernance configuration for things like bluetooth + # In this configuration with /etc and /var/log being persistent, only directories outside of that need to be done here. See hardware configuration for all mountpoints. + + environment.persistence."/nix/persist/system" = { + hideMounts = true; + directories = [ + "/var/lib/bluetooth" + "/var/lib/nixos" + "/var/lib/tailscale" + "/var/lib/systemd/coredump" + "/etc/NetworkManager/system-connections" + "/etc/secureboot" + { + directory = "/var/lib/private/authentik/media"; + user = "authentik"; + group = "authentik"; + mode = "u=rwx,g=,o="; + } + { + directory = "/var/lib/hass"; + user = "hass"; + group = "hass"; + mode = "u=rwx,g=,o="; + } + { + directory = "/var/lib/private"; + mode = "u=rwx,g=rx,o="; + } + { + directory = "/var/lib/colord"; + user = "colord"; + group = "colord"; + mode = "u=rwx,g=rx,o="; + } + { + directory = "/etc/nix"; + user = "root"; + group = "wheel"; + mode = "u=rwx,g=rx,o=rx"; + } + ]; + files = [ + "/var/cache-priv-key.pem" + "/etc/machine-id" + ]; + }; + + security.sudo.extraConfig = '' + # rollback results in sudo lectures after each reboot + Defaults lecture = never + ''; +} diff --git a/hosts/homeassistant/scenes.yaml b/hosts/homeassistant/scenes.yaml new file mode 100644 index 0000000..e69de29 diff --git a/hosts/homeassistant/scripts.yaml b/hosts/homeassistant/scripts.yaml new file mode 100644 index 0000000..e69de29 diff --git a/hosts/nas/apps.nix b/hosts/nas/apps.nix index 54ba60e..6e13a9f 100644 --- a/hosts/nas/apps.nix +++ b/hosts/nas/apps.nix @@ -14,6 +14,8 @@ ./apps/netdata ./apps/collabora + + ./apps/homeassistant ]; nas-apps = { diff --git a/hosts/nas/apps/homeassistant/default.nix b/hosts/nas/apps/homeassistant/default.nix deleted file mode 100644 index 9f5cb7c..0000000 --- a/hosts/nas/apps/homeassistant/default.nix +++ /dev/null @@ -1,54 +0,0 @@ -{ config, pkgs, ... }: -{ - homeassistant = { - enable = true; - extraComponents = [ - # Components required to complete the onboarding - "analytics" - "google_translate" - "met" - "radio_browser" - "shopping_list" - # Recommended for fast zlib compression - # https://www.home-assistant.io/integrations/isal - "isal" - ]; - customComponents = with pkgs.home-assistant-custom-components; [ - auth-header - # bambulab - # ge_home - # mail_and_packages - # overseerr - # petlibro - # subaru - # vesync - # wyze-api - ]; - # use postgresql instead of sqlite - extraPackages = ps: with ps; [ psycopg2 ]; - config.recorder.db_url = "postgresql://@/hass"; - config = { - "automation ui" = "!include automations.yaml"; - "scene ui" = "!include scenes.yaml"; - "script ui" = "!include scripts.yaml"; - # https://www.home-assistant.io/integrations/ota_updater/ - zha.zigpy_config.ota.z2m_remote_index = "https://raw.githubusercontent.com/Koenkk/zigbee-OTA/master/index.json"; - }; - }; - - # https://www.home-assistant.io/integrations/automation/ - systemd.tmpfiles.rules = [ - "f ${config.services.home-assistant.configDir}/automations.yaml 0755 hass hass" - ]; - - - services.postgresql = { - enable = true; - dataDir = "/media/nas/ssd/nix-apps/postgresql"; - ensureDatabases = [ "hass" ]; - ensureUsers = [{ - name = "hass"; - ensureDBOwnership = true; - }]; - }; -} \ No newline at end of file