hswaw/machines: add sound.waw.hackerspace.pl

Change-Id: Id0e6a02d9ae4cf61d758713a99d21c6da0c72b66
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/1401
Reviewed-by: vuko <vuko@hackerspace.pl>
Reviewed-by: informatic <informatic@hackerspace.pl>
diff --git a/hswaw/machines/sound.waw.hackerspace.pl/configuration.nix b/hswaw/machines/sound.waw.hackerspace.pl/configuration.nix
new file mode 100644
index 0000000..fccd656
--- /dev/null
+++ b/hswaw/machines/sound.waw.hackerspace.pl/configuration.nix
@@ -0,0 +1,214 @@
+{ config, pkgs, ... }:
+
+let
+  hw = builtins.fromJSON (builtins.readFile ./hw.json);
+  ssh-keys = {
+    vuko = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFhaCaC/CVYv6hphqmEdKaPrIn+Q946+myvL9SSnzFZk vuko@eagle";
+    informatic = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDoKB2p/gFaKthQNXeQvSLzhOlLSq3vjVL3AEOBTMXGH informatic@atuin";
+  };
+  networks = {
+    lan = {
+      description = "LAN";
+      hw_addr = "4c:52:62:ba:a9:78";
+      ipv4 = "10.8.1.26";
+      #ipv6 = "2a0d:eb00:4242::1";
+    };
+  };
+
+  system-vim = pkgs.vim_configurable.customize {
+      name = "vim";
+      vimrcConfig.packages.myplugins = with pkgs.vimPlugins; {
+        start = [ vim-nix vim-lastplace ];
+        opt = [];
+      };
+      vimrcConfig.customRC = ''
+        set nocompatible
+      '';
+    };
+
+
+in {
+  imports =
+    [
+      ./hardware-configuration.nix
+    ];
+
+  boot.loader.systemd-boot.enable = true;
+  boot.loader.efi.canTouchEfiVariables = true;
+
+  time.timeZone = "Europe/Warsaw";
+
+  fileSystems."/" = {
+    device = "/dev/disk/by-partuuid/${hw.rootUUID}";
+    fsType = "ext4";
+  };
+
+  networking.hostName = "newsound";
+  networking.domain = "waw.hackerspace.pl";
+  networking.useDHCP = false;
+
+  networking.defaultGateway = {
+    address = "10.8.1.2";
+    interface = "lan";
+  };
+
+  networking.interfaces = {
+      lan = {
+          ipv4.addresses = [
+            {
+              address = networks.lan.ipv4;
+              prefixLength = 16;
+            }
+          ];
+      };
+  };
+
+  networking.nameservers = ["10.8.1.2"];
+
+  services.acpid.enable = true;
+
+  # TODO copy acls and paswords from old sound
+  services.mosquitto.enable = true;
+  services.mosquitto.listeners = [
+    {
+      settings.allow_anonymous = true;
+    }
+  ];
+
+  services.home-assistant = {
+    enable = true;
+    config = import ./home-assistant.nix;
+
+    # TODO if some components / packages are not needed
+    extraComponents = [
+        "default_config"
+        "mqtt"
+        "met"
+        "media_player"
+        "light"
+        "frontend"
+        "cast"
+        "spotify"
+    ];
+    extraPackages = ps: [
+        ps.aiohttp-cors
+        ps.pillow
+        ps.sqlalchemy
+        ps.websockets
+        ps.fnvhash
+        ps.hass-nabucasa
+        ps.pymetno
+        ps.radios
+    ];
+  };
+
+  sound.enable = true;
+
+  # TODO create config that setups volume, default output etc.
+  hardware.pulseaudio = {
+    enable = true;
+    systemWide = true;
+    zeroconf.publish.enable = true;
+
+    tcp.enable = true;
+    tcp.anonymousClients.allowAll = true;
+  };
+
+  services.nginx = {
+      enable = true;
+      virtualHosts = {
+      "iot.waw.hackerspace.pl" = {
+        serverAliases = ["default_server"];
+        listen = [
+          {
+            addr = networks.lan.ipv4;
+            port = 80;
+            ssl = false;
+          }
+        ];
+        locations."/" = {
+            extraConfig = ''
+              proxy_set_header Upgrade $http_upgrade;
+              proxy_set_header Connection $http_connection;
+              proxy_set_header Host $host;
+              proxy_set_header X-Real-IP $remote_addr;
+              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+              proxy_set_header X-Forwarded-Host $host:$server_port;
+              proxy_set_header X-Forwarded-Server $host;
+              proxy_set_header X-Forwarded-Proto $scheme;
+            '';
+            proxyPass = "http://localhost:8123";
+          };
+        };
+      };
+    };
+
+
+  systemd.network.links = builtins.listToAttrs (map (
+    name: { name = "10-link-${name}"; value = {
+      enable = true;
+      matchConfig = {
+        MACAddress = networks."${name}".hw_addr;
+      };
+      linkConfig = {
+        Name = "${name}";
+      };
+    }; }
+  ) (builtins.filter (name: builtins.hasAttr "hw_addr" networks."${name}") (builtins.attrNames networks)));
+
+  networking.firewall = {
+    enable = true;
+    allowedTCPPorts = [
+        22 # ssh
+        80 # nginx http
+        1883 # mqtt (mosquitto)
+        4713 # pulseaudo
+    ];
+  };
+
+  services.openssh = {
+    enable = true;
+    passwordAuthentication = false;
+  };
+
+  # TODO extract ssh keys synchronization from customs and add it here
+  users.users.root.openssh.authorizedKeys.keys = [ ssh-keys.vuko ssh-keys.informatic ];
+
+  environment.systemPackages = with pkgs; [
+    system-vim tcpdump htop nmon tmux git file procps parted dmidecode ack utillinux
+    nmap mosh ncdu tree lz4 bind neovim hdparm usbutils
+  ];
+
+  programs.mtr.enable = true;
+
+  environment.variables = {
+    EDITOR = "vim";
+  };
+
+  #environment.extraInit = ''
+  #  export NIX_PATH="nixpkgs=${config.channel-sources.nixpkgs}";
+  #'';
+
+  environment.etc."inputrc" = {
+    text = pkgs.lib.mkDefault( pkgs.lib.mkAfter ''
+      set colored-stats on
+      set show-all-if-ambiguous on
+      set completion-ignore-case on
+
+      # arrow up
+      "\e[A": history-search-backward
+      # arrow down
+      "\e[B": history-search-forward
+
+      "\e[5~": history-search-backward
+      "\e[6~": history-search-forward
+    '');
+  };
+
+  system.stateVersion = "22.05";
+
+
+  boot.vesa = false;
+  boot.loader.grub.splashImage = null;
+}
+
diff --git a/hswaw/machines/sound.waw.hackerspace.pl/hardware-configuration.nix b/hswaw/machines/sound.waw.hackerspace.pl/hardware-configuration.nix
new file mode 100644
index 0000000..bd8709d
--- /dev/null
+++ b/hswaw/machines/sound.waw.hackerspace.pl/hardware-configuration.nix
@@ -0,0 +1,19 @@
+# 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 = [ "ahci" "xhci_pci" "usb_storage" "sd_mod" ];
+  boot.initrd.kernelModules = [ ];
+  boot.kernelModules = [ "kvm-intel" ];
+  boot.extraModulePackages = [ ];
+
+  swapDevices = [ ];
+
+  powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
+}
diff --git a/hswaw/machines/sound.waw.hackerspace.pl/home-assistant.nix b/hswaw/machines/sound.waw.hackerspace.pl/home-assistant.nix
new file mode 100644
index 0000000..468f5e5
--- /dev/null
+++ b/hswaw/machines/sound.waw.hackerspace.pl/home-assistant.nix
@@ -0,0 +1,289 @@
+{
+  default_config = {};
+
+  homeassistant = {
+    auth_providers = [
+      {
+        type = "homeassistant";
+      }
+      {
+        type = "trusted_networks";
+        trusted_networks = ["127.0.0.1" "::1" "10.0.0.0/8" "fd00::/8"];
+        allow_bypass_login = true;
+      }
+    ];
+    customize = {
+      "light.left_par_brightness" = {hidden = true;};
+      "light.right_par_brightness" = {hidden = true;};
+      "switch.portable_spejsiot_node_b4a90f" = {icon = "mdi:power-plug";};
+      "switch.projection_screen" = {icon = "mdi:projector-screen";};
+      "switch.projector" = {icon = "mdi:projector";};
+      "switch.samsung_tv_mute" = {icon = "mdi:volume-off";};
+      "switch.samsung_tv_telelele" = {icon = "mdi:monitor";};
+      "switch.space_heater" = {icon = "mdi:fire";};
+    };
+    customize_glob = {"media_player.m*" = {custom_ui_state_card = "state-card-mini-media-player";};};
+    elevation = "106";
+    latitude = "52.25";
+    longitude = "21";
+    name = "Warsaw Hackerspace";
+    time_zone = "Europe/Warsaw";
+    unit_system = "metric";
+  };
+
+  http = {
+    use_x_forwarded_for = true;
+    trusted_proxies = [ "127.0.0.1" "::1" ];
+  };
+
+  automation = [
+    {
+      action = {
+        data_template = {
+          payload = "{{ states('input_number.polycom_hdmi_gain') }}";
+          retain = true;
+          topic = "iot/polycom/hdmi:main/gain/set";
+        };
+        service = "mqtt.publish";
+      };
+      hide_entity = true;
+      trigger = {
+        entity_id = "input_number.polycom_hdmi_gain";
+        platform = "state";
+      };
+    }
+    {
+      action = {
+        data_template = {
+          payload = "{{ states('input_number.polycom_aux1_gain') }}";
+          retain = true;
+          topic = "iot/polycom/aux1:main/gain/set";
+        };
+        service = "mqtt.publish";
+      };
+      hide_entity = true;
+      trigger = {
+        entity_id = "input_number.polycom_aux1_gain";
+        platform = "state";
+      };
+    }
+    {
+      action = {
+        data_template = {
+          payload = "{{ states.input_select.hdmi_source_a.attributes['options'].index(states('input_select.hdmi_source_a')) }}";
+          retain = true;
+          topic = "iot/3c189c/matrix/sourceA/set";
+        };
+        service = "mqtt.publish";
+      };
+      hide_entity = true;
+      trigger = {
+        entity_id = "input_select.hdmi_source_a";
+        platform = "state";
+      };
+    }
+    {
+      action = {
+        data_template = {
+          payload = "{{ states.input_select.hdmi_source_b.attributes['options'].index(states('input_select.hdmi_source_b')) }}";
+          retain = true;
+          topic = "iot/3c189c/matrix/sourceB/set";
+        };
+        service = "mqtt.publish";
+      };
+      hide_entity = true;
+      trigger = {
+        entity_id = "input_select.hdmi_source_b";
+        platform = "state";
+      };
+    }
+    {
+      action = {
+        data = {
+          entity_id = "input_select.hdmi_source_b";
+          option = "Input 1 / Kolumna";
+        };
+        service = "input_select.select_option";
+      };
+      alias = "Switch projector on HDMI1 connect";
+      trigger = {
+        payload = "true";
+        platform = "mqtt";
+        topic = "iot/3c189c/matrix/rx1_online";
+      };
+    }
+    {
+      action = {
+        data = {
+          entity_id = "input_select.hdmi_source_b";
+          option = "Chromecast";
+        };
+        service = "input_select.select_option";
+      };
+      alias = "Switch projector on HDMI1 disconnect";
+      trigger = {
+        payload = "false";
+        platform = "mqtt";
+        topic = "iot/3c189c/matrix/rx1_online";
+      };
+    }
+    {
+      action = {
+        data_template = {
+          payload = "{{ states('input_number.heater_fan_speed') }}";
+          retain = true;
+          topic = "iot/ab20d2/heater/fan/set";
+        };
+        service = "mqtt.publish";
+      };
+      hide_entity = true;
+      trigger = {
+        entity_id = "input_number.heater_fan_speed";
+        platform = "state";
+      };
+    }
+  ];
+
+  cast = {media_player = [{host = "10.8.1.44";}];};
+
+  # TODO fix and enable
+  #frontend = {
+  #  extra_html_url = ["/local/custom_ui/state-card-mini-media-player.html"];
+  #  extra_html_url_es5 = ["/local/custom_ui/state-card-mini-media-player_es5.html"];
+  #};
+
+  group = {
+    av = {
+      control = "hidden";
+      entities = ["switch.projector" "switch.projection_screen" "input_select.hdmi_source_a" "input_number.polycom_hdmi_gain" "switch.samsung_tv_telelele" "switch.samsung_tv_mute" "input_select.hdmi_source_b" "input_number.polycom_aux1_gain" "switch.aux1_gain_mic" "media_player.mpd"];
+      name = "HackAV";
+    };
+    heater = {
+      control = "hidden";
+      entities = ["switch.space_heater" "input_number.heater_fan_speed"];
+      name = "Heater";
+    };
+  };
+  input_number = {
+    heater_fan_speed = {
+      max = 100;
+      min = 0;
+      name = "Fan Speed";
+      step = 1;
+    };
+    polycom_aux1_gain = {
+      max = 10;
+      min = -40;
+      name = "AUX1 Audio Gain";
+      step = 1;
+    };
+    polycom_hdmi_gain = {
+      max = 0;
+      min = -40;
+      name = "HDMI Audio Gain";
+      step = 1;
+    };
+  };
+  input_select = {
+    hdmi_source_b = {
+      name = "Projector HDMI Source (Conn A/TX1)";
+      options = ["PS3" "Input 1 / Kolumna" "Unused" "Chromecast"];
+    };
+  };
+
+  media_player = [
+    {
+      host = "10.8.1.16";
+      platform = "mpd";
+    }
+  ];
+
+  mqtt = {
+    light = [
+      {
+        command_topic = "iot/077521/relay/on/set";
+        name = "Main room";
+        payload_off = "false";
+        payload_on = "true";
+        retain = true;
+        state_topic = "iot/077521/relay/on";
+      }
+    ];
+    fan = [
+      {
+        command_topic = "iot/c0dbe7/relay/on/set";
+        name = "Wyciąg";
+        payload_off = "false";
+        payload_on = "true";
+        retain = true;
+        state_topic = "iot/c0dbe7/relay/on";
+      }
+    ];
+    sensor = [
+      {
+        name = "DCR01 Temperature";
+        qos = 0;
+        state_topic = "iot/3394f5/environment/degree";
+        unit_of_measurement = "ºC";
+      }
+      {
+        name = "DCR01 Humidity";
+        qos = 0;
+        state_topic = "iot/3394f5/environment/humidity";
+        unit_of_measurement = "%";
+      }
+    ];
+    switch = [
+      {
+        command_topic = "iot/b4a90f/relay/on/set";
+        name = "Portable SpejsIoT node (b4a90f)";
+        payload_off = "false";
+        payload_on = "true";
+        retain = true;
+        state_topic = "iot/b4a90f/relay/on";
+      }
+      {
+        command_topic = "iot/d106e1/screen/down/set";
+        name = "Projection screen";
+        payload_off = "false";
+        payload_on = "true";
+        retain = true;
+        state_topic = "iot/d106e1/screen/down";
+      }
+      {
+        command_topic = "iot/craptrap/windows10/state/set";
+        name = "Windows 10 VM (Craptrap)";
+        payload_off = "pmsuspended";
+        payload_on = "running";
+        state_topic = "iot/craptrap/windows10/state";
+      }
+      {
+        command_topic = "iot/ab20d2/heater/on/set";
+        name = "Space Heater";
+        payload_off = "false";
+        payload_on = "true";
+        retain = true;
+        state_topic = "iot/ab20d2/heater/on";
+      }
+    ];
+  };
+
+  scene = [
+    {
+      entities = {
+        "light.main_room" = false;
+        "switch.projection_screen" = true;
+        "switch.projector" = true;
+      };
+      name = "Cinema";
+    }
+    {
+      entities = {
+        "light.main_room" = true;
+        "switch.projection_screen" = false;
+        "switch.projector" = false;
+      };
+      name = "Standard";
+    }
+  ];
+}
diff --git a/hswaw/machines/sound.waw.hackerspace.pl/hw.json b/hswaw/machines/sound.waw.hackerspace.pl/hw.json
new file mode 100644
index 0000000..c915106
--- /dev/null
+++ b/hswaw/machines/sound.waw.hackerspace.pl/hw.json
@@ -0,0 +1 @@
+{"rootUUID": "77a096b7-3e3b-1040-957e-1e2094d0dd54"}