diff options
24 files changed, 625 insertions, 513 deletions
diff --git a/krebs/1systems/puyak/config.nix b/krebs/1systems/puyak/config.nix index 9ee61c6f8..e41488cc3 100644 --- a/krebs/1systems/puyak/config.nix +++ b/krebs/1systems/puyak/config.nix @@ -1,12 +1,16 @@ { config, pkgs, ... }: - { imports = [ + ./net.nix <stockholm/krebs> <stockholm/krebs/2configs> <stockholm/krebs/2configs/secret-passwords.nix> <stockholm/krebs/2configs/hw/x220.nix> + # see documentation in included getty-for-esp.nix: + # brain hosts/puyak/root + <stockholm/krebs/2configs/hw/getty-for-esp.nix> + ## initrd unlocking # (brain hosts/puyak/luks-ssd;echo) | ssh root@$(brain krebs-secrets/puyak/initrd/hostname) 'cat > /crypt-ramfs/passphrase' @@ -118,7 +122,6 @@ krebs.build.host = config.krebs.hosts.puyak; sound.enable = false; - boot = { loader.systemd-boot.enable = true; loader.efi.canTouchEfiVariables = true; @@ -163,10 +166,6 @@ services.logind.lidSwitchExternalPower = "ignore"; - services.udev.extraRules = '' - SUBSYSTEM=="net", ATTR{address}=="8c:70:5a:b2:84:58", NAME="wl0" - SUBSYSTEM=="net", ATTR{address}=="3c:97:0e:07:b9:14", NAME="et0" - ''; environment.systemPackages = [ pkgs.zsh ]; @@ -179,5 +178,4 @@ isNormalUser = true; shell = "/run/current-system/sw/bin/zsh"; }; - networking.firewall.allowedTCPPorts = [ 5901 ]; } diff --git a/krebs/1systems/puyak/net.nix b/krebs/1systems/puyak/net.nix new file mode 100644 index 000000000..4cb8d247c --- /dev/null +++ b/krebs/1systems/puyak/net.nix @@ -0,0 +1,23 @@ +let + ext-if = "enp0s25"; + shack-ip = "10.42.22.184"; + shack-gw = "10.42.20.1"; +in { + services.udev.extraRules = '' + SUBSYSTEM=="net", ATTR{address}=="8c:70:5a:b2:84:58", NAME="wl0" + SUBSYSTEM=="net", ATTR{address}=="3c:97:0e:07:b9:14", NAME="et0" + ''; + networking = { + firewall.enable = false; + firewall.allowedTCPPorts = [ 8088 8086 8083 5901 ]; + interfaces."${ext-if}".ipv4.addresses = [ + { + address = shack-ip; + prefixLength = 20; + } + ]; + + defaultGateway = shack-gw; + nameservers = [ "10.42.0.100" "10.42.0.200" ]; + }; +} diff --git a/krebs/2configs/hw/getty-for-esp.nix b/krebs/2configs/hw/getty-for-esp.nix new file mode 100644 index 000000000..18c912353 --- /dev/null +++ b/krebs/2configs/hw/getty-for-esp.nix @@ -0,0 +1,17 @@ +{ + # 1. Program an esp8266 devboard (esp8266+usb-ttl) with # https://github.com/jeelabs/esp-link + # tested vesion: esp-link v3.2.47-g9c6530d + # Pin Preset: esp-bridge + # tx-enable: false + # uart-pins: normal + # 2. connect directly with usb-cable to device, check that vendorID and ProductID match + # 3. nc <esp-link-ip> 23 + # Info: for puyak the root pw is `brain hosts/puyak/root` + services.udev.extraRules = '' + SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="ilo", MODE="0660" + ''; + systemd.services."serial-getty@ilo".enable = true; + systemd.services."serial-getty@ilo".wantedBy = [ "multi-user.target" ]; + systemd.services."serial-getty@ilo".serviceConfig.Restart = "always"; +} + diff --git a/krebs/2configs/shack/gitlab-runner.nix b/krebs/2configs/shack/gitlab-runner.nix index ecb064579..d525e7987 100644 --- a/krebs/2configs/shack/gitlab-runner.nix +++ b/krebs/2configs/shack/gitlab-runner.nix @@ -1,5 +1,6 @@ { pkgs,lib, ... }: { + boot.kernel.sysctl."net.ipv4.ip_forward" = true; services.gitlab-runner = { enable = true; services= { @@ -17,6 +18,7 @@ "/nix/var/nix/daemon-socket:/nix/var/nix/daemon-socket:ro" ]; dockerDisableCache = true; + # TODO: use the channel from <stockholm/krebs/nixpkgs.json> preBuildScript = pkgs.writeScript "setup-container" '' mkdir -p -m 0755 /nix/var/log/nix/drvs mkdir -p -m 0755 /nix/var/nix/gcroots @@ -28,9 +30,9 @@ mkdir -p -m 0755 /nix/var/nix/profiles/per-user/root mkdir -p -m 0700 "$HOME/.nix-defexpr" . ${pkgs.nix}/etc/profile.d/nix.sh - ${pkgs.nix}/bin/nix-env -i ${concatStringsSep " " (with pkgs; [ nix cacert git openssh ])} - ${pkgs.nix}/bin/nix-channel --add https://nixos.org/channels/nixpkgs-unstable + ${pkgs.nix}/bin/nix-channel --add https://nixos.org/channels/nixos-20.09 nixpkgs ${pkgs.nix}/bin/nix-channel --update nixpkgs + ${pkgs.nix}/bin/nix-env -i ${concatStringsSep " " (with pkgs; [ nix cacert git openssh ])} ''; environmentVariables = { ENV = "/etc/profile"; diff --git a/krebs/2configs/shack/glados/automation/hass-restart.nix b/krebs/2configs/shack/glados/automation/hass-restart.nix index 1b380204d..5f61e19f1 100644 --- a/krebs/2configs/shack/glados/automation/hass-restart.nix +++ b/krebs/2configs/shack/glados/automation/hass-restart.nix @@ -1,21 +1,24 @@ # needs: # light.fablab_led -[ - { alias = "State on HA start-up"; - trigger = { - platform = "homeassistant"; - event = "start"; - }; - # trigger good/bad air - action = [ - { service = "light.turn_on"; - data = { - entity_id = "light.fablab_led"; - effect = "Rainbow"; - color_name = "purple"; - }; - } - ]; - } -] +{ + services.home-assistant.config.automation = + [ + { alias = "State on HA start-up"; + trigger = { + platform = "homeassistant"; + event = "start"; + }; + # trigger good/bad air + action = [ + { service = "light.turn_on"; + data = { + entity_id = "light.fablab_led"; + effect = "Rainbow"; + color_name = "purple"; + }; + } + ]; + } + ]; +} diff --git a/krebs/2configs/shack/glados/automation/party-time.nix b/krebs/2configs/shack/glados/automation/party-time.nix index dfa42d05c..9e7fe24cd 100644 --- a/krebs/2configs/shack/glados/automation/party-time.nix +++ b/krebs/2configs/shack/glados/automation/party-time.nix @@ -6,24 +6,27 @@ let disko_schalter = "switch.lounge_diskoschalter_relay"; player = "media_player.lounge"; in -[ - { alias = "Party um 21 Uhr"; - trigger = { - platform = "sun"; - event = "sunset"; - }; - action = - ( glados.say.kiosk "Die Sonne geht unter. Und jetzt geht die Party im shack erst richtig los. Partybeleuchtung, aktiviert!" ) - ++ - [ - { - service = "homeassistant.turn_on"; - entity_id = disko_schalter; - } - { - service = "media_player.turn_on"; - data.entity_id = player; - } # TODO: also start playlist if nothing is running? - ]; - } -] +{ + services.home-assistant.config.automation = + [ + { alias = "Party um 21 Uhr"; + trigger = { + platform = "sun"; + event = "sunset"; + }; + action = + ( glados.say.kiosk "Die Sonne geht unter. Und jetzt geht die Party im shack erst richtig los. Partybeleuchtung, aktiviert!" ) + ++ + [ + { + service = "homeassistant.turn_on"; + entity_id = disko_schalter; + } + { + service = "media_player.turn_on"; + data.entity_id = player; + } # TODO: also start playlist if nothing is running? + ]; + } + ]; +} diff --git a/krebs/2configs/shack/glados/automation/shack-startup.nix b/krebs/2configs/shack/glados/automation/shack-startup.nix index ac7dd4f1e..471d817a2 100644 --- a/krebs/2configs/shack/glados/automation/shack-startup.nix +++ b/krebs/2configs/shack/glados/automation/shack-startup.nix @@ -13,85 +13,88 @@ let glados = import ../lib; in -[ - { - alias = "Bedanken bei Übernahme von Key"; - initial_state = true; - trigger = { - platform = "state"; - entity_id = "sensor.keyholder"; - }; - condition = { - condition = "template"; - value_template = "{{ (trigger.from_state.state != 'No Keyholder') and (trigger.from_state.state != 'No Keyholder') }}"; - }; - action = glados.say.kiosk "Danke {{ trigger.to_state.state }} für das Übernehmen des Keys von {{ trigger.from_state.state }}"; - } - { - alias = "Keyholder Begrüßen wenn MPD hoch fährt"; - initial_state = true; - trigger = { - platform = "state"; - from = "unavailable"; - entity_id = "media_player.kiosk"; - }; - action = glados.say.kiosk (builtins.readFile ./announcement.j2); - } - { - alias = "Start Music on portal lock on"; - trigger = { - platform = "state"; - entity_id = "binary_sensor.portal_lock"; - to = "on"; - for.seconds = 30; - }; - condition = { - condition = "and"; - conditions = - [ - { # only start if a keyholder opened the door and if the lounge mpd is currently not playing anything - condition = "template"; - value_template = "{{ state('sensor.keyholder') != 'No Keyholder' }}"; - } - { - condition = "state"; - entity_id = "media_player.lounge"; - state = "idle"; - } - ]; - }; - action = [ - { - service = "media_player.volume_set"; - data = { +{ + services.home-assistant.config.automation = + [ + { + alias = "Bedanken bei Übernahme von Key"; + initial_state = true; + trigger = { + platform = "state"; + entity_id = "sensor.keyholder"; + }; + condition = { + condition = "template"; + value_template = "{{ (trigger.from_state.state != 'No Keyholder') and (trigger.from_state.state != 'No Keyholder') }}"; + }; + action = glados.say.kiosk "Danke {{ trigger.to_state.state }} für das Übernehmen des Keys von {{ trigger.from_state.state }}"; + } + { + alias = "Keyholder Begrüßen wenn MPD hoch fährt"; + initial_state = true; + trigger = { + platform = "state"; + from = "unavailable"; + entity_id = "media_player.kiosk"; + }; + action = glados.say.kiosk (builtins.readFile ./announcement.j2); + } + { + alias = "Start Music on portal lock on"; + trigger = { + platform = "state"; + entity_id = "binary_sensor.portal_lock"; + to = "on"; + for.seconds = 30; + }; + condition = { + condition = "and"; + conditions = + [ + { # only start if a keyholder opened the door and if the lounge mpd is currently not playing anything + condition = "template"; + value_template = "{{ state('sensor.keyholder') != 'No Keyholder' }}"; + } + { + condition = "state"; entity_id = "media_player.lounge"; - volume_level = 1.0; - }; - } - { - service = "media_player.play_media"; - data = { - entity_id = "media_player.lounge"; - media_content_type = "playlist"; - media_content_id = "ansage"; - }; - } - { delay.seconds = 8.5; } - { - service = "media_player.volume_set"; - data = { - entity_id = "media_player.lounge"; - volume_level = 0.6; - }; - } - { - service = "media_player.play_media"; - data = { - entity_id = "media_player.lounge"; - media_content_type = "playlist"; - media_content_id = "lassulus"; - }; - } - ]; - } -] + state = "idle"; + } + ]; + }; + action = [ + { + service = "media_player.volume_set"; + data = { + entity_id = "media_player.lounge"; + volume_level = 1.0; + }; + } + { + service = "media_player.play_media"; + data = { + entity_id = "media_player.lounge"; + media_content_type = "playlist"; + media_content_id = "ansage"; + }; + } + { delay.seconds = 8.5; } + { + service = "media_player.volume_set"; + data = { + entity_id = "media_player.lounge"; + volume_level = 0.6; + }; + } + { + service = "media_player.play_media"; + data = { + entity_id = "media_player.lounge"; + media_content_type = "playlist"; + media_content_id = "lassulus"; + }; + } + ]; + } + ]; +} diff --git a/krebs/2configs/shack/glados/default.nix b/krebs/2configs/shack/glados/default.nix index 04843cb24..d546564c5 100644 --- a/krebs/2configs/shack/glados/default.nix +++ b/krebs/2configs/shack/glados/default.nix @@ -1,9 +1,5 @@ { config, pkgs, lib, ... }: let - shackopen = import ./multi/shackopen.nix; - wasser = import ./multi/wasser.nix; - badair = import ./multi/schlechte_luft.nix; - rollos = import ./multi/rollos.nix; in { services.nginx.virtualHosts."hass.shack" = { serverAliases = [ "glados.shack" ]; @@ -21,14 +17,28 @@ in { ''; }; }; + imports = [ + ./multi/shackopen.nix + ./multi/wasser.nix + ./multi/schlechte_luft.nix + ./multi/rollos.nix + + ./switch/power.nix + + ./sensors/power.nix + ./sensors/mate.nix + ./sensors/darksky.nix + ./sensors/spaceapi.nix + ./sensors/sensemap.nix + + ./automation/shack-startup.nix + ./automation/party-time.nix + ./automation/hass-restart.nix + + ]; services.home-assistant = { enable = true; - package = pkgs.home-assistant.override { - extraPackages = ps: with ps; [ - python-forecastio jsonrpc-async jsonrpc-websocket mpd2 pkgs.picotts - ]; - }; autoExtraComponents = true; config = { homeassistant = { @@ -85,9 +95,6 @@ in { retain = true; }; }; - switch = - (import ./switch/power.nix) - ; light = []; media_player = [ { platform = "mpd"; @@ -100,34 +107,23 @@ in { } ]; - sensor = - (import ./sensors/power.nix) - ++ (import ./sensors/mate.nix) - ++ (import ./sensors/darksky.nix { inherit lib;}) - ++ shackopen.sensor - ++ wasser.sensor - ; - air_quality = (import ./sensors/sensemap.nix ); - - binary_sensor = - shackopen.binary_sensor - ++ (import ./sensors/spaceapi.nix) - ; - camera = []; - frontend = { }; config = { }; + sun = {}; http = { base_url = "http://hass.shack"; use_x_forwarded_for = true; trusted_proxies = "127.0.0.1"; }; #conversation = {}; - # history = {}; - #logbook = {}; - logger.default = "info"; + + history = {}; + logbook = {}; #recorder = {}; + + logger.default = "info"; + tts = [ { platform = "google_translate"; service_name = "say"; @@ -136,15 +132,6 @@ in { time_memory = 57600; } ]; - sun = {}; - - automation = wasser.automation - ++ badair.automation - ++ rollos.automation - ++ (import ./automation/shack-startup.nix) - ++ (import ./automation/party-time.nix) - ++ (import ./automation/hass-restart.nix); - device_tracker = []; }; }; diff --git a/krebs/2configs/shack/glados/multi/rollos.nix b/krebs/2configs/shack/glados/multi/rollos.nix index 4e6494936..29525ad82 100644 --- a/krebs/2configs/shack/glados/multi/rollos.nix +++ b/krebs/2configs/shack/glados/multi/rollos.nix @@ -11,46 +11,49 @@ let ]; in { - automation = - [ - { alias = "Rollos fahren Runter"; - trigger = [ - { - platform = "numeric_state"; - entity_id = tempsensor; - above = 25; - for = "00:30:00"; - } - ]; - condition = - [ + services.home-assistant.config = + { + automation = + [ + { alias = "Rollos fahren Runter"; + trigger = [ { - condition = "state"; - entity_id = "sun.sun"; - state = "above_horizon"; - } - ]; - action = - [ - { service = "cover.close_cover"; - entity_id = all_covers; + platform = "numeric_state"; + entity_id = tempsensor; + above = 25; + for = "00:30:00"; } ]; - } - { alias = "Rollos fahren Hoch"; - trigger = [ - { - platform = "sun"; - event = "sunset"; - } - ]; - condition = [ ]; - action = - [ - { service = "cover.open_cover"; - entity_id = all_covers; + condition = + [ + { + condition = "state"; + entity_id = "sun.sun"; + state = "above_horizon"; + } + ]; + action = + [ + { service = "cover.close_cover"; + entity_id = all_covers; + } + ]; + } + { alias = "Rollos fahren Hoch"; + trigger = [ + { + platform = "sun"; + event = "sunset"; } ]; - } - ]; + condition = [ ]; + action = + [ + { service = "cover.open_cover"; + entity_id = all_covers; + } + ]; + } + ]; + }; } diff --git a/krebs/2configs/shack/glados/multi/schlechte_luft.nix b/krebs/2configs/shack/glados/multi/schlechte_luft.nix index 31373d7b9..c1890361b 100644 --- a/krebs/2configs/shack/glados/multi/schlechte_luft.nix +++ b/krebs/2configs/shack/glados/multi/schlechte_luft.nix @@ -4,103 +4,106 @@ let ledring = "light.fablab_led_ring"; in { - automation = - [ - { alias = "Gute Luft Fablab"; - trigger = [ - { - platform = "numeric_state"; - entity_id = feinstaub_sensor; - below = 3; - } - ]; - action = - [ - { service = "light.turn_on"; - data = { - entity_id = ledring; - effect = "Twinkle"; - color_name = "green"; - }; + services.home-assistant.config = + { + automation = + [ + { alias = "Gute Luft Fablab"; + trigger = [ + { + platform = "numeric_state"; + entity_id = feinstaub_sensor; + below = 3; } ]; - } - { alias = "mäßige Luft Fablab"; - trigger = [ - { - platform = "numeric_state"; - above = 3; - below = 10; - entity_id = feinstaub_sensor; - } - ]; - action = - [ - { service = "light.turn_on"; - data = { - entity_id = ledring; - effect = "Twinkle"; - color_name = "yellow"; - }; + action = + [ + { service = "light.turn_on"; + data = { + entity_id = ledring; + effect = "Twinkle"; + color_name = "green"; + }; + } + ]; + } + { alias = "mäßige Luft Fablab"; + trigger = [ + { + platform = "numeric_state"; + above = 3; + below = 10; + entity_id = feinstaub_sensor; } ]; - } - { alias = "schlechte Luft Fablab"; - trigger = [ - { - platform = "numeric_state"; - above = 10; - entity_id = feinstaub_sensor; - } - ]; - action = - [ - { service = "light.turn_on"; - data = { - entity_id = ledring; - effect = "Fireworks"; - color_name = "red"; - }; + action = + [ + { service = "light.turn_on"; + data = { + entity_id = ledring; + effect = "Twinkle"; + color_name = "yellow"; + }; + } + ]; + } + { alias = "schlechte Luft Fablab"; + trigger = [ + { + platform = "numeric_state"; + above = 10; + entity_id = feinstaub_sensor; } ]; - } - { alias = "Luft Sensor nicht verfügbar"; - trigger = [ - { - platform = "state"; - to = "unavailable"; - entity_id = feinstaub_sensor; - } - ]; - action = - [ - { service = "light.turn_on"; - data = { - entity_id = ledring; - effect = "Rainbow"; - color_name = "blue"; - }; + action = + [ + { service = "light.turn_on"; + data = { + entity_id = ledring; + effect = "Fireworks"; + color_name = "red"; + }; + } + ]; + } + { alias = "Luft Sensor nicht verfügbar"; + trigger = [ + { + platform = "state"; + to = "unavailable"; + entity_id = feinstaub_sensor; } ]; - } - { alias = "Fablab Licht Reboot"; - trigger = [ - { - platform = "state"; - from = "unavailable"; - entity_id = ledring; - } - ]; - action = - [ - { service = "light.turn_on"; - data = { - entity_id = ledring; - effect = "Rainbow"; - color_name = "orange"; - }; + action = + [ + { service = "light.turn_on"; + data = { + entity_id = ledring; + effect = "Rainbow"; + color_name = "blue"; + }; + } + ]; + } + { alias = "Fablab Licht Reboot"; + trigger = [ + { + platform = "state"; + from = "unavailable"; + entity_id = ledring; } ]; - } - ]; + action = + [ + { service = "light.turn_on"; + data = { + entity_id = ledring; + effect = "Rainbow"; + color_name = "orange"; + }; + } + ]; + } + ]; + }; } diff --git a/krebs/2configs/shack/glados/multi/shackopen.nix b/krebs/2configs/shack/glados/multi/shackopen.nix index 354405d06..d9be9adfa 100644 --- a/krebs/2configs/shack/glados/multi/shackopen.nix +++ b/krebs/2configs/shack/glados/multi/shackopen.nix @@ -1,23 +1,26 @@ { - binary_sensor = [ - { platform = "mqtt"; - name = "Portal Lock"; - device_class = "door"; - state_topic = "portal/gateway/status"; - availability_topic = "portal/gateway/lwt"; - payload_on = "open"; - payload_off = "closed"; - payload_available = "online"; - payload_not_available = "offline"; - } - ]; - sensor = [ - { platform = "mqtt"; - name = "Keyholder"; - state_topic = "portal/gateway/keyholder"; - availability_topic = "portal/gateway/lwt"; - payload_available = "online"; - payload_not_available = "offline"; - } - ]; + services.home-assistant.config = + { + binary_sensor = [ + { platform = "mqtt"; + name = "Portal Lock"; + device_class = "door"; + state_topic = "portal/gateway/status"; + availability_topic = "portal/gateway/lwt"; + payload_on = "open"; + payload_off = "closed"; + payload_available = "online"; + payload_not_available = "offline"; + } + ]; + sensor = [ + { platform = "mqtt"; + name = "Keyholder"; + state_topic = "portal/gateway/keyholder"; + availability_topic = "portal/gateway/lwt"; + payload_available = "online"; + payload_not_available = "offline"; + } + ]; + }; } diff --git a/krebs/2configs/shack/glados/multi/wasser.nix b/krebs/2configs/shack/glados/multi/wasser.nix index bd8252e1c..9ca5e4500 100644 --- a/krebs/2configs/shack/glados/multi/wasser.nix +++ b/krebs/2configs/shack/glados/multi/wasser.nix @@ -11,100 +11,103 @@ let }; in { - sensor = map ( entity_id: { - platform = "statistics"; - name = "Statistics for ${entity_id}"; - inherit entity_id; - max_age.minutes = "60"; - sampling_size = 1000; - }) ["sensor.crafting_brotbox_soil_moisture"]; + services.home-assistant.config = + { + sensor = map ( entity_id: { + platform = "statistics"; + name = "Statistics for ${entity_id}"; + inherit entity_id; + max_age.minutes = "60"; + sampling_size = 1000; + }) ["sensor.crafting_brotbox_soil_moisture"]; - automation = - [ - ### Brotbox ##### - #{ alias = "Brotbox: water for ${toString brotbox.minutes} minutes every hour"; - # trigger = - # { # Trigger once every hour at :42 - # platform = "time_pattern"; - # minutes = 42; - # }; - # condition = { - # condition = "numeric_state"; - # entity_id = brotbox.sensor; - # value_template = "{{ state_attr('${brotbox.sensor}', 'median') }}"; - # below = 75; - # }; - # action = - # [ - # { - # service = "homeassistant.turn_on"; - # entity_id = brotbox.pump; - # } - # { delay.minutes = brotbox.minutes; } - # { - # service = "homeassistant.turn_off"; - # entity_id = brotbox.pump ; - # } - # ]; - #} - { alias = "Brotbox: Always turn off water after ${toString (brotbox.minutes * 2)} minutes"; - trigger = - { - platform = "state"; - entity_id = brotbox.pump; - to = "on"; - for.minutes = brotbox.minutes*2; - }; - action = - { - service = "homeassistant.turn_off"; - entity_id = brotbox.pump; - }; - } - - ##### Kaffeemaschine - { alias = "Water the plant for ${toString seconds} seconds"; - trigger = [ - { # trigger at 20:00 no matter what - # TODO: retry or run only if switch.wasser is available - platform = "time"; - |