Merge remote-tracking branch 'gum/master'
This commit is contained in:
commit
139799c53c
@ -104,7 +104,8 @@ in {
|
|||||||
nets = {
|
nets = {
|
||||||
retiolum.ip4.addr = "10.243.0.91";
|
retiolum.ip4.addr = "10.243.0.91";
|
||||||
wiregrill = {
|
wiregrill = {
|
||||||
# defaults
|
ip4.addr = "10.243.245.6";
|
||||||
|
aliases = [ "x.w" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -120,6 +121,12 @@ in {
|
|||||||
ci = true;
|
ci = true;
|
||||||
syncthing.id = "Y5OTK3S-JOJLAUU-KTBXKUW-M7S5UEQ-MMQPUK2-7CXO5V6-NOUDLKP-PRGAFAK";
|
syncthing.id = "Y5OTK3S-JOJLAUU-KTBXKUW-M7S5UEQ-MMQPUK2-7CXO5V6-NOUDLKP-PRGAFAK";
|
||||||
nets = {
|
nets = {
|
||||||
|
wiregrill = {
|
||||||
|
aliases = ["omo.w" "hass.omo.w" "jelly.omo.w" "jelly.makefu.w" ];
|
||||||
|
ip6.addr = (krebs.genipv6 "wiregrill" "makefu" { hostName = "omo"; }).address;
|
||||||
|
ip4.addr = "10.244.245.5";
|
||||||
|
|
||||||
|
};
|
||||||
retiolum = {
|
retiolum = {
|
||||||
ip4.addr = "10.243.0.89";
|
ip4.addr = "10.243.0.89";
|
||||||
aliases = [
|
aliases = [
|
||||||
@ -239,6 +246,7 @@ in {
|
|||||||
play.work.euer IN A ${nets.internet.ip4.addr}
|
play.work.euer IN A ${nets.internet.ip4.addr}
|
||||||
ul.work.euer IN A ${nets.internet.ip4.addr}
|
ul.work.euer IN A ${nets.internet.ip4.addr}
|
||||||
music.euer IN A ${nets.internet.ip4.addr}
|
music.euer IN A ${nets.internet.ip4.addr}
|
||||||
|
ntfy.euer IN A ${nets.internet.ip4.addr}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
nets = rec {
|
nets = rec {
|
||||||
|
@ -1 +1 @@
|
|||||||
Ed25519PublicKey = lKMWnuEVjcSoSEUWrj+51pwDQrQj2TqloL3aBKVWBbO
|
lKMWnuEVjcSoSEUWrj+51pwDQrQj2TqloL3aBKVWBbO
|
||||||
|
1
kartei/makefu/wiregrill/omo.pub
Normal file
1
kartei/makefu/wiregrill/omo.pub
Normal file
@ -0,0 +1 @@
|
|||||||
|
JmcpzkwgKymVecZqaV0ODQactoVwGGlEHcfYIOCkx3A=
|
@ -35,12 +35,13 @@ in
|
|||||||
'';
|
'';
|
||||||
networking = {
|
networking = {
|
||||||
firewall.enable = true;
|
firewall.enable = true;
|
||||||
interfaces.et0.ipv4.addresses = [
|
interfaces.et0.useDHCP = true;
|
||||||
{
|
#interfaces.et0.ipv4.addresses = [
|
||||||
address = shack-ip;
|
# {
|
||||||
prefixLength = 20;
|
# address = shack-ip;
|
||||||
}
|
# prefixLength = 20;
|
||||||
];
|
# }
|
||||||
|
#];
|
||||||
|
|
||||||
defaultGateway = "10.42.0.1";
|
defaultGateway = "10.42.0.1";
|
||||||
nameservers = [ "10.42.0.100" "10.42.0.200" ];
|
nameservers = [ "10.42.0.100" "10.42.0.200" ];
|
||||||
|
@ -46,10 +46,8 @@
|
|||||||
# light.shack web-ui
|
# light.shack web-ui
|
||||||
<stockholm/krebs/2configs/shack/light.shack.nix> #light.shack
|
<stockholm/krebs/2configs/shack/light.shack.nix> #light.shack
|
||||||
|
|
||||||
# powerraw usb serial to mqtt and raw socket
|
# fetch the u300 power stats
|
||||||
<stockholm/krebs/2configs/shack/powerraw.nix> # powerraw.shack standby.shack
|
<stockholm/krebs/2configs/shack/power/u300-power.nix>
|
||||||
# send power stats to s3
|
|
||||||
<stockholm/krebs/2configs/shack/s3-power.nix> # powerraw.shack must be available
|
|
||||||
|
|
||||||
|
|
||||||
{ # do not log to /var/spool/log
|
{ # do not log to /var/spool/log
|
||||||
|
@ -7,6 +7,7 @@ in {
|
|||||||
SUBSYSTEM=="net", ATTR{address}=="8c:70:5a:b2:84:58", NAME="wl0"
|
SUBSYSTEM=="net", ATTR{address}=="8c:70:5a:b2:84:58", NAME="wl0"
|
||||||
SUBSYSTEM=="net", ATTR{address}=="3c:97:0e:07:b9:14", NAME="${ext-if}"
|
SUBSYSTEM=="net", ATTR{address}=="3c:97:0e:07:b9:14", NAME="${ext-if}"
|
||||||
'';
|
'';
|
||||||
|
networking.wireless.enable = true;
|
||||||
networking = {
|
networking = {
|
||||||
firewall.enable = true;
|
firewall.enable = true;
|
||||||
firewall.allowedTCPPorts = [ 80 443 8088 8086 8083 5901 ];
|
firewall.allowedTCPPorts = [ 80 443 8088 8086 8083 5901 ];
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
# needs:
|
|
||||||
# binary_sensor.lounge_ampel_status
|
|
||||||
# light.lounge_ampel_licht_rot
|
|
||||||
|
|
||||||
let
|
|
||||||
glados = import ../lib;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
services.home-assistant.config.automation =
|
|
||||||
[
|
|
||||||
{
|
|
||||||
alias = "Ampel Rotes Licht";
|
|
||||||
initial_state = true;
|
|
||||||
trigger = {
|
|
||||||
platform = "state";
|
|
||||||
entity_id = "binary_sensor.lounge_ampel_status";
|
|
||||||
};
|
|
||||||
action = { service = "light.turn_on";
|
|
||||||
data.entity_id = "light.lounge_ampel_licht_rot";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
Willkommen werter Keyholder {{ states("sensor.keyholder") }} in deinem Lieblingshackerspace.
|
|
||||||
|
|
||||||
Es ist {{states("sensor.fablab_feinstaub_temperature") | round(1) | replace('.',' Komma ')}} Grad {% if states("sensor.fablab_feinstaub_temperature")|float > 25 %}heiss{%elif states("sensor.fablab_feinstaub_temperature")|float > 15%}warm{%else%}kalt{%endif%} bei {% if states(" sensor.rz_feinstaub_humidity") | int <45 %}trockenen{% elif states(" sensor.rz_feinstaub_humidity") | int <65 %}angenehmen{%else%}feuchten{%endif%} {{states(" sensor.rz_feinstaub_humidity") | int }} Prozent Luftfeuchtigkeit.
|
|
||||||
|
|
||||||
{% if (states("sensor.fullstand_mate_1")|int == 0) and
|
|
||||||
states("sensor.fullstand_mate_2")|int == 0 %}ES IST MAHTECALYPSE, BEIDE MAHTESCHÄCHTE SIND LEER! {%if states("sensor.fullstand_mate_cola")| int == 0%} UND SOGAR DIE COLA IST ALLE. Ihr seid sowas von am Arsch!{%else%}Zum Glück gibt es noch Cola, Phew!{%endif%}
|
|
||||||
{% elif (states("sensor.fullstand_mate_1")|int + states("sensor.fullstand_mate_2")|int) < 5 %}
|
|
||||||
Der Mahtestand im Automaten ist mit {{states("sensor.fullstand_mate_1")|int + states("sensor.fullstand_mate_2")|int }} verbleibenden Flaschen kritisch!
|
|
||||||
{% else %}
|
|
||||||
Im Automaten sind noch {{states("sensor.fullstand_mate_1")|int + states("sensor.fullstand_mate_2")|int }} Flaschen Mahte und {{states("sensor.fullstand_mate_cola")}} Flaschen Cola.
|
|
||||||
{%endif%}
|
|
||||||
|
|
||||||
Die Wettervorhersage: {{states("sensor.dark_sky_hourly_summary")}} Aktuell {{states("sensor.dark_sky_summary")}} bei {{states("sensor.dark_sky_temperature") | round(1) | replace('.',' Komma ')}} Grad.
|
|
||||||
Der Stromverbrauch liegt bei {{ (( states("sensor.l1_power")|int + states("sensor.l2_power")|int + states("sensor.l3_power")|int ) / 1000 )| round(1) | replace('.',' Komma ')}} Kilowatt.
|
|
||||||
|
|
||||||
Im Fablab ist die Feinstaubbelastung {% if states("sensor.fablab_particulate_matter_2_5um_concentration") | float > 50 %}hoch!{%elif states("sensor.fablab_particulate_matter_2_5um_concentration") | float > 25 %}mäßig.{% else %}gering.{%endif%}
|
|
||||||
|
|
||||||
{% if is_state("binary_sensor.door_rzl",'on') and is_state("binary_sensor.door_entropia",'on') %}
|
|
||||||
Das Raumzeitlabor und Entropia haben geöffnet.
|
|
||||||
{% elif is_state("binary_sensor.door_rzl",'off') and is_state("binary_sensor.door_entropia",'off') %}
|
|
||||||
Das Raumzeitlabor und Entropia haben geschlossen.
|
|
||||||
{% elif is_state("binary_sensor.door_rzl",'on') and is_state("binary_sensor.door_entropia",'off') %}
|
|
||||||
Das Raumzeitlabor hat geöffnet und Entropia hat geschlossen.
|
|
||||||
{% elif is_state("binary_sensor.door_rzl",'off') and is_state("binary_sensor.door_entropia",'on') %}
|
|
||||||
Das Raumzeitlabor hat geschlossen und Entropia hat geöffnet.
|
|
||||||
{%endif%}
|
|
||||||
|
|
||||||
Die Glados Hackerspace Automation wünscht dir und allen Anwesenden einen produktiven und angenehmen Aufenthalt!
|
|
@ -1,24 +0,0 @@
|
|||||||
# needs:
|
|
||||||
# light.fablab_led
|
|
||||||
{
|
|
||||||
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";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
|||||||
# Needs:
|
|
||||||
# sun.sunset
|
|
||||||
# switch.lounge_diskoschalter_relay
|
|
||||||
let
|
|
||||||
glados = import ../lib;
|
|
||||||
disko_schalter = "switch.lounge_diskoschalter_relay";
|
|
||||||
player = "media_player.lounge";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
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?
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
@ -1,100 +0,0 @@
|
|||||||
# needs:
|
|
||||||
# binary_sensor.portal_lock
|
|
||||||
# sensor.keyholder
|
|
||||||
# media_player.lounge
|
|
||||||
|
|
||||||
# additional state required on:
|
|
||||||
# mpd.shack:
|
|
||||||
# playlist "ansage"
|
|
||||||
# playlist "lassulus"
|
|
||||||
# lounge.kiosk.shack:
|
|
||||||
# playlist "ansage"
|
|
||||||
|
|
||||||
let
|
|
||||||
glados = import ../lib;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
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";
|
|
||||||
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";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
@ -1,12 +1,33 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
let
|
let
|
||||||
unstable = import (pkgs.fetchFromGitHub {
|
kodi-host = "192.168.8.11";
|
||||||
owner = "nixos";
|
confdir = "/var/lib/homeassistant-docker";
|
||||||
repo = "nixpkgs";
|
|
||||||
rev = (lib.importJSON ../../../nixpkgs-unstable.json).rev;
|
|
||||||
sha256 = (lib.importJSON ../../../nixpkgs-unstable.json).sha256;
|
|
||||||
}) {};
|
|
||||||
in {
|
in {
|
||||||
|
imports = [
|
||||||
|
];
|
||||||
|
|
||||||
|
# networking.firewall.allowedTCPPorts = [ 8123 ];
|
||||||
|
virtualisation.oci-containers.containers.hass = {
|
||||||
|
image = "homeassistant/home-assistant:latest";
|
||||||
|
environment = {
|
||||||
|
TZ = "Europe/Berlin";
|
||||||
|
# TODO create unique users
|
||||||
|
PUID = toString config.users.users.news_container.uid;
|
||||||
|
PGID = toString config.users.groups.news_container.gid;
|
||||||
|
UMASK = "007";
|
||||||
|
};
|
||||||
|
extraOptions = ["--net=host" ];
|
||||||
|
volumes = [
|
||||||
|
"${confdir}:/config"
|
||||||
|
#"${confdir}/docker-run:/etc/services.d/home-assistant/run:"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
#"f ${confdir}/docker-run 0770 kiosk kiosk - -"
|
||||||
|
# TODO:
|
||||||
|
"d ${confdir} 0770 news_container news_container - -"
|
||||||
|
];
|
||||||
|
|
||||||
services.nginx.virtualHosts."hass.shack" = {
|
services.nginx.virtualHosts."hass.shack" = {
|
||||||
serverAliases = [ "glados.shack" ];
|
serverAliases = [ "glados.shack" ];
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
@ -23,127 +44,4 @@ 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
|
|
||||||
./automation/ampel.nix
|
|
||||||
|
|
||||||
];
|
|
||||||
services.home-assistant =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
package = unstable.home-assistant.overrideAttrs (old: {
|
|
||||||
doInstallCheck = false;
|
|
||||||
});
|
|
||||||
config = {
|
|
||||||
homeassistant = {
|
|
||||||
name = "Glados";
|
|
||||||
time_zone = "Europe/Berlin";
|
|
||||||
latitude = "48.8265";
|
|
||||||
longitude = "9.0676";
|
|
||||||
elevation = 303;
|
|
||||||
auth_providers = [
|
|
||||||
{ type = "homeassistant";}
|
|
||||||
{ type = "trusted_networks";
|
|
||||||
trusted_networks = [
|
|
||||||
"127.0.0.1/32"
|
|
||||||
"10.42.0.0/16"
|
|
||||||
"::1/128"
|
|
||||||
"fd00::/8"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
# https://www.home-assistant.io/components/influxdb/
|
|
||||||
influxdb = {
|
|
||||||
database = "glados";
|
|
||||||
host = "influx.shack";
|
|
||||||
component_config_glob = {
|
|
||||||
"sensor.*particulate_matter_2_5um_concentration".override_measurement = "2_5um particles";
|
|
||||||
"sensor.*particulate_matter_10_0um_concentration".override_measurement ="10um particles";
|
|
||||||
};
|
|
||||||
tags = {
|
|
||||||
instance = "wolf";
|
|
||||||
source = "glados";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
esphome = {};
|
|
||||||
api = {};
|
|
||||||
mqtt = {
|
|
||||||
broker = "localhost";
|
|
||||||
port = 1883;
|
|
||||||
client_id = "home-assistant";
|
|
||||||
keepalive = 60;
|
|
||||||
protocol = 3.1;
|
|
||||||
discovery = true; #enable esphome discovery
|
|
||||||
discovery_prefix = "homeassistant";
|
|
||||||
birth_message = {
|
|
||||||
topic = "glados/hass/status/LWT";
|
|
||||||
payload = "Online";
|
|
||||||
qos = 1;
|
|
||||||
retain = true;
|
|
||||||
};
|
|
||||||
will_message = {
|
|
||||||
topic = "glados/hass/status/LWT";
|
|
||||||
payload = "Offline";
|
|
||||||
qos = 1;
|
|
||||||
retain = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
light = [];
|
|
||||||
media_player = [
|
|
||||||
{ platform = "mpd";
|
|
||||||
name = "lounge";
|
|
||||||
host = "lounge.mpd.shack";
|
|
||||||
}
|
|
||||||
{ platform = "mpd";
|
|
||||||
name = "kiosk";
|
|
||||||
#host = "lounge.kiosk.shack";
|
|
||||||
host = "kiosk.shack";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
camera = [];
|
|
||||||
frontend = { };
|
|
||||||
config = { };
|
|
||||||
sun = {};
|
|
||||||
http = {
|
|
||||||
base_url = "http://hass.shack";
|
|
||||||
use_x_forwarded_for = true;
|
|
||||||
trusted_proxies = [ "127.0.0.1" "::1" ];
|
|
||||||
};
|
|
||||||
#conversation = {};
|
|
||||||
|
|
||||||
history = {};
|
|
||||||
logbook = {};
|
|
||||||
#recorder = {};
|
|
||||||
|
|
||||||
logger.default = "info";
|
|
||||||
|
|
||||||
tts = [
|
|
||||||
{ platform = "google_translate";
|
|
||||||
service_name = "say";
|
|
||||||
language = "de";
|
|
||||||
cache = true;
|
|
||||||
time_memory = 57600;
|
|
||||||
base_url = "http://hass.shack";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
device_tracker = [];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
{ lib
|
|
||||||
, buildPythonPackage
|
|
||||||
, fetchPypi
|
|
||||||
, requests
|
|
||||||
}:
|
|
||||||
|
|
||||||
buildPythonPackage rec {
|
|
||||||
pname = "gtts-token";
|
|
||||||
version = "1.1.3";
|
|
||||||
|
|
||||||
src = fetchPypi {
|
|
||||||
pname = "gTTS-token";
|
|
||||||
inherit version;
|
|
||||||
sha256 = "9d6819a85b813f235397ef931ad4b680f03d843c9b2a9e74dd95175a4bc012c5";
|
|
||||||
};
|
|
||||||
|
|
||||||
propagatedBuildInputs = [
|
|
||||||
requests
|
|
||||||
];
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
description = "Calculates a token to run the Google Translate text to speech";
|
|
||||||
homepage = https://github.com/boudewijn26/gTTS-token;
|
|
||||||
license = licenses.mit;
|
|
||||||
# maintainers = [ maintainers. ];
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
{ lib
|
|
||||||
, buildPythonPackage
|
|
||||||
, fetchpatch
|
|
||||||
, fetchPypi
|
|
||||||
, aiohttp
|
|
||||||
, async-timeout
|
|
||||||
}:
|
|
||||||
|
|
||||||
buildPythonPackage rec {
|
|
||||||
pname = "pyhaversion";
|
|
||||||
version = "2.2.1";
|
|
||||||
|
|
||||||
src = fetchPypi {
|
|
||||||
inherit pname version;
|
|
||||||
sha256 = "72b65aa25d7b2dbb839a4d0218df2005c2335e93526035904d365bb668030b9f";
|
|
||||||
};
|
|
||||||
patches = [
|
|
||||||
(fetchpatch { url = "https://github.com/makefu/pyhaversion/commit/f3bdc38970272cd345c2cfbde3037ea492ca27c4.patch";
|
|
||||||
sha256 =
|
|
||||||
"1rhq4z7mdgnwhwpf5fmarnbc1ba3qysk1wqjdr0hvbzi8vmvbfcc";})
|
|
||||||
];
|
|
||||||
doCheck = false;
|
|
||||||
propagatedBuildInputs = [
|
|
||||||
aiohttp
|
|
||||||
async-timeout
|
|
||||||
];
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
description = "";
|
|
||||||
homepage = https://github.com/ludeeus/pyhaversion;
|
|
||||||
# maintainers = [ maintainers. ];
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
let
|
|
||||||
prefix = "glados";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
|
|
||||||
say = let
|
|
||||||
# returns a list of actions to be performed on an mpd to say something
|
|
||||||
tts = { message, entity }:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
service = "media_player.turn_on";
|
|
||||||
data.entity_id = "media_player.${entity}";
|
|
||||||
}
|
|
||||||
{ service = "media_player.play_media";
|
|
||||||
data = {
|
|
||||||
entity_id = "media_player.${entity}";
|
|
||||||
media_content_type = "playlist";
|
|
||||||
media_content_id = "ansage";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
service = "media_player.turn_on";
|
|
||||||
data.entity_id = "media_player.${entity}";
|
|
||||||
}
|
|
||||||
{ delay.seconds = 4.5; }
|
|
||||||
{ service = "tts.say";
|
|
||||||
entity_id = "media_player.${entity}";
|
|
||||||
data_template = {
|
|
||||||
inherit message;
|
|
||||||
language = "de";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
in
|
|
||||||
{
|
|
||||||
lounge = message: tts {
|
|
||||||
inherit message;
|
|
||||||
entity = "lounge";
|
|
||||||
};
|
|
||||||
herrenklo = message: tts {
|
|
||||||
inherit message;
|
|
||||||
entity = "herrenklo";
|
|
||||||
};
|
|
||||||
kiosk = message: tts {
|
|
||||||
inherit message;
|
|
||||||
entity = "kiosk";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
tasmota =
|
|
||||||
{
|
|
||||||
plug = {host, name ? host, topic ? host}:
|
|
||||||
{
|
|
||||||
platform = "mqtt";
|
|
||||||
inherit name;
|
|
||||||
state_topic = "sonoff/stat/${topic}/POWER1";
|
|
||||||
command_topic = "sonoff/cmnd/${topic}/POWER1";
|
|
||||||
availability_topic = "sonoff/tele/${topic}/LWT";
|
|
||||||
payload_on= "ON";
|
|
||||||
payload_off= "OFF";
|
|
||||||
payload_available= "Online";
|
|
||||||
payload_not_available= "Offline";
|
|
||||||
retain = false;
|
|
||||||
qos = 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
#
|
|
||||||
|
|
||||||
let
|
|
||||||
glados = import ../lib;
|
|
||||||
tempsensor = "sensor.dark_sky_temperature";
|
|
||||||
all_covers = [
|
|
||||||
"cover.crafting_rollo"
|
|
||||||
"cover.elab_rollo"
|
|
||||||
"cover.or2_rollo"
|
|
||||||
"cover.retroraum_rollo"
|
|
||||||
];
|
|
||||||
in
|
|
||||||
{
|
|
||||||
services.home-assistant.config =
|
|
||||||
{
|
|
||||||
automation =
|
|
||||||
[
|
|
||||||
{ alias = "Rollos fahren Runter";
|
|
||||||
trigger = [
|
|
||||||
{
|
|
||||||
platform = "numeric_state";
|
|
||||||
entity_id = tempsensor;
|
|
||||||
above = 25;
|
|
||||||
for = "00:30:00";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,109 +0,0 @@
|
|||||||
let
|
|
||||||
glados = import ../lib;
|
|
||||||
feinstaub_sensor = "sensor.fablab_particulate_matter_2_5um_concentration";
|
|
||||||
ledring = "light.fablab_led_ring";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
services.home-assistant.config =
|
|
||||||
{
|
|
||||||
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";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{ 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";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{ 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";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{ 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";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{ 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";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
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";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,113 +0,0 @@
|
|||||||
# uses:
|
|
||||||
# switch.crafting_giesskanne_relay
|
|
||||||
let
|
|
||||||
glados = import ../lib;
|
|
||||||
seconds = 20;
|
|
||||||
wasser = "switch.crafting_giesskanne_relay";
|
|
||||||
brotbox = {
|
|
||||||
minutes = 10;
|
|
||||||
pump = "switch.crafting_brotbox_pumpe";
|
|
||||||
sensor = "sensor.statistics_for_sensor_crafting_brotbox_soil_moisture";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
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";
|
|
||||||
at = "20:00:00";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
action =
|
|
||||||
[
|
|
||||||
{
|
|
||||||
service = "homeassistant.turn_on";
|
|
||||||
entity_id = [
|
|
||||||
wasser
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{ delay.seconds = seconds; }
|
|
||||||
{
|
|
||||||
service = "homeassistant.turn_off";
|
|
||||||
entity_id = [
|
|
||||||
wasser
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{ alias = "Always turn off water after ${toString (seconds * 2)}seconds";
|
|
||||||
trigger = [
|
|
||||||
{
|
|
||||||
platform = "state";
|
|
||||||
entity_id = wasser;
|
|
||||||
to = "on";
|
|
||||||
for.seconds = seconds*2;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
action =
|
|
||||||
[
|
|
||||||
{
|
|
||||||
service = "homeassistant.turn_off";
|
|
||||||
entity_id = [ wasser ];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
{lib,...}:
|
|
||||||
{
|
|
||||||
services.home-assistant.config.sensor =
|
|
||||||
[
|
|
||||||
{ platform = "darksky";
|
|
||||||
api_key = lib.removeSuffix "\n"
|
|
||||||
(builtins.readFile <secrets/hass/darksky.apikey>);
|
|
||||||
language = "de";
|
|
||||||
monitored_conditions = [
|
|
||||||
"summary" "icon"
|
|
||||||
"nearest_storm_distance" "precip_probability"
|
|
||||||
"precip_intensity"
|
|
||||||
"temperature" # "temperature_high" "temperature_low"
|
|
||||||
"apparent_temperature"
|
|
||||||
"hourly_summary" # next 24 hours text
|
|
||||||
"humidity"
|
|
||||||
"pressure"
|
|
||||||
"uv_index"
|
|
||||||
];
|
|
||||||
units = "si" ;
|
|
||||||
scan_interval = "00:15:00";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
let
|
|
||||||
fuellstand = name: id: {
|
|
||||||
platform = "rest";
|
|
||||||
resource = "https://ora5.tutschonwieder.net/ords/lick_prod/v1/get/fuellstand/1/${toString id}";
|
|
||||||
method = "GET";
|
|
||||||
name = "Füllstand ${name}";
|
|
||||||
value_template = "{{ value_json.fuellstand }}";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
services.home-assistant.config.sensor =
|
|
||||||
[
|
|
||||||
(fuellstand "Wasser" 1)
|
|
||||||
(fuellstand "Mate Cola" 2)
|
|
||||||
(fuellstand "Apfelschorle" 3)
|
|
||||||
(fuellstand "Zitronensprudel" 4)
|
|
||||||
(fuellstand "Mate 1" 26)
|
|
||||||
(fuellstand "Mate 2" 27)
|
|
||||||
];
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
let
|
|
||||||
power_x = name: phase:
|
|
||||||
{ platform = "mqtt";
|
|
||||||
name = "${phase} ${name}";
|
|
||||||
state_topic = "/power/total/${phase}/${name}";
|
|
||||||
availability_topic = "/power/lwt";
|
|
||||||
payload_available = "Online";
|
|
||||||
payload_not_available = "Offline";
|
|
||||||
};
|
|
||||||
power_consumed =
|
|
||||||
{ platform = "mqtt";
|
|
||||||
name = "Power Consumed";
|
|
||||||
device_class = "power";
|
|
||||||
state_topic = "/power/total/consumed";
|
|
||||||
availability_topic = "/power/lwt";
|
|
||||||
payload_available = "Online";
|
|
||||||
payload_not_available = "Offline";
|
|
||||||
};
|
|
||||||
power_volt = power_x "Voltage";
|
|
||||||
power_watt = (power_x "Power") ;
|
|
||||||
power_curr = power_x "Current";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
services.home-assistant.config.sensor =
|
|
||||||
(map power_volt [ "L1" "L2" "L3" ])
|
|
||||||
++ (map (x: ((power_watt x) // { device_class = "power"; })) [ "L1" "L2" "L3" ])
|
|
||||||
++ (map power_curr [ "L1" "L2" "L3" ])
|
|
||||||
++ [ power_consumed ];
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
services.home-assistant.config.air_quality =
|
|
||||||
[
|
|
||||||
{
|
|
||||||
platform = "opensensemap";
|
|
||||||
station_id = "56a0de932cb6e1e41040a68b";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
{
|
|
||||||
services.home-assistant.config.binary_sensor =
|
|
||||||
[
|
|
||||||
{
|
|
||||||
platform = "rest";
|
|
||||||
resource = "https://spaceapi.afra-berlin.de/v1/status.json";
|
|
||||||
method = "GET";
|
|
||||||
name = "Door AFRA Berlin";
|
|
||||||
device_class = "door";
|
|
||||||
value_template = "{{ value_json.open }}";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
platform = "rest";
|
|
||||||
resource = "http://club.entropia.de/spaceapi";
|
|
||||||
method = "GET";
|
|
||||||
name = "Door Entropia";
|
|
||||||
device_class = "door";
|
|
||||||
value_template = "{{ value_json.open }}";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
platform = "rest";
|
|
||||||
resource = "http://www.c-base.org/status.json";
|
|
||||||
method = "GET";
|
|
||||||
name = "Door C-Base Berlin";
|
|
||||||
device_class = "door";
|
|
||||||
value_template = "{{ value_json.open }}";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
platform = "rest";
|
|
||||||
resource = "https://status.raumzeitlabor.de/api/full.json";
|
|
||||||
method = "GET";
|
|
||||||
name = "Door RZL";
|
|
||||||
device_class = "door";
|
|
||||||
value_template = "{{ value_json.status }}";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
platform = "rest";
|
|
||||||
resource = "https://datenobservatorium.de/";
|
|
||||||
method = "GET";
|
|
||||||
name = "Door Datenobservatorium";
|
|
||||||
device_class = "door";
|
|
||||||
value_template = "false";
|
|
||||||
scan_interval = 2592000;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
platform = "rest";
|
|
||||||
resource = "https://infuanfu.de/";
|
|
||||||
method = "GET";
|
|
||||||
name = "Door Infuanfu";
|
|
||||||
device_class = "door";
|
|
||||||
value_template = "false";
|
|
||||||
scan_interval = 2592000;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
controllers = {
|
|
||||||
host = "unifi.shack";
|
|
||||||
site = "shackspace";
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
# 1 - haupt
|
|
||||||
# 2 - dusche
|
|
||||||
# 3 - warmwasser
|
|
||||||
# 4 - or
|
|
||||||
# 5 - kueche
|
|
||||||
let
|
|
||||||
nodelight = type: ident: name: {
|
|
||||||
platform = "mqtt";
|
|
||||||
name = "${type} ${name}";
|
|
||||||
command_topic = "${type}/${toString ident}/command";
|
|
||||||
state_topic = "${type}/${toString ident}/state";
|
|
||||||
payload_on = "on";
|
|
||||||
payload_off = "off";
|
|
||||||
};
|
|
||||||
power = nodelight "power";
|
|
||||||
light = ident: name: { icon = "mdi:lightbulb";} // nodelight "light" ident name;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
services.home-assistant.config.switch =
|
|
||||||
[
|
|
||||||
# These commands we see with a shutdown:
|
|
||||||
# power/143/state on
|
|
||||||
# power/142/state on
|
|
||||||
# power/141/state on
|
|
||||||
# power/142/state off
|
|
||||||
# power/141/state off
|
|
||||||
# power/10/state off
|
|
||||||
# power/main/state off
|
|
||||||
|
|
||||||
(power "10" "Hauptschalter")
|
|
||||||
(power 1 "Dusche") # ???
|
|
||||||
(power 2 "Warmwasser") # ???
|
|
||||||
(power 3 "Optionsräume") # ???
|
|
||||||
(power 4 "Küche") # ???
|
|
||||||
(light 1 "Decke Lounge 1")
|
|
||||||
(light 2 "Decke Lounge 2")
|
|
||||||
(light 3 "Decke Lounge 3")
|
|
||||||
(light 4 "Decke Lounge 4")
|
|
||||||
(light 5 "Decke Lounge 5")
|
|
||||||
(light 6 "Decke Lounge 6")
|
|
||||||
(light 7 "Decke Lounge 7")
|
|
||||||
(light 8 "Decke Lounge 8")
|
|
||||||
];
|
|
||||||
}
|
|
@ -4,7 +4,18 @@ in {
|
|||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [ port ]; # legacy
|
networking.firewall.allowedTCPPorts = [ port ]; # legacy
|
||||||
services.nginx.virtualHosts."grafana.shack" = {
|
services.nginx.virtualHosts."grafana.shack" = {
|
||||||
locations."/".proxyPass = "http://localhost:${toString port}";
|
locations."/" = {
|
||||||
|
proxyPass = "http://localhost:${toString port}";
|
||||||
|
extraConfig =''
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
'';
|
||||||
|
|
||||||
|
};
|
||||||
};
|
};
|
||||||
services.grafana = {
|
services.grafana = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -15,6 +15,16 @@ in
|
|||||||
'';
|
'';
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
proxyPass = "http://localhost:${toString port}/";
|
proxyPass = "http://localhost:${toString port}/";
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
proxy_buffering off;
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
nixpkgs.overlays = [
|
nixpkgs.overlays = [
|
||||||
|
29
krebs/2configs/shack/power/u300-power.nix
Normal file
29
krebs/2configs/shack/power/u300-power.nix
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
repo = "shackstrom";
|
||||||
|
owner = "samularity";
|
||||||
|
rev = "adfbdc7d12000fbc9fd9367c8ef0a53b7d0a9fad";
|
||||||
|
hash = "sha256-77vSX2+1XXaBVgLka+tSEK/XYZASEk9iq+uEuO1aOUQ=";
|
||||||
|
};
|
||||||
|
pkg = pkgs.writers.writePython3 "test_python3" {
|
||||||
|
libraries = [ pkgs.python3Packages.requests pkgs.python3Packages.paho-mqtt ];
|
||||||
|
} (builtins.readFile "${src}/shackstrom.py");
|
||||||
|
in
|
||||||
|
{
|
||||||
|
systemd.services = {
|
||||||
|
u300-power = {
|
||||||
|
enable = true;
|
||||||
|
environment = {
|
||||||
|
DATA_URL = "http://10.42.20.255/csv.html";
|
||||||
|
BROKER = "mqtt.shack";
|
||||||
|
};
|
||||||
|
serviceConfig = {
|
||||||
|
Restart = "always";
|
||||||
|
ExecStart = pkg;
|
||||||
|
RestartSec = "15s";
|
||||||
|
};
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -1,28 +1,12 @@
|
|||||||
{ lib,... }:
|
{ lib,... }:
|
||||||
let
|
let
|
||||||
disk_free_threshold = "10"; # at least this much free disk percentage
|
disk_free_threshold = "5"; # at least this much free disk percentage
|
||||||
in {
|
in {
|
||||||
services.prometheus.rules = [(builtins.toJSON
|
services.prometheus.rules = [(builtins.toJSON
|
||||||
{
|
{
|
||||||
groups = [
|
groups = [
|
||||||
{ name = "shack-env";
|
{ name = "shack-env";
|
||||||
rules = [
|
rules = [
|
||||||
{
|
|
||||||
alert = "Wolf RootPartitionFull";
|
|
||||||
for = "30m";
|
|
||||||
expr = ''(node_filesystem_avail_bytes{alias="wolf.shack",mountpoint="/"} * 100) / node_filesystem_size_bytes{alias="wolf.shack",mountpoint="/"} < ${disk_free_threshold}'';
|
|
||||||
labels.severity = "warning";
|
|
||||||
annotations.summary = "{{ $labels.alias }} root disk full";
|
|
||||||
annotations.url = "http://grafana.shack/d/hb7fSE0Zz/shack-system-dashboard?orgId=1&var-job=node&var-hostname=All&var-node=wolf.shack:9100&var-device=All&var-maxmount=%2F&var-show_hostname=wolf";
|
|
||||||
annotations.description = ''The root disk of {{ $labels.alias }} has {{ $value | printf "%.2f" }}% free disk space (Threshold at ${disk_free_threshold}%). CI for deploying new configuration will seize working. Log in to the system and try to clean up the obsolete files on the machine. There are a couple of things you can do:
|
|
||||||
1. `nix-collect-garbage -d`
|
|
||||||
2. clean up the shack share folder in `/home/share`
|
|
||||||
3. check `du -hs /var/ | sort -h`.
|
|
||||||
4. run `docker system prune`
|
|
||||||
5. `find /var/lib/containers/news/var/lib/htgen-go/items -mtime +7 -delete;` to clean up the link shortener data
|
|
||||||
5. If you are really desperate run `du -hs / | sort -h` and go through the folders recursively until you've found something to delete
|
|
||||||
6. as a last resort the root disk can be expanded via `lvresize -L +10G /dev/pool/root && btrfs filesystem resize max /` '';
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
alert = "Puyak RootPartitionFull";
|
alert = "Puyak RootPartitionFull";
|
||||||
for = "30m";
|
for = "30m";
|
||||||
@ -32,9 +16,8 @@ in {
|
|||||||
annotations.url = "http://grafana.shack/d/hb7fSE0Zz/shack-system-dashboard?orgId=1&var-job=node&var-hostname=All&var-node=wolf.shack:9100&var-device=All&var-maxmount=%2F&var-show_hostname=puyak";
|
annotations.url = "http://grafana.shack/d/hb7fSE0Zz/shack-system-dashboard?orgId=1&var-job=node&var-hostname=All&var-node=wolf.shack:9100&var-device=All&var-maxmount=%2F&var-show_hostname=puyak";
|
||||||
annotations.description = ''The root disk of {{ $labels.alias }} has {{ $value | printf "%.2f" }}% free disk space (Threshold at ${disk_free_threshold}%).Prometheus will not be able to create new alerts and CI for deploying new configuration will also seize working. Log in to the system and run `nix-collect-garbage -d` and if this does not help you can check `du -hs /var/ | sort -h`, run `docker system prune` or if you are really desperate run `du -hs / | sort -h` and go through the folders recursively until you've found something to delete'';
|
annotations.description = ''The root disk of {{ $labels.alias }} has {{ $value | printf "%.2f" }}% free disk space (Threshold at ${disk_free_threshold}%).Prometheus will not be able to create new alerts and CI for deploying new configuration will also seize working. Log in to the system and run `nix-collect-garbage -d` and if this does not help you can check `du -hs /var/ | sort -h`, run `docker system prune` or if you are really desperate run `du -hs / | sort -h` and go through the folders recursively until you've found something to delete'';
|
||||||
}
|
}
|
||||||
# wolf.shack is not worth supervising anymore
|
|
||||||
{
|
{
|
||||||
alert = "HostDown";
|
alert = "Infra01 down";
|
||||||
expr = ''up{alias="infra01.shack"} == 0'';
|
expr = ''up{alias="infra01.shack"} == 0'';
|
||||||
for = "5m";
|
for = "5m";
|
||||||
labels.severity = "page";
|
labels.severity = "page";
|
||||||
|
207
krebs/2configs/shack/prometheus/irc-alerts.py
Normal file
207
krebs/2configs/shack/prometheus/irc-alerts.py
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
import base64
|
||||||
|
import cgi
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import socket
|
||||||
|
import ssl
|
||||||
|
import sys
|
||||||
|
from http.server import BaseHTTPRequestHandler
|
||||||
|
from typing import List, Optional, Tuple
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
DEBUG = os.environ.get("DEBUG") is not None
|
||||||
|
|
||||||
|
|
||||||
|
def _irc_send(
|
||||||
|
server: str,
|
||||||
|
nick: str,
|
||||||
|
channel: str,
|
||||||
|
sasl_password: Optional[str] = None,
|
||||||
|
server_password: Optional[str] = None,
|
||||||
|
tls: bool = True,
|
||||||
|
port: int = 6697,
|
||||||
|
messages: List[str] = [],
|
||||||
|
) -> None:
|
||||||
|
if not messages:
|
||||||
|
return
|
||||||
|
|
||||||
|
sock = socket.socket()
|
||||||
|
if tls:
|
||||||
|
sock = ssl.wrap_socket(
|
||||||
|
sock, cert_reqs=ssl.CERT_NONE, ssl_version=ssl.PROTOCOL_TLSv1_2
|
||||||
|
)
|
||||||
|
|
||||||
|
def _send(command: str) -> int:
|
||||||
|
if DEBUG:
|
||||||
|
print(command)
|
||||||
|
return sock.send((f"{command}\r\n").encode())
|
||||||
|
|
||||||
|
def _pong(ping: str):
|
||||||
|
if ping.startswith("PING"):
|
||||||
|
sock.send(ping.replace("PING", "PONG").encode("ascii"))
|
||||||
|
|
||||||
|
recv_file = sock.makefile(mode="r")
|
||||||
|
|
||||||
|
print(f"connect {server}:{port}")
|
||||||
|
sock.connect((server, port))
|
||||||
|
if server_password:
|
||||||
|
_send(f"PASS {server_password}")
|
||||||
|
_send(f"USER {nick} 0 * :{nick}")
|
||||||
|
_send(f"NICK {nick}")
|
||||||
|
for line in recv_file.readline():
|
||||||
|
if re.match(r"^:[^ ]* (MODE|221|376|422) ", line):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
_pong(line)
|
||||||
|
|
||||||
|
if sasl_password:
|
||||||
|
_send("CAP REQ :sasl")
|
||||||
|
_send("AUTHENTICATE PLAIN")
|
||||||
|
auth = base64.encodebytes(f"{nick}\0{nick}\0{sasl_password}".encode("utf-8"))
|
||||||
|
_send(f"AUTHENTICATE {auth.decode('ascii')}")
|
||||||
|
_send("CAP END")
|
||||||
|
_send(f"JOIN :{channel}")
|
||||||
|
|
||||||
|
for m in messages:
|
||||||
|
_send(f"PRIVMSG {channel} :{m}")
|
||||||
|
|
||||||
|
_send("INFO")
|
||||||
|
for line in recv_file:
|
||||||
|
if DEBUG:
|
||||||
|
print(line, end="")
|
||||||
|
# Assume INFO reply means we are done
|
||||||
|
if "End of /INFO" in line:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
_pong(line)
|
||||||
|
|
||||||
|
sock.send(b"QUIT")
|
||||||
|
print("disconnect")
|
||||||
|
sock.close()
|
||||||
|
|
||||||
|
|
||||||
|
def irc_send(
|
||||||
|
url: str, notifications: List[str], password: Optional[str] = None
|
||||||
|
) -> None:
|
||||||
|
parsed = urlparse(f"{url}")
|
||||||
|
username = parsed.username or "prometheus"
|
||||||
|
server = parsed.hostname or "chat.freenode.net"
|
||||||
|
if parsed.fragment != "":
|
||||||
|
channel = f"#{parsed.fragment}"
|
||||||
|
else:
|
||||||
|
channel = "#krebs-announce"
|
||||||
|
port = parsed.port or 6697
|
||||||
|
if not password:
|
||||||
|
password = parsed.password
|
||||||
|
if len(notifications) == 0:
|
||||||
|
return
|
||||||
|
_irc_send(
|
||||||
|
server=server,
|
||||||
|
nick=username,
|
||||||
|
sasl_password=password,
|
||||||
|
channel=channel,
|
||||||
|
port=port,
|
||||||
|
messages=notifications,
|
||||||
|
tls=parsed.scheme == "irc+tls",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class PrometheusWebHook(BaseHTTPRequestHandler):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
irc_url: str,
|
||||||
|
conn: socket.socket,
|
||||||
|
addr: Tuple[str, int],
|
||||||
|
password: Optional[str] = None,
|
||||||
|
) -> None:
|
||||||
|
self.irc_url = irc_url
|
||||||
|
self.password = password
|
||||||
|
self.rfile = conn.makefile("rb")
|
||||||
|
self.wfile = conn.makefile("wb")
|
||||||
|
self.client_address = addr
|
||||||
|
self.handle()
|
||||||
|
|
||||||
|
# for testing
|
||||||
|
def do_GET(self) -> None:
|
||||||
|
if DEBUG:
|
||||||
|
print("GET: Request Received")
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header("Content-type", "text/plain")
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(b"ok")
|
||||||
|
|
||||||
|
def do_POST(self) -> None:
|
||||||
|
if DEBUG:
|
||||||
|
print("POST: Request Received")
|
||||||
|
content_type, _ = cgi.parse_header(self.headers.get("content-type"))
|
||||||
|
|
||||||
|
# refuse to receive non-json content
|
||||||
|
if content_type != "application/json":
|
||||||
|
if DEBUG:
|
||||||
|
print(f"POST: wrong content type {content_type}")
|
||||||
|
self.send_response(400)
|
||||||
|
self.end_headers()
|
||||||
|
return
|
||||||
|
|
||||||
|
length = int(self.headers.get("content-length"))
|
||||||
|
payload = json.loads(self.rfile.read(length))
|
||||||
|
messages = []
|
||||||
|
for alert in payload["alerts"]:
|
||||||
|
description = alert["annotations"]["description"]
|
||||||
|
messages.append(f"{alert['status']}: {description}")
|
||||||
|
irc_send(self.irc_url, messages, password=self.password)
|
||||||
|
|
||||||
|
self.do_GET()
|
||||||
|
|
||||||
|
|
||||||
|
def systemd_socket_response() -> None:
|
||||||
|
irc_url = os.environ.get("IRC_URL", None)
|
||||||
|
if irc_url is None:
|
||||||
|
print(
|
||||||
|
"IRC_URL environment variable not set: i.e. IRC_URL=irc+tls://mic92-prometheus@chat.freenode.net/#krebs-announce",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
password = None
|
||||||
|
irc_password_file = os.environ.get("IRC_PASSWORD_FILE", None)
|
||||||
|
if irc_password_file:
|
||||||
|
with open(irc_password_file) as f:
|
||||||
|
password = f.read()
|
||||||
|
|
||||||
|
msgs = sys.argv[1:]
|
||||||
|
|
||||||
|
if msgs != []:
|
||||||
|
irc_send(irc_url, msgs, password=password)
|
||||||
|
return
|
||||||
|
|
||||||
|
nfds = os.environ.get("LISTEN_FDS", None)
|
||||||
|
if nfds is None:
|
||||||
|
print(
|
||||||
|
"LISTEN_FDS not set. Run me with systemd(TM) socket activation?",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
sys.exit(1)
|
||||||
|
fds = range(3, 3 + int(nfds))
|
||||||
|
|
||||||
|
for fd in fds:
|
||||||
|
sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
sock.settimeout(0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
PrometheusWebHook(irc_url, *sock.accept(), password=password)
|
||||||
|
except BlockingIOError:
|
||||||
|
# no more connections
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if DEBUG:
|
||||||
|
print("Starting in DEBUG mode")
|
||||||
|
if len(sys.argv) == 3:
|
||||||
|
print(f"{sys.argv[1]} {sys.argv[2]}")
|
||||||
|
irc_send(sys.argv[1], [sys.argv[2]])
|
||||||
|
else:
|
||||||
|
systemd_socket_response()
|
59
krebs/2configs/shack/prometheus/irc-hooks.nix
Normal file
59
krebs/2configs/shack/prometheus/irc-hooks.nix
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
{ config
|
||||||
|
, lib
|
||||||
|
, pkgs
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
irc-alerts = pkgs.writers.writePython3 "irc-alerts" {
|
||||||
|
flakeIgnore = [ "E501" ];
|
||||||
|
} (builtins.readFile ./irc-alerts.py);
|
||||||
|
endpoints = {
|
||||||
|
binaergewitter = {
|
||||||
|
url = "irc+tls://puyak-alerts@irc.libera.chat:6697/#binaergewitter-alerts";
|
||||||
|
port = 9223;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
systemd.sockets =
|
||||||
|
lib.mapAttrs'
|
||||||
|
(name: opts:
|
||||||
|
lib.nameValuePair "irc-alerts-${name}" {
|
||||||
|
description = "Receive http hook and send irc message for ${name}";
|
||||||
|
wantedBy = [ "sockets.target" ];
|
||||||
|
listenStreams = [ "[::]:${builtins.toString opts.port}" ];
|
||||||
|
}) endpoints;
|
||||||
|
|
||||||
|
systemd.services =
|
||||||
|
lib.mapAttrs'
|
||||||
|
(name: opts:
|
||||||
|
let
|
||||||
|
serviceName = "irc-alerts-${name}";
|
||||||
|
hasPassword = opts.passwordFile or null != null;
|
||||||
|
in
|
||||||
|
lib.nameValuePair serviceName {
|
||||||
|
description = "Receive http hook and send irc message for ${name}";
|
||||||
|
requires = [ "irc-alerts-${name}.socket" ];
|
||||||
|
serviceConfig =
|
||||||
|
{
|
||||||
|
Environment =
|
||||||
|
[
|
||||||
|
"IRC_URL=${opts.url}"
|
||||||
|
"DEBUG=y"
|
||||||
|
]
|
||||||
|
++ lib.optional hasPassword "IRC_PASSWORD_FILE=/run/${serviceName}/password";
|
||||||
|
DynamicUser = true;
|
||||||
|
User = serviceName;
|
||||||
|
ExecStart = irc-alerts;
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs hasPassword {
|
||||||
|
PermissionsStartOnly = true;
|
||||||
|
ExecStartPre =
|
||||||
|
"${pkgs.coreutils}/bin/install -m400 "
|
||||||
|
+ "-o ${serviceName} -g ${serviceName} "
|
||||||
|
+ "${config.sops.secrets.prometheus-irc-password.path} "
|
||||||
|
+ "/run/${serviceName}/password";
|
||||||
|
RuntimeDirectory = serviceName;
|
||||||
|
};
|
||||||
|
}) endpoints;
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./alert-rules.nix
|
./alert-rules.nix
|
||||||
|
./irc-hooks.nix
|
||||||
];
|
];
|
||||||
networking = {
|
networking = {
|
||||||
firewall.allowedTCPPorts = [
|
firewall.allowedTCPPorts = [
|
||||||
@ -129,11 +130,11 @@
|
|||||||
"group_wait" = "30s";
|
"group_wait" = "30s";
|
||||||
"group_interval" = "2m";
|
"group_interval" = "2m";
|
||||||
"repeat_interval" = "4h";
|
"repeat_interval" = "4h";
|
||||||
"receiver" = "team-admins";
|
"receiver" = "shack-admins";
|
||||||
};
|
};
|
||||||
"receivers" = [
|
"receivers" = [
|
||||||
{
|
{
|
||||||
"name" = "team-admins";
|
"name" = "shack-admins";
|
||||||
"email_configs" = [ ];
|
"email_configs" = [ ];
|
||||||
"webhook_configs" = [
|
"webhook_configs" = [
|
||||||
{
|
{
|
||||||
|
@ -14,8 +14,15 @@ in {
|
|||||||
#<stockholm/makefu/2configs/support-nixos.nix>
|
#<stockholm/makefu/2configs/support-nixos.nix>
|
||||||
# <stockholm/makefu/2configs/homeautomation/default.nix>
|
# <stockholm/makefu/2configs/homeautomation/default.nix>
|
||||||
# <stockholm/makefu/2configs/homeautomation/google-muell.nix>
|
# <stockholm/makefu/2configs/homeautomation/google-muell.nix>
|
||||||
|
# <stockholm/makefu/2configs/hw/pseyecam.nix>
|
||||||
# configure your hw:
|
# configure your hw:
|
||||||
# <stockholm/makefu/2configs/save-diskspace.nix>
|
# <stockholm/makefu/2configs/save-diskspace.nix>
|
||||||
|
|
||||||
|
# directly use the alsa device instead of attaching to pulse
|
||||||
|
|
||||||
|
<stockholm/makefu/2configs/audio/respeaker.nix>
|
||||||
|
<stockholm/makefu/2configs/home/rhasspy/default.nix>
|
||||||
|
<stockholm/makefu/2configs/home/rhasspy/led-control.nix>
|
||||||
];
|
];
|
||||||
krebs = {
|
krebs = {
|
||||||
enable = true;
|
enable = true;
|
||||||
@ -28,5 +35,4 @@ in {
|
|||||||
documentation.info.enable = false;
|
documentation.info.enable = false;
|
||||||
documentation.man.enable = false;
|
documentation.man.enable = false;
|
||||||
documentation.nixos.enable = false;
|
documentation.nixos.enable = false;
|
||||||
sound.enable = false;
|
|
||||||
}
|
}
|
||||||
|
@ -10,5 +10,6 @@
|
|||||||
options = [ "noatime" ];
|
options = [ "noatime" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
#hardware.raspberry-pi."4".fkms-3d.enable = true;
|
hardware.raspberry-pi."4".fkms-3d.enable = true;
|
||||||
|
hardware.raspberry-pi."4".audio.enable = true;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,12 @@ in {
|
|||||||
imports = [
|
imports = [
|
||||||
<stockholm/makefu>
|
<stockholm/makefu>
|
||||||
./hetznercloud
|
./hetznercloud
|
||||||
|
{
|
||||||
|
# wait for mount
|
||||||
|
systemd.services.rtorrent.wantedBy = lib.mkForce [];
|
||||||
|
systemd.services.phpfpm-nextcloud.wantedBy = lib.mkForce [];
|
||||||
|
systemd.services.samba-smbd.wantedBy = lib.mkForce [];
|
||||||
|
}
|
||||||
{
|
{
|
||||||
users.users.lass = {
|
users.users.lass = {
|
||||||
uid = 19002;
|
uid = 19002;
|
||||||
@ -103,6 +109,7 @@ in {
|
|||||||
# <stockholm/makefu/2configs/sabnzbd.nix>
|
# <stockholm/makefu/2configs/sabnzbd.nix>
|
||||||
# <stockholm/makefu/2configs/mail/mail.euer.nix>
|
# <stockholm/makefu/2configs/mail/mail.euer.nix>
|
||||||
{ krebs.exim.enable = mkDefault true; }
|
{ krebs.exim.enable = mkDefault true; }
|
||||||
|
<stockholm/makefu/2configs/nix-community/mediawiki-matrix-bot.nix>
|
||||||
|
|
||||||
# sharing
|
# sharing
|
||||||
<stockholm/makefu/2configs/share/gum.nix> # samba sahre
|
<stockholm/makefu/2configs/share/gum.nix> # samba sahre
|
||||||
@ -125,7 +132,7 @@ in {
|
|||||||
<stockholm/makefu/2configs/backup/server.nix>
|
<stockholm/makefu/2configs/backup/server.nix>
|
||||||
<stockholm/makefu/2configs/backup/state.nix>
|
<stockholm/makefu/2configs/backup/state.nix>
|
||||||
<stockholm/makefu/2configs/wireguard/server.nix>
|
<stockholm/makefu/2configs/wireguard/server.nix>
|
||||||
# <stockholm/makefu/2configs/wireguard/wiregrill.nix>
|
<stockholm/makefu/2configs/wireguard/wiregrill.nix>
|
||||||
|
|
||||||
{ # recent changes mediawiki bot
|
{ # recent changes mediawiki bot
|
||||||
networking.firewall.allowedUDPPorts = [ 5005 5006 ];
|
networking.firewall.allowedUDPPorts = [ 5005 5006 ];
|
||||||
@ -139,6 +146,7 @@ in {
|
|||||||
<stockholm/makefu/2configs/deployment/rss/rss.euer.krebsco.de.nix> # postgres backend
|
<stockholm/makefu/2configs/deployment/rss/rss.euer.krebsco.de.nix> # postgres backend
|
||||||
<stockholm/makefu/2configs/deployment/rss/ratt.nix>
|
<stockholm/makefu/2configs/deployment/rss/ratt.nix>
|
||||||
|
|
||||||
|
<stockholm/makefu/2configs/deployment/ntfysh.nix>
|
||||||
<stockholm/makefu/2configs/deployment/owncloud.nix> #postgres backend
|
<stockholm/makefu/2configs/deployment/owncloud.nix> #postgres backend
|
||||||
### Moving owncloud data dir to /media/cloud/nextcloud-data
|
### Moving owncloud data dir to /media/cloud/nextcloud-data
|
||||||
{
|
{
|
||||||
@ -173,7 +181,7 @@ in {
|
|||||||
# <stockholm/makefu/2configs/nginx/iso.euer.nix>
|
# <stockholm/makefu/2configs/nginx/iso.euer.nix>
|
||||||
|
|
||||||
# <stockholm/makefu/2configs/deployment/photostore.krebsco.de.nix>
|
# <stockholm/makefu/2configs/deployment/photostore.krebsco.de.nix>
|
||||||
<stockholm/makefu/2configs/deployment/graphs.nix>
|
# <stockholm/makefu/2configs/deployment/graphs.nix>
|
||||||
#<stockholm/makefu/2configs/deployment/owncloud.nix>
|
#<stockholm/makefu/2configs/deployment/owncloud.nix>
|
||||||
# <stockholm/makefu/2configs/deployment/board.euer.krebsco.de.nix>
|
# <stockholm/makefu/2configs/deployment/board.euer.krebsco.de.nix>
|
||||||
#<stockholm/makefu/2configs/deployment/feed.euer.krebsco.de>
|
#<stockholm/makefu/2configs/deployment/feed.euer.krebsco.de>
|
||||||
@ -184,7 +192,7 @@ in {
|
|||||||
<stockholm/makefu/2configs/bgt/etherpad.euer.krebsco.de.nix>
|
<stockholm/makefu/2configs/bgt/etherpad.euer.krebsco.de.nix>
|
||||||
# <stockholm/makefu/2configs/deployment/systemdultras-rss.nix>
|
# <stockholm/makefu/2configs/deployment/systemdultras-rss.nix>
|
||||||
|
|
||||||
# <stockholm/makefu/2configs/shiori.nix>
|
<stockholm/makefu/2configs/shiori.nix>
|
||||||
#<stockholm/makefu/2configs/workadventure>
|
#<stockholm/makefu/2configs/workadventure>
|
||||||
|
|
||||||
<stockholm/makefu/2configs/bgt/download.binaergewitter.de.nix>
|
<stockholm/makefu/2configs/bgt/download.binaergewitter.de.nix>
|
||||||
|
@ -3,7 +3,7 @@ let
|
|||||||
external-mac = "96:00:01:24:33:f4";
|
external-mac = "96:00:01:24:33:f4";
|
||||||
external-gw = "172.31.1.1";
|
external-gw = "172.31.1.1";
|
||||||
external-ip = "142.132.189.140";
|
external-ip = "142.132.189.140";
|
||||||
external-ip6 = "2a01:4f8:1c17:5cdf::2/64";
|
external-ip6 = "2a01:4f8:1c17:5cdf::2";
|
||||||
external-gw6 = "fe80::1";
|
external-gw6 = "fe80::1";
|
||||||
external-netmask = 32;
|
external-netmask = 32;
|
||||||
external-netmask6 = 64;
|
external-netmask6 = 64;
|
||||||
@ -16,19 +16,20 @@ in
|
|||||||
SUBSYSTEM=="net", ATTR{address}=="${external-mac}", NAME="${ext-if}"
|
SUBSYSTEM=="net", ATTR{address}=="${external-mac}", NAME="${ext-if}"
|
||||||
'';
|
'';
|
||||||
networking = {
|
networking = {
|
||||||
|
enableIPv6 = true;
|
||||||
|
nat.enableIPv6 = true;
|
||||||
interfaces."${ext-if}" = {
|
interfaces."${ext-if}" = {
|
||||||
useDHCP = true;
|
useDHCP = true;
|
||||||
|
ipv6.addresses = [{
|
||||||
|
address = external-ip6;
|
||||||
|
prefixLength = external-netmask6;
|
||||||
|
}];
|
||||||
};
|
};
|
||||||
#ipv4.addresses = [{
|
#ipv4.addresses = [{
|
||||||
# address = external-ip;
|
# address = external-ip;
|
||||||
# prefixLength = external-netmask;
|
# prefixLength = external-netmask;
|
||||||
#}];
|
#}];
|
||||||
#ipv6.addresses = [{
|
defaultGateway6 = { address = external-gw6; interface = ext-if; };
|
||||||
# address = external-ip6;
|
|
||||||
# prefixLength = external-netmask6;
|
|
||||||
# }];
|
|
||||||
#};
|
|
||||||
#defaultGateway6 = { address = external-gw6; interface = ext-if; };
|
|
||||||
#defaultGateway = external-gw;
|
#defaultGateway = external-gw;
|
||||||
nameservers = [ "1.1.1.1" ];
|
nameservers = [ "1.1.1.1" ];
|
||||||
};
|
};
|
||||||
|
@ -32,8 +32,6 @@ in {
|
|||||||
<stockholm/makefu/2configs/share>
|
<stockholm/makefu/2configs/share>
|
||||||
# <stockholm/makefu/2configs/share/hetzner-client.nix>
|
# <stockholm/makefu/2configs/share/hetzner-client.nix>
|
||||||
|
|
||||||
# Services:
|
|
||||||
<stockholm/makefu/2configs/nix-community/mediawiki-matrix-bot.nix>
|
|
||||||
|
|
||||||
# torrent is managed by gum
|
# torrent is managed by gum
|
||||||
# <stockholm/makefu/2configs/torrent/rtorrent.nix>
|
# <stockholm/makefu/2configs/torrent/rtorrent.nix>
|
||||||
|
27
makefu/1systems/minicake/config.nix
Normal file
27
makefu/1systems/minicake/config.nix
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{ config,nixpkgsPath, pkgs, lib, ... }:
|
||||||
|
{
|
||||||
|
krebs = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
dns.providers.lan = "hosts";
|
||||||
|
build.user = config.krebs.users.makefu;
|
||||||
|
};
|
||||||
|
imports = [
|
||||||
|
(nixpkgsPath + "/nixos/modules/profiles/minimal.nix")
|
||||||
|
(nixpkgsPath + "/nixos/modules/profiles/installation-device.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
# cifs-utils fails to cross-compile
|
||||||
|
# Let's simplify this by removing all unneeded filesystems from the image.
|
||||||
|
boot.supportedFilesystems = lib.mkForce [ "vfat" ];
|
||||||
|
|
||||||
|
boot.kernelPackages = lib.mkDefault pkgs.linuxPackages_latest;
|
||||||
|
|
||||||
|
|
||||||
|
users.users = {
|
||||||
|
root = {
|
||||||
|
openssh.authorizedKeys.keys = [ config.krebs.users.makefu.pubkey ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.openssh.enable = true;
|
||||||
|
}
|
@ -54,17 +54,19 @@ in {
|
|||||||
<stockholm/makefu/2configs/share/omo.nix>
|
<stockholm/makefu/2configs/share/omo.nix>
|
||||||
<stockholm/makefu/2configs/share/gum-client.nix>
|
<stockholm/makefu/2configs/share/gum-client.nix>
|
||||||
<stockholm/makefu/2configs/sync>
|
<stockholm/makefu/2configs/sync>
|
||||||
<stockholm/makefu/2configs/dcpp/airdcpp.nix>
|
|
||||||
{ krebs.airdcpp.dcpp.shares = let
|
<stockholm/makefu/2configs/wireguard/wiregrill.nix>
|
||||||
d = path: "/media/cryptX/${path}";
|
#<stockholm/makefu/2configs/dcpp/airdcpp.nix>
|
||||||
in {
|
#{ krebs.airdcpp.dcpp.shares = let
|
||||||
emu.path = d "emu";
|
# d = path: "/media/cryptX/${path}";
|
||||||
audiobooks.path = lib.mkForce (d "audiobooks");
|
# in {
|
||||||
incoming.path = lib.mkForce (d "torrent");
|
# emu.path = d "emu";
|
||||||
anime.path = d "anime";
|
# audiobooks.path = lib.mkForce (d "audiobooks");
|
||||||
};
|
# incoming.path = lib.mkForce (d "torrent");
|
||||||
krebs.airdcpp.dcpp.DownloadDirectory = "/media/cryptX/torrent/dcpp";
|
# anime.path = d "anime";
|
||||||
}
|
# };
|
||||||
|
# krebs.airdcpp.dcpp.DownloadDirectory = "/media/cryptX/torrent/dcpp";
|
||||||
|
#}
|
||||||
{
|
{
|
||||||
# copy config from <secrets/sabnzbd.ini> to /var/lib/sabnzbd/
|
# copy config from <secrets/sabnzbd.ini> to /var/lib/sabnzbd/
|
||||||
#services.sabnzbd.enable = true;
|
#services.sabnzbd.enable = true;
|
||||||
@ -84,12 +86,12 @@ in {
|
|||||||
<stockholm/makefu/2configs/stats/telegraf>
|
<stockholm/makefu/2configs/stats/telegraf>
|
||||||
# <stockholm/makefu/2configs/stats/telegraf/europastats.nix>
|
# <stockholm/makefu/2configs/stats/telegraf/europastats.nix>
|
||||||
<stockholm/makefu/2configs/stats/telegraf/hamstats.nix>
|
<stockholm/makefu/2configs/stats/telegraf/hamstats.nix>
|
||||||
# <stockholm/makefu/2configs/stats/arafetch.nix>
|
<stockholm/makefu/2configs/hw/cdrip.nix>
|
||||||
|
|
||||||
# services
|
# services
|
||||||
{
|
{
|
||||||
services.nginx.enable = true;
|
services.nginx.enable = true;
|
||||||
networking.firewall.allowedTCPPorts = [ 80 ];
|
networking.firewall.allowedTCPPorts = [ 80 8123 ];
|
||||||
}
|
}
|
||||||
# <stockholm/makefu/2configs/syncthing.nix>
|
# <stockholm/makefu/2configs/syncthing.nix>
|
||||||
<stockholm/makefu/2configs/remote-build/slave.nix>
|
<stockholm/makefu/2configs/remote-build/slave.nix>
|
||||||
@ -100,10 +102,11 @@ in {
|
|||||||
<stockholm/makefu/2configs/home/jellyfin.nix>
|
<stockholm/makefu/2configs/home/jellyfin.nix>
|
||||||
<stockholm/makefu/2configs/home/music.nix>
|
<stockholm/makefu/2configs/home/music.nix>
|
||||||
<stockholm/makefu/2configs/home/photoprism.nix>
|
<stockholm/makefu/2configs/home/photoprism.nix>
|
||||||
<stockholm/makefu/2configs/home/tonie.nix>
|
# <stockholm/makefu/2configs/home/tonie.nix>
|
||||||
<stockholm/makefu/2configs/home/ps4srv.nix>
|
<stockholm/makefu/2configs/home/ps4srv.nix>
|
||||||
# <stockholm/makefu/2configs/home/metube.nix>
|
# <stockholm/makefu/2configs/home/metube.nix>
|
||||||
<stockholm/makefu/2configs/home/ham>
|
# <stockholm/makefu/2configs/home/ham>
|
||||||
|
<stockholm/makefu/2configs/home/ham/docker.nix>
|
||||||
<stockholm/makefu/2configs/home/zigbee2mqtt>
|
<stockholm/makefu/2configs/home/zigbee2mqtt>
|
||||||
{
|
{
|
||||||
makefu.ps3netsrv = {
|
makefu.ps3netsrv = {
|
||||||
|
@ -10,7 +10,7 @@ in {
|
|||||||
<stockholm/makefu/2configs/binary-cache/nixos.nix>
|
<stockholm/makefu/2configs/binary-cache/nixos.nix>
|
||||||
|
|
||||||
<stockholm/makefu/2configs/home/rhasspy>
|
<stockholm/makefu/2configs/home/rhasspy>
|
||||||
<stockholm/makefu/2configs/home/rhasspy/led-control.nix>
|
# <stockholm/makefu/2configs/hw/pseyecam.nix>
|
||||||
];
|
];
|
||||||
krebs = {
|
krebs = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
<nixpkgs/nixos/modules/installer/scan/not-detected.nix>
|
<nixpkgs/nixos/modules/installer/scan/not-detected.nix>
|
||||||
|
./wifi.nix
|
||||||
|
./sound.nix
|
||||||
];
|
];
|
||||||
boot.loader.grub.enable = true;
|
boot.loader.grub.enable = true;
|
||||||
boot.loader.grub.version = 2;
|
boot.loader.grub.version = 2;
|
||||||
@ -18,4 +20,5 @@
|
|||||||
|
|
||||||
boot.kernelParams = [ "net.ifnames=0" ];
|
boot.kernelParams = [ "net.ifnames=0" ];
|
||||||
networking.hostId = "0123AABB";
|
networking.hostId = "0123AABB";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
51
makefu/1systems/snake/sound.nix
Normal file
51
makefu/1systems/snake/sound.nix
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
{ lib, ... }: {
|
||||||
|
imports = [
|
||||||
|
<stockholm/makefu/2configs/gui/snake-kiosk.nix>
|
||||||
|
];
|
||||||
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
networking.networkmanager.enable = lib.mkForce false;
|
||||||
|
# sound.enable = true;
|
||||||
|
#hardware.pulseaudio = {
|
||||||
|
# enable = true;
|
||||||
|
# systemWide = true;
|
||||||
|
# tcp = {
|
||||||
|
# enable = true;
|
||||||
|
# anonymousClients.allowAll = true;
|
||||||
|
# };
|
||||||
|
#};
|
||||||
|
|
||||||
|
#users.users.makefu = {
|
||||||
|
# extraGroups = [ "pipewire" "audio" ];
|
||||||
|
#};
|
||||||
|
|
||||||
|
|
||||||
|
#services.xserver = {
|
||||||
|
# enable = true;
|
||||||
|
# # desktopManager.xterm.enable = true;
|
||||||
|
# desktopManager.xfce = {
|
||||||
|
# enable = true;
|
||||||
|
# noDesktop = true;
|
||||||
|
# };
|
||||||
|
|
||||||
|
# displayManager.autoLogin = {
|
||||||
|
# enable = true;
|
||||||
|
# user = "makefu";
|
||||||
|
# };
|
||||||
|
#};
|
||||||
|
hardware.pulseaudio.enable = lib.mkForce false;
|
||||||
|
security.rtkit.enable = true;
|
||||||
|
#services.pipewire = {
|
||||||
|
# enable = true;
|
||||||
|
# systemWide = true;
|
||||||
|
# socketActivation = false;
|
||||||
|
# alsa.enable = true;
|
||||||
|
# alsa.support32Bit = true;
|
||||||
|
# pulse.enable = true;
|
||||||
|
# config.pipewire-pulse = {
|
||||||
|
# "pulse.properties"."server.address" = [ "unix:native" "tcp:4713" ];
|
||||||
|
# };
|
||||||
|
|
||||||
|
#};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -3,5 +3,4 @@
|
|||||||
full = true;
|
full = true;
|
||||||
home-manager = true;
|
home-manager = true;
|
||||||
hw = true;
|
hw = true;
|
||||||
disko = true;
|
|
||||||
}
|
}
|
||||||
|
6
makefu/1systems/snake/wifi.nix
Normal file
6
makefu/1systems/snake/wifi.nix
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
networking.wireless = {
|
||||||
|
enable = true;
|
||||||
|
networks = import <secrets/wifi.nix>;
|
||||||
|
};
|
||||||
|
}
|
@ -22,7 +22,7 @@ in {
|
|||||||
# <stockholm/makefu/2configs/virtualisation/virtualbox.nix>
|
# <stockholm/makefu/2configs/virtualisation/virtualbox.nix>
|
||||||
<stockholm/makefu/2configs/tinc/retiolum.nix>
|
<stockholm/makefu/2configs/tinc/retiolum.nix>
|
||||||
<stockholm/makefu/2configs/gui/wbob-kiosk.nix>
|
<stockholm/makefu/2configs/gui/wbob-kiosk.nix>
|
||||||
{ environment.systemPackages = [ pkgs.nano ]; }
|
{ environment.systemPackages = [ pkgs.brother_ql_web pkgs.nano ]; }
|
||||||
|
|
||||||
# <stockholm/makefu/2configs/gui/studio-virtual.nix>
|
# <stockholm/makefu/2configs/gui/studio-virtual.nix>
|
||||||
# <stockholm/makefu/2configs/audio/jack-on-pulse.nix>
|
# <stockholm/makefu/2configs/audio/jack-on-pulse.nix>
|
||||||
@ -53,6 +53,7 @@ in {
|
|||||||
|
|
||||||
<stockholm/makefu/2configs/bureautomation> # new hass entry point
|
<stockholm/makefu/2configs/bureautomation> # new hass entry point
|
||||||
<stockholm/makefu/2configs/bureautomation/led-fader.nix>
|
<stockholm/makefu/2configs/bureautomation/led-fader.nix>
|
||||||
|
<stockholm/makefu/2configs/bureautomation/printer.nix>
|
||||||
# <stockholm/makefu/2configs/bureautomation/kalauerbot.nix> now runs in thales
|
# <stockholm/makefu/2configs/bureautomation/kalauerbot.nix> now runs in thales
|
||||||
# <stockholm/makefu/2configs/bureautomation/visitor-photostore.nix>
|
# <stockholm/makefu/2configs/bureautomation/visitor-photostore.nix>
|
||||||
# <stockholm/makefu/2configs/bureautomation/mpd.nix> #mpd is only used for TTS, this is the web interface
|
# <stockholm/makefu/2configs/bureautomation/mpd.nix> #mpd is only used for TTS, this is the web interface
|
||||||
@ -100,7 +101,9 @@ in {
|
|||||||
<stockholm/makefu/2configs/backup/state.nix>
|
<stockholm/makefu/2configs/backup/state.nix>
|
||||||
# temporary
|
# temporary
|
||||||
# <stockholm/makefu/2configs/temp/rst-issue.nix>
|
# <stockholm/makefu/2configs/temp/rst-issue.nix>
|
||||||
{ services.jellyfin.enable = true; }
|
{
|
||||||
|
services.jellyfin.enable = true;
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
krebs = {
|
krebs = {
|
||||||
|
@ -48,6 +48,16 @@
|
|||||||
{ bits = 4096; path = (toString <secrets/ssh_host_rsa_key>); type = "rsa";}
|
{ bits = 4096; path = (toString <secrets/ssh_host_rsa_key>); type = "rsa";}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
#{
|
||||||
|
# imports = [
|
||||||
|
# <stockholm/makefu/2configs/bureautomation/rhasspy.nix>
|
||||||
|
# ];
|
||||||
|
# services.pipewire.config.pipewire-pulse = {
|
||||||
|
# "pulse.properties"."server.address" = [ "unix:native" "tcp:4713" ];
|
||||||
|
# };
|
||||||
|
# networking.firewall.allowedTCPPorts = [ 4713 ];
|
||||||
|
|
||||||
|
#}
|
||||||
|
|
||||||
#{
|
#{
|
||||||
# users.users.makefu.packages = with pkgs;[ mpc_cli ncmpcpp ];
|
# users.users.makefu.packages = with pkgs;[ mpc_cli ncmpcpp ];
|
||||||
@ -130,7 +140,7 @@
|
|||||||
# <stockholm/makefu/2configs/deployment/hound>
|
# <stockholm/makefu/2configs/deployment/hound>
|
||||||
# <stockholm/makefu/2configs/deployment/photostore.krebsco.de.nix>
|
# <stockholm/makefu/2configs/deployment/photostore.krebsco.de.nix>
|
||||||
# <stockholm/makefu/2configs/deployment/bureautomation/hass.nix>
|
# <stockholm/makefu/2configs/deployment/bureautomation/hass.nix>
|
||||||
<stockholm/makefu/2configs/bureautomation/office-radio>
|
# <stockholm/makefu/2configs/bureautomation/office-radio>
|
||||||
|
|
||||||
# Krebs
|
# Krebs
|
||||||
<stockholm/makefu/2configs/tinc/retiolum.nix>
|
<stockholm/makefu/2configs/tinc/retiolum.nix>
|
||||||
@ -146,7 +156,7 @@
|
|||||||
<stockholm/makefu/2configs/mail-client.nix>
|
<stockholm/makefu/2configs/mail-client.nix>
|
||||||
<stockholm/makefu/2configs/printer.nix>
|
<stockholm/makefu/2configs/printer.nix>
|
||||||
# <stockholm/makefu/2configs/syncthing.nix>
|
# <stockholm/makefu/2configs/syncthing.nix>
|
||||||
<stockholm/makefu/2configs/sync>
|
# <stockholm/makefu/2configs/sync>
|
||||||
|
|
||||||
# Virtualization
|
# Virtualization
|
||||||
# <stockholm/makefu/2configs/virtualisation/libvirt.nix>
|
# <stockholm/makefu/2configs/virtualisation/libvirt.nix>
|
||||||
@ -179,6 +189,7 @@
|
|||||||
|
|
||||||
# temporary
|
# temporary
|
||||||
# { services.redis.enable = true; }
|
# { services.redis.enable = true; }
|
||||||
|
# citadel exporter
|
||||||
# { services.mongodb.enable = true; }
|
# { services.mongodb.enable = true; }
|
||||||
# { services.elasticsearch.enable = true; }
|
# { services.elasticsearch.enable = true; }
|
||||||
# <stockholm/makefu/2configs/deployment/nixos.wiki>
|
# <stockholm/makefu/2configs/deployment/nixos.wiki>
|
||||||
@ -189,27 +200,28 @@
|
|||||||
# <stockholm/makefu/2configs/lanparty/lancache-dns.nix>
|
# <stockholm/makefu/2configs/lanparty/lancache-dns.nix>
|
||||||
# <stockholm/makefu/2configs/lanparty/samba.nix>
|
# <stockholm/makefu/2configs/lanparty/samba.nix>
|
||||||
# <stockholm/makefu/2configs/lanparty/mumble-server.nix>
|
# <stockholm/makefu/2configs/lanparty/mumble-server.nix>
|
||||||
|
<stockholm/makefu/2configs/wireguard/wiregrill.nix>
|
||||||
|
|
||||||
{
|
# {
|
||||||
networking.wireguard.interfaces.wg0 = {
|
# networking.wireguard.interfaces.wg0 = {
|
||||||
ips = [ "10.244.0.2/24" ];
|
# ips = [ "10.244.0.2/24" ];
|
||||||
privateKeyFile = (toString <secrets>) + "/wireguard.key";
|
# privateKeyFile = (toString <secrets>) + "/wireguard.key";
|
||||||
allowedIPsAsRoutes = true;
|
# allowedIPsAsRoutes = true;
|
||||||
peers = [
|
# peers = [
|
||||||
{
|
# {
|
||||||
# gum
|
# # gum
|
||||||
endpoint = "${config.krebs.hosts.gum.nets.internet.ip4.addr}:51820";
|
# endpoint = "${config.krebs.hosts.gum.nets.internet.ip4.addr}:51820";
|
||||||
allowedIPs = [ "10.244.0.0/24" ];
|
# allowedIPs = [ "10.244.0.0/24" ];
|
||||||
publicKey = "yAKvxTvcEVdn+MeKsmptZkR3XSEue+wSyLxwcjBYxxo=";
|
# publicKey = "yAKvxTvcEVdn+MeKsmptZkR3XSEue+wSyLxwcjBYxxo=";
|
||||||
}
|
# }
|
||||||
#{
|
# #{
|
||||||
# # vbob
|
# # # vbob
|
||||||
# allowedIPs = [ "10.244.0.3/32" ];
|
# # allowedIPs = [ "10.244.0.3/32" ];
|
||||||
# publicKey = "Lju7EsCu1OWXhkhdNR7c/uiN60nr0TUPHQ+s8ULPQTw=";
|
# # publicKey = "Lju7EsCu1OWXhkhdNR7c/uiN60nr0TUPHQ+s8ULPQTw=";
|
||||||
#}
|
# #}
|
||||||
];
|
# ];
|
||||||
};
|
# };
|
||||||
}
|
# }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
6
makefu/1systems/x/x13/battery.nix
Normal file
6
makefu/1systems/x/x13/battery.nix
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
powerManagement.powertop.enable = true;
|
||||||
|
services.power-profiles-daemon.enable = true;
|
||||||
|
users.users.makefu.packages = [ pkgs.gnome.gnome-power-manager ];
|
||||||
|
}
|
@ -4,6 +4,7 @@
|
|||||||
imports = [
|
imports = [
|
||||||
./zfs.nix
|
./zfs.nix
|
||||||
./input.nix
|
./input.nix
|
||||||
|
./battery.nix
|
||||||
<stockholm/makefu/2configs/hw/bluetooth.nix>
|
<stockholm/makefu/2configs/hw/bluetooth.nix>
|
||||||
<nixos-hardware/lenovo/thinkpad/l14/amd> # close enough
|
<nixos-hardware/lenovo/thinkpad/l14/amd> # close enough
|
||||||
# <stockholm/makefu/2configs/hw/tpm.nix>
|
# <stockholm/makefu/2configs/hw/tpm.nix>
|
||||||
@ -17,23 +18,26 @@
|
|||||||
|
|
||||||
# services.xserver.enable = lib.mkForce false;
|
# services.xserver.enable = lib.mkForce false;
|
||||||
|
|
||||||
services.xserver.videoDrivers = [
|
services.xserver.videoDrivers = [ "amdgpu" ];
|
||||||
"amdgpu"
|
boot.initrd.kernelModules = [ "amdgpu" ];
|
||||||
|
hardware.opengl.driSupport = true;
|
||||||
|
hardware.opengl.extraPackages = [ pkgs.amdvlk pkgs.rocm-opencl-icd pkgs.rocm-opencl-runtime ];
|
||||||
|
# For 32 bit applications
|
||||||
|
hardware.opengl.driSupport32Bit = true;
|
||||||
|
hardware.opengl.extraPackages32 = with pkgs; [
|
||||||
|
driversi686Linux.amdvlk
|
||||||
];
|
];
|
||||||
hardware.opengl.extraPackages = [ pkgs.amdvlk pkgs.rocm-opencl-icd ];
|
|
||||||
# is required for amd graphics support ( xorg wont boot otherwise )
|
# is required for amd graphics support ( xorg wont boot otherwise )
|
||||||
#boot.kernelPackages = pkgs.linuxPackages_latest;
|
#boot.kernelPackages = pkgs.linuxPackages_latest;
|
||||||
boot.kernelPackages = lib.mkForce pkgs.linuxPackages;
|
boot.kernelPackages = lib.mkForce pkgs.linuxPackages;
|
||||||
|
|
||||||
environment.variables.VK_ICD_FILENAMES =
|
|
||||||
"/run/opengl-driver/share/vulkan/icd.d/amd_icd64.json";
|
|
||||||
|
|
||||||
services.fwupd.enable = true;
|
services.fwupd.enable = true;
|
||||||
|
|
||||||
programs.light.enable = true;
|
programs.light.enable = true;
|
||||||
|
|
||||||
users.groups.video = {};
|
users.groups.video = {};
|
||||||
users.users.makefu.extraGroups = [ "video" ];
|
users.groups.render = {};
|
||||||
|
users.users.makefu.extraGroups = [ "video" "render" ];
|
||||||
|
|
||||||
boot.extraModprobeConfig = ''
|
boot.extraModprobeConfig = ''
|
||||||
options thinkpad_acpi fan_control=1
|
options thinkpad_acpi fan_control=1
|
||||||
|
67
makefu/1systems/x/x13/disk.nix
Normal file
67
makefu/1systems/x/x13/disk.nix
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
{ disk ? "/dev/sda", ... }: {
|
||||||
|
disko.devices = {
|
||||||
|
disk = {
|
||||||
|
nvme = {
|
||||||
|
type = "disk";
|
||||||
|
device = disk;
|
||||||
|
content = {
|
||||||
|
type = "table";
|
||||||
|
format = "gpt";
|
||||||
|
partitions = [
|
||||||
|
{
|
||||||
|
name = "ESP";
|
||||||
|
start = "0";
|
||||||
|
end = "512MiB";
|
||||||
|
fs-type = "fat32";
|
||||||
|
bootable = true;
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "vfat";
|
||||||
|
mountpoint = "/boot";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "zfs";
|
||||||
|
start = "512MiB";
|
||||||
|
end = "100%";
|
||||||
|
content = {
|
||||||
|
type = "zfs";
|
||||||
|
pool = "tank";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
zpool = {
|
||||||
|
tank = {
|
||||||
|
type = "zpool";
|
||||||
|
rootFsOptions = {
|
||||||
|
compression = "lz4";
|
||||||
|
#reservation = "5G";
|
||||||
|
"com.sun:auto-snapshot" = "false";
|
||||||
|
};
|
||||||
|
mountpoint = null;
|
||||||
|
postCreateHook = "zfs snapshot tank@blank";
|
||||||
|
|
||||||
|
datasets = {
|
||||||
|
|
||||||
|
root = {
|
||||||
|
type = "zfs_fs";
|
||||||
|
mountpoint = "/";
|
||||||
|
options = {
|
||||||
|
encryption = "aes-256-gcm";
|
||||||
|
keyformat = "passphrase";
|
||||||
|
"com.sun:auto-snapshot" = "true";
|
||||||
|
};
|
||||||
|
#keylocation = "file:///tmp/secret.key";
|
||||||
|
};
|
||||||
|
"root/home" = {
|
||||||
|
type = "zfs_fs";
|
||||||
|
mountpoint = "/home";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -4,14 +4,16 @@
|
|||||||
# 1. for pressing insert hold shift+fn+Fin
|
# 1. for pressing insert hold shift+fn+Fin
|
||||||
|
|
||||||
# scroll by holding middle mouse
|
# scroll by holding middle mouse
|
||||||
services.xserver.displayManager.sessionCommands =''
|
#services.xserver.displayManager.sessionCommands =''
|
||||||
xinput set-int-prop "ETPS/2 Elantech TrackPoint" "Evdev Wheel Emulation" 8 1
|
# xinput set-int-prop "ETPS/2 Elantech TrackPoint" "Evdev Wheel Emulation" 8 1
|
||||||
xinput set-int-prop "ETPS/2 Elantech TrackPoint" "Evdev Wheel Emulation Button" 8 2
|
# xinput set-int-prop "ETPS/2 Elantech TrackPoint" "Evdev Wheel Emulation Button" 8 2
|
||||||
xinput set-prop "ETPS/2 Elantech TrackPoint" "Evdev Wheel Emulation Axes" 6 7 4 5
|
# xinput set-prop "ETPS/2 Elantech TrackPoint" "Evdev Wheel Emulation Axes" 6 7 4 5
|
||||||
# configure timeout of pressing and holding middle button
|
# # configure timeout of pressing and holding middle button
|
||||||
# xinput set-int-prop "ETPS/2 Elantech TrackPoint" "Evdev Wheel Emulation Timeout" 8 200
|
# # xinput set-int-prop "ETPS/2 Elantech TrackPoint" "Evdev Wheel Emulation Timeout" 8 200
|
||||||
xinput disable 'ETPS/2 Elantech Touchpad'
|
# xinput disable 'ETPS/2 Elantech Touchpad'
|
||||||
'';
|
#'';
|
||||||
|
|
||||||
|
services.xserver.libinput.enable = true;
|
||||||
boot.kernelParams = [
|
boot.kernelParams = [
|
||||||
#"psmouse.proto=imps"
|
#"psmouse.proto=imps"
|
||||||
#"psmouse.proto=bare"
|
#"psmouse.proto=bare"
|
||||||
@ -27,20 +29,20 @@
|
|||||||
{ keys = [ 224 ]; events = [ "key" ]; command = "${pkgs.light}/bin/light -U 10"; } # fn - F6
|
{ keys = [ 224 ]; events = [ "key" ]; command = "${pkgs.light}/bin/light -U 10"; } # fn - F6
|
||||||
# fn - 4 => suspend
|
# fn - 4 => suspend
|
||||||
# fn - d => lcdshadow
|
# fn - d => lcdshadow
|
||||||
{ keys = [ 227 ]; events = [ "key" ]; command = builtins.toString ( # fn - F7
|
#{ keys = [ 227 ]; events = [ "key" ]; command = builtins.toString ( # fn - F7
|
||||||
pkgs.writers.writeDash "toggle_touchpad" ''
|
# pkgs.writers.writeDash "toggle_touchpad" ''
|
||||||
PATH=${lib.makeBinPath [ pkgs.xorg.xinput pkgs.gnugrep ]}
|
# PATH=${lib.makeBinPath [ pkgs.xorg.xinput pkgs.gnugrep ]}
|
||||||
DISPLAY=:0
|
# DISPLAY=:0
|
||||||
export DISPLAY PATH
|
# export DISPLAY PATH
|
||||||
|
|
||||||
device=$(xinput list --name-only | grep Touchpad)
|
# device=$(xinput list --name-only | grep Touchpad)
|
||||||
if [ "$(xinput list-props "$device" | grep -P ".*Device Enabled.*\K.(?=$)" -o)" -eq 1 ];then
|
# if [ "$(xinput list-props "$device" | grep -P ".*Device Enabled.*\K.(?=$)" -o)" -eq 1 ];then
|
||||||
xinput disable "$device"
|
# xinput disable "$device"
|
||||||
else
|
# else
|
||||||
xinput enable "$device"
|
# xinput enable "$device"
|
||||||
fi
|
# fi
|
||||||
'');
|
# '');
|
||||||
}
|
#}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
{ config, pkgs, ... }:
|
|
||||||
let
|
|
||||||
pulse = pkgs.pulseaudioFull;
|
|
||||||
user = config.makefu.gui.user;
|
|
||||||
wait_time = 30;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
sound.enable = true;
|
|
||||||
hardware.pulseaudio = {
|
|
||||||
enable = true;
|
|
||||||
package = pulse;
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
jack2Full
|
|
||||||
jack_capture
|
|
||||||
];
|
|
||||||
# from http://anderspapitto.com/posts/2015-11-26-overtone-on-nixos-with-jack-and-pulseaudio.html
|
|
||||||
|
|
||||||
systemd.user.services = {
|
|
||||||
jackdbus = {
|
|
||||||
description = "Runs jack, and points pulseaudio at it";
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
ExecStart = pkgs.writeScript "start_jack.sh" ''
|
|
||||||
#! ${pkgs.bash}/bin/bash
|
|
||||||
. ${config.system.build.setEnvironment}
|
|
||||||
|
|
||||||
# TODO: correctly wait for pulseaudio, cannot use pulseaudio.service
|
|
||||||
sleep ${toString wait_time} # wait for the gui to load
|
|
||||||
|
|
||||||
${pkgs.jack2Full}/bin/jack_control start
|
|
||||||
sleep 3 # give some time for sources/sinks to be created
|
|
||||||
|
|
||||||
${pulse}/bin/pacmd set-default-sink jack_out
|
|
||||||
${pulse}/bin/pacmd set-default-source jack_in
|
|
||||||
'';
|
|
||||||
ExecStop = pkgs.writeScript "stop_jack.sh" ''
|
|
||||||
#! ${pkgs.bash}/bin/bash
|
|
||||||
. ${config.system.build.setEnvironment}
|
|
||||||
|
|
||||||
${pkgs.jack2Full}/bin/jack_control stop
|
|
||||||
'';
|
|
||||||
RemainAfterExit = true;
|
|
||||||
Restart = "always";
|
|
||||||
RestartSec = "5";
|
|
||||||
};
|
|
||||||
after = [ "display-manager.service" "sound.target" ];
|
|
||||||
wantedBy = [ "default.target" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
122
makefu/2configs/audio/respeaker.nix
Normal file
122
makefu/2configs/audio/respeaker.nix
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
let
|
||||||
|
seeed-voicecard = (pkgs.callPackage ../../5pkgs/seeed-voicecard { kernel = config.boot.kernelPackages.kernel; });
|
||||||
|
in
|
||||||
|
{
|
||||||
|
hardware.raspberry-pi."4".i2c1.enable = true;
|
||||||
|
hardware.raspberry-pi."4".audio.enable = true;
|
||||||
|
hardware.raspberry-pi."4".apply-overlays-dtmerge.enable = true;
|
||||||
|
hardware.deviceTree.filter = lib.mkForce "bcm2711-rpi-4-b.dtb";
|
||||||
|
|
||||||
|
security.rtkit.enable = true;
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
alsaUtils
|
||||||
|
i2c-tools
|
||||||
|
ponymix
|
||||||
|
];
|
||||||
|
|
||||||
|
sound.enable = true;
|
||||||
|
hardware.pulseaudio.enable = lib.mkForce false;
|
||||||
|
services.pipewire = {
|
||||||
|
enable = true;
|
||||||
|
systemWide = true;
|
||||||
|
alsa.enable = true;
|
||||||
|
alsa.support32Bit = true;
|
||||||
|
pulse.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.pipewire.config.pipewire-pulse = {
|
||||||
|
"pulse.properties"."server.address" = [ "unix:native" "tcp:4713" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
sound.extraConfig = ''
|
||||||
|
pcm.!default {
|
||||||
|
type asym
|
||||||
|
playback.pcm "playback"
|
||||||
|
capture.pcm "ac108"
|
||||||
|
}
|
||||||
|
|
||||||
|
pcm.ac108 {
|
||||||
|
type plug
|
||||||
|
slave.pcm "hw:seeed4micvoicec"
|
||||||
|
}
|
||||||
|
'' ;
|
||||||
|
|
||||||
|
|
||||||
|
boot.extraModulePackages = [
|
||||||
|
seeed-voicecard
|
||||||
|
];
|
||||||
|
boot.initrd.kernelModules = [
|
||||||
|
"snd-soc-seeed-voicecard"
|
||||||
|
"snd-soc-ac108"
|
||||||
|
"i2c-dev"
|
||||||
|
#"i2c-bcm2708"
|
||||||
|
#"snd-soc-wm8960"
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.loader.raspberryPi.firmwareConfig = [
|
||||||
|
"dtparam=i2c_arm=on"
|
||||||
|
"dtparam=i2s=on"
|
||||||
|
"dtparam=spi=on"
|
||||||
|
"dtparam=i2c1=on"
|
||||||
|
# dtoverlay=seeeed-8mic-voicecard not required because we use hardware.deviceTree
|
||||||
|
];
|
||||||
|
hardware.deviceTree = {
|
||||||
|
enable = true;
|
||||||
|
overlays = [
|
||||||
|
{ name = "respeaker-4mic"; dtsFile = "${seeed-voicecard}/lib/dts/seeed-4mic-voicecard-overlay.dts";}
|
||||||
|
{ name = "spi"; dtsText = ''
|
||||||
|
/dts-v1/;
|
||||||
|
/plugin/;
|
||||||
|
|
||||||
|
/ {
|
||||||
|
compatible = "raspberrypi";
|
||||||
|
fragment@0 {
|
||||||
|
target = <&spi>;
|
||||||
|
__overlay__ {
|
||||||
|
cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
|
||||||
|
status = "okay";
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
spidev@0 {
|
||||||
|
reg = <0>; // CE0
|
||||||
|
spi-max-frequency = <500000>;
|
||||||
|
compatible = "spidev";
|
||||||
|
};
|
||||||
|
|
||||||
|
spidev@1 {
|
||||||
|
reg = <1>; // CE1
|
||||||
|
spi-max-frequency = <500000>;
|
||||||
|
compatible = "spidev";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
fragment@1 {
|
||||||
|
target = <&alt0>;
|
||||||
|
__overlay__ {
|
||||||
|
// Drop GPIO 7, SPI 8-11
|
||||||
|
brcm,pins = <4 5>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@2 {
|
||||||
|
target = <&gpio>;
|
||||||
|
__overlay__ {
|
||||||
|
spi0_pins: spi0_pins {
|
||||||
|
brcm,pins = <9 10 11>;
|
||||||
|
brcm,function = <4>; // alt0
|
||||||
|
};
|
||||||
|
spi0_cs_pins: spi0_cs_pins {
|
||||||
|
brcm,pins = <8 7>;
|
||||||
|
brcm,function = <1>; // out
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
'';}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
0. Sendung twittern und mastodieren (eine Woche + eine Stunde vorher) von Ingo/l33tname (wichtig)
|
0. Sendung twittern und mastodieren (eine Woche + eine Stunde vorher) von Ingo/l33tname (wichtig)
|
||||||
1. `eine` Person anrufen (den Host):
|
1. `eine` Person anrufen (den Host):
|
||||||
- markus 162dcbf89f@studio.link
|
- markus madmas@studio.link
|
||||||
- Felix1 makefu@studio.link
|
- Felix1 makefu@studio.link
|
||||||
- L33tFelix l33tname@studio.link
|
- L33tFelix l33tname@studio.link
|
||||||
- Ingo ingo@studio.link
|
- Ingo ingo@studio.link
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
services.bitlbee = {
|
services.bitlbee = {
|
||||||
enable = true;
|
enable = true;
|
||||||
# libpurple_plugins = [ pkgs.telegram-purple pkgs.pidgin-skypeweb];
|
# libpurple_plugins = [ pkgs.telegram-purple pkgs.pidgin-skypeweb];
|
||||||
|
plugins = [ pkgs.bitlbee-mastodon ];
|
||||||
};
|
};
|
||||||
users.users.makefu.packages = with pkgs; [ weechat tmux ];
|
users.users.makefu.packages = with pkgs; [ weechat tmux ];
|
||||||
state = [ "/var/lib/bitlbee" ];
|
state = [ "/var/lib/bitlbee" ];
|
||||||
|
23
makefu/2configs/bureautomation/brother-ql-web.nix
Normal file
23
makefu/2configs/bureautomation/brother-ql-web.nix
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{pkgs, ... }:
|
||||||
|
let
|
||||||
|
pkg = pkgs.brother_ql_web;
|
||||||
|
in {
|
||||||
|
systemd.services.brother-ql-web = {
|
||||||
|
after = [ "network.target" ];
|
||||||
|
description = "Brother QL Web Interface";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
environment = {
|
||||||
|
FLASK_PRINTER = "usb://0x04f9:0x209b/000F1Z401759";
|
||||||
|
FLASK_MODEL = "QL-800";
|
||||||
|
#FLASK_SERVER_PORT = "8013";
|
||||||
|
#FLASK_LABEL_DEFAULT_SIZE = "d24";
|
||||||
|
#FLASK_LABEL_DEFAULT_QR_SIZE = "7";
|
||||||
|
};
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${pkg}/bin/brother_ql_web";
|
||||||
|
DynamicUser = true;
|
||||||
|
SupplementaryGroups = "lp";
|
||||||
|
Restart = "always";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
28
makefu/2configs/bureautomation/printer.nix
Normal file
28
makefu/2configs/bureautomation/printer.nix
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{ pkgs, config, ... }:
|
||||||
|
let
|
||||||
|
mainUser = config.krebs.build.user.name;
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
./brother-ql-web.nix
|
||||||
|
];
|
||||||
|
services.printing = {
|
||||||
|
enable = true;
|
||||||
|
drivers = with pkgs;[
|
||||||
|
brlaser
|
||||||
|
cups-ptouch
|
||||||
|
];
|
||||||
|
};
|
||||||
|
users.users.kiosk.extraGroups = [ "scanner" "lp" ];
|
||||||
|
state = [ "/var/lib/cups"];
|
||||||
|
users.users.kiosk.packages = with pkgs;[
|
||||||
|
python3Packages.brother-ql
|
||||||
|
libreoffice
|
||||||
|
qrencode
|
||||||
|
imagemagick
|
||||||
|
];
|
||||||
|
|
||||||
|
services.udev.extraRules = ''
|
||||||
|
SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f9", ATTRS{idProduct}=="209b", ATTRS{serial}=="000F1Z401759", MODE="0664", GROUP="lp", SYMLINK+="usb/lp0"
|
||||||
|
'';
|
||||||
|
|
||||||
|
}
|
@ -31,6 +31,7 @@ with import <stockholm/lib>;
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
nix.settings.trusted-users = [ config.krebs.build.user.name ];
|
nix.settings.trusted-users = [ config.krebs.build.user.name ];
|
||||||
|
nix.settings.experimental-features = [ "flakes" "nix-command" ];
|
||||||
|
|
||||||
boot.kernelPackages = lib.mkDefault pkgs.linuxPackages;
|
boot.kernelPackages = lib.mkDefault pkgs.linuxPackages;
|
||||||
|
|
||||||
|
@ -26,18 +26,6 @@
|
|||||||
zipcode: 70378
|
zipcode: 70378
|
||||||
q: Werkbank
|
q: Werkbank
|
||||||
distance: 5
|
distance: 5
|
||||||
- name: Stirnthermometer
|
|
||||||
zipcode: 70378
|
|
||||||
q: Stirnthermometer
|
|
||||||
distance: 5
|
|
||||||
- name: Ohrthermometer
|
|
||||||
zipcode: 70378
|
|
||||||
q: Ohrthermometer
|
|
||||||
distance: 5
|
|
||||||
- name: Fieberthermometer
|
|
||||||
zipcode: 70378
|
|
||||||
q: Fieberthermometer
|
|
||||||
distance: 5
|
|
||||||
- name: Einhell
|
- name: Einhell
|
||||||
zipcode: 70378
|
zipcode: 70378
|
||||||
q: Einhell
|
q: Einhell
|
||||||
|
9
makefu/2configs/deployment/nixos.wiki/default.nix
Normal file
9
makefu/2configs/deployment/nixos.wiki/default.nix
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ ./mediawiki.nix
|
||||||
|
./network.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
481
makefu/2configs/deployment/nixos.wiki/mediawiki.module.nix
Normal file
481
makefu/2configs/deployment/nixos.wiki/mediawiki.module.nix
Normal file
@ -0,0 +1,481 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
inherit (lib) mkDefault mkEnableOption mkForce mkIf mkMerge mkOption;
|
||||||
|
inherit (lib) concatStringsSep literalExample mapAttrsToList optional optionals optionalString types;
|
||||||
|
|
||||||
|
cfg = config.services.mediawiki;
|
||||||
|
fpm = config.services.phpfpm.pools.mediawiki;
|
||||||
|
user = "mediawiki";
|
||||||
|
group = config.services.httpd.group;
|
||||||
|
cacheDir = "/var/cache/mediawiki";
|
||||||
|
stateDir = "/var/lib/mediawiki";
|
||||||
|
|
||||||
|
pkg = pkgs.stdenv.mkDerivation rec {
|
||||||
|
pname = "mediawiki-full";
|
||||||
|
version = src.version;
|
||||||
|
src = cfg.package;
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
cp -r * $out/
|
||||||
|
|
||||||
|
rm -rf $out/share/mediawiki/skins/*
|
||||||
|
rm -rf $out/share/mediawiki/extensions/*
|
||||||
|
|
||||||
|
${concatStringsSep "\n" (mapAttrsToList (k: v: ''
|
||||||
|
ln -s ${v} $out/share/mediawiki/skins/${k}
|
||||||
|
'') cfg.skins)}
|
||||||
|
|
||||||
|
${concatStringsSep "\n" (mapAttrsToList (k: v: ''
|
||||||
|
ln -s ${if v != null then v else "$src/share/mediawiki/extensions/${k}"} $out/share/mediawiki/extensions/${k}
|
||||||
|
'') cfg.extensions)}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
mediawikiScripts = pkgs.runCommand "mediawiki-scripts" {
|
||||||
|
buildInputs = [ pkgs.makeWrapper ];
|
||||||
|
preferLocalBuild = true;
|
||||||
|
} ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
for i in changePassword.php createAndPromote.php userOptions.php edit.php nukePage.php update.php; do
|
||||||
|
makeWrapper ${pkgs.php}/bin/php $out/bin/mediawiki-$(basename $i .php) \
|
||||||
|
--set MEDIAWIKI_CONFIG ${mediawikiConfig} \
|
||||||
|
--add-flags ${pkg}/share/mediawiki/maintenance/$i
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
|
||||||
|
mediawikiConfig = pkgs.writeText "LocalSettings.php" ''
|
||||||
|
<?php
|
||||||
|
# Protect against web entry
|
||||||
|
if ( !defined( 'MEDIAWIKI' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$wgSitename = "${cfg.name}";
|
||||||
|
$wgMetaNamespace = false;
|
||||||
|
|
||||||
|
## The URL base path to the directory containing the wiki;
|
||||||
|
## defaults for all runtime URL paths are based off of this.
|
||||||
|
## For more information on customizing the URLs
|
||||||
|
## (like /w/index.php/Page_title to /wiki/Page_title) please see:
|
||||||
|
## https://www.mediawiki.org/wiki/Manual:Short_URL
|
||||||
|
$wgScriptPath = "${cfg.basePath}";
|
||||||
|
|
||||||
|
## The protocol and server name to use in fully-qualified URLs
|
||||||
|
#$wgServer = "${if cfg.virtualHost.addSSL || cfg.virtualHost.forceSSL || cfg.virtualHost.onlySSL then "https" else "http"}://${cfg.virtualHost.hostName}";
|
||||||
|
#$wgServer = "";
|
||||||
|
$wgServer = "http://localhost";
|
||||||
|
|
||||||
|
## The URL path to static resources (images, scripts, etc.)
|
||||||
|
$wgResourceBasePath = $wgScriptPath;
|
||||||
|
|
||||||
|
## The URL path to the logo. Make sure you change this from the default,
|
||||||
|
## or else you'll overwrite your logo when you upgrade!
|
||||||
|
$wgLogo = "$wgResourceBasePath/resources/assets/wiki.png";
|
||||||
|
|
||||||
|
## UPO means: this is also a user preference option
|
||||||
|
|
||||||
|
$wgEnableEmail = true;
|
||||||
|
$wgEnableUserEmail = true; # UPO
|
||||||
|
|
||||||
|
$wgEmergencyContact = "${if cfg.virtualHost.adminAddr != null then cfg.virtualHost.adminAddr else config.services.httpd.adminAddr}";
|
||||||
|
$wgPasswordSender = $wgEmergencyContact;
|
||||||
|
|
||||||
|
$wgEnotifUserTalk = false; # UPO
|
||||||
|
$wgEnotifWatchlist = false; # UPO
|
||||||
|
$wgEmailAuthentication = true;
|
||||||
|
|
||||||
|
## Database settings
|
||||||
|
$wgDBtype = "${cfg.database.type}";
|
||||||
|
$wgDBserver = "${cfg.database.host}:${if cfg.database.socket != null then cfg.database.socket else toString cfg.database.port}";
|
||||||
|
$wgDBname = "${cfg.database.name}";
|
||||||
|
$wgDBuser = "${cfg.database.user}";
|
||||||
|
${optionalString (cfg.database.passwordFile != null) "$wgDBpassword = file_get_contents(\"${cfg.database.passwordFile}\");"}
|
||||||
|
|
||||||
|
${optionalString (cfg.database.type == "mysql" && cfg.database.tablePrefix != null) ''
|
||||||
|
# MySQL specific settings
|
||||||
|
$wgDBprefix = "${cfg.database.tablePrefix}";
|
||||||
|
''}
|
||||||
|
|
||||||
|
${optionalString (cfg.database.type == "mysql") ''
|
||||||
|
# MySQL table options to use during installation or update
|
||||||
|
$wgDBTableOptions = "ENGINE=InnoDB, DEFAULT CHARSET=binary";
|
||||||
|
''}
|
||||||
|
|
||||||
|
## Shared memory settings
|
||||||
|
$wgMainCacheType = CACHE_NONE;
|
||||||
|
$wgMemCachedServers = [];
|
||||||
|
|
||||||
|
${optionalString (cfg.uploadsDir != null) ''
|
||||||
|
$wgEnableUploads = true;
|
||||||
|
$wgUploadDirectory = "${cfg.uploadsDir}";
|
||||||
|
''}
|
||||||
|
|
||||||
|
$wgUseImageMagick = true;
|
||||||
|
$wgImageMagickConvertCommand = "${pkgs.imagemagick}/bin/convert";
|
||||||
|
|
||||||
|
# InstantCommons allows wiki to use images from https://commons.wikimedia.org
|
||||||
|
$wgUseInstantCommons = false;
|
||||||
|
|
||||||
|
# Periodically send a pingback to https://www.mediawiki.org/ with basic data
|
||||||
|
# about this MediaWiki instance. The Wikimedia Foundation shares this data
|
||||||
|
# with MediaWiki developers to help guide future development efforts.
|
||||||
|
$wgPingback = true;
|
||||||
|
|
||||||
|
## If you use ImageMagick (or any other shell command) on a
|
||||||
|
## Linux server, this will need to be set to the name of an
|
||||||
|
## available UTF-8 locale
|
||||||
|
$wgShellLocale = "C.UTF-8";
|
||||||
|
|
||||||
|
## Set $wgCacheDirectory to a writable directory on the web server
|
||||||
|
## to make your wiki go slightly faster. The directory should not
|
||||||
|
## be publically accessible from the web.
|
||||||
|
$wgCacheDirectory = "${cacheDir}";
|
||||||
|
|
||||||
|
# Site language code, should be one of the list in ./languages/data/Names.php
|
||||||
|
$wgLanguageCode = "en";
|
||||||
|
|
||||||
|
$wgSecretKey = file_get_contents("${stateDir}/secret.key");
|
||||||
|
|
||||||
|
# Changing this will log out all existing sessions.
|
||||||
|
$wgAuthenticationTokenVersion = "";
|
||||||
|
|
||||||
|
## For attaching licensing metadata to pages, and displaying an
|
||||||
|
## appropriate copyright notice / icon. GNU Free Documentation
|
||||||
|
## License and Creative Commons licenses are supported so far.
|
||||||
|
$wgRightsPage = ""; # Set to the title of a wiki page that describes your license/copyright
|
||||||
|
$wgRightsUrl = "";
|
||||||
|
$wgRightsText = "";
|
||||||
|
$wgRightsIcon = "";
|
||||||
|
|
||||||
|
# Path to the GNU diff3 utility. Used for conflict resolution.
|
||||||
|
$wgDiff = "${pkgs.diffutils}/bin/diff";
|
||||||
|
$wgDiff3 = "${pkgs.diffutils}/bin/diff3";
|
||||||
|
|
||||||
|
# Enabled skins.
|
||||||
|
${concatStringsSep "\n" (mapAttrsToList (k: v: "wfLoadSkin('${k}');") cfg.skins)}
|
||||||
|
|
||||||
|
# Enabled extensions.
|
||||||
|
${concatStringsSep "\n" (mapAttrsToList (k: v: "wfLoadExtension('${k}');") cfg.extensions)}
|
||||||
|
|
||||||
|
|
||||||
|
# End of automatically generated settings.
|
||||||
|
# Add more configuration options below.
|
||||||
|
|
||||||
|
${cfg.extraConfig}
|
||||||
|
'';
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# interface
|
||||||
|
options = {
|
||||||
|
services.mediawiki = {
|
||||||
|
|
||||||
|
enable = mkEnableOption "MediaWiki";
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.mediawiki;
|
||||||
|
description = "Which MediaWiki package to use.";
|
||||||
|
};
|
||||||
|
|
||||||
|
basePath = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "/";
|
||||||
|
description = "Base path to Wiki";
|
||||||
|
};
|
||||||
|
|
||||||
|
name = mkOption {
|
||||||
|
default = "MediaWiki";
|
||||||
|
example = "Foobar Wiki";
|
||||||
|
description = "Name of the wiki.";
|
||||||
|
};
|
||||||
|
|
||||||
|
uploadsDir = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = "${stateDir}/uploads";
|
||||||
|
description = ''
|
||||||
|
This directory is used for uploads of pictures. The directory passed here is automatically
|
||||||
|
created and permissions adjusted as required.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
passwordFile = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = "A file containing the initial password for the admin user.";
|
||||||
|
example = "/run/keys/mediawiki-password";
|
||||||
|
};
|
||||||
|
|
||||||
|
skins = mkOption {
|
||||||
|
default = {};
|
||||||
|
type = types.attrsOf types.path;
|
||||||
|
description = ''
|
||||||
|
Attribute set of paths whose content is copied to the <filename>skins</filename>
|
||||||
|
subdirectory of the MediaWiki installation in addition to the default skins.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extensions = mkOption {
|
||||||
|
default = {};
|
||||||
|
type = types.attrsOf (types.nullOr types.path);
|
||||||
|
description = ''
|
||||||
|
Attribute set of paths whose content is copied to the <filename>extensions</filename>
|
||||||
|
subdirectory of the MediaWiki installation and enabled in configuration.
|
||||||
|
|
||||||
|
Use <literal>null</literal> instead of path to enable extensions that are part of MediaWiki.
|
||||||
|
'';
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
Matomo = pkgs.fetchzip {
|
||||||
|
url = "https://github.com/DaSchTour/matomo-mediawiki-extension/archive/v4.0.1.tar.gz";
|
||||||
|
sha256 = "0g5rd3zp0avwlmqagc59cg9bbkn3r7wx7p6yr80s644mj6dlvs1b";
|
||||||
|
};
|
||||||
|
ParserFunctions = null;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
database = {
|
||||||
|
type = mkOption {
|
||||||
|
type = types.enum [ "mysql" "postgres" "sqlite" "mssql" "oracle" ];
|
||||||
|
default = "mysql";
|
||||||
|
description = "Database engine to use. MySQL/MariaDB is the database of choice by MediaWiki developers.";
|
||||||
|
};
|
||||||
|
|
||||||
|
host = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "localhost";
|
||||||
|
description = "Database host address.";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 3306;
|
||||||
|
description = "Database host port.";
|
||||||
|
};
|
||||||
|
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "mediawiki";
|
||||||
|
description = "Database name.";
|
||||||
|
};
|
||||||
|
|
||||||
|
user = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "mediawiki";
|
||||||
|
description = "Database user.";
|
||||||
|
};
|
||||||
|
|
||||||
|
passwordFile = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
example = "/run/keys/mediawiki-dbpassword";
|
||||||
|
description = ''
|
||||||
|
A file containing the password corresponding to
|
||||||
|
<option>database.user</option>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
tablePrefix = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
If you only have access to a single database and wish to install more than
|
||||||
|
one version of MediaWiki, or have other applications that also use the
|
||||||
|
database, you can give the table names a unique prefix to stop any naming
|
||||||
|
conflicts or confusion.
|
||||||
|
See <link xlink:href='https://www.mediawiki.org/wiki/Manual:$wgDBprefix'/>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
socket = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = if cfg.database.createLocally then "/run/mysqld/mysqld.sock" else null;
|
||||||
|
defaultText = "/run/mysqld/mysqld.sock";
|
||||||
|
description = "Path to the unix socket file to use for authentication.";
|
||||||
|
};
|
||||||
|
|
||||||
|
createLocally = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = cfg.database.type == "mysql";
|
||||||
|
defaultText = "true";
|
||||||
|
description = ''
|
||||||
|
Create the database and database user locally.
|
||||||
|
This currently only applies if database type "mysql" is selected.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
virtualHost = mkOption {
|
||||||
|
type = types.submodule (import <nixpkgs/nixos/modules/services/web-servers/apache-httpd/vhost-options.nix>);
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
hostName = "mediawiki.example.org";
|
||||||
|
adminAddr = "webmaster@example.org";
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Apache configuration can be done by adapting <option>services.httpd.virtualHosts</option>.
|
||||||
|
See <xref linkend="opt-services.httpd.virtualHosts"/> for further information.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
poolConfig = mkOption {
|
||||||
|
type = with types; attrsOf (oneOf [ str int bool ]);
|
||||||
|
default = {
|
||||||
|
"pm" = "dynamic";
|
||||||
|
"pm.max_children" = 32;
|
||||||
|
"pm.start_servers" = 2;
|
||||||
|
"pm.min_spare_servers" = 2;
|
||||||
|
"pm.max_spare_servers" = 4;
|
||||||
|
"pm.max_requests" = 500;
|
||||||
|
};
|
||||||
|
description = ''
|
||||||
|
Options for the MediaWiki PHP pool. See the documentation on <literal>php-fpm.conf</literal>
|
||||||
|
for details on configuration directives.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
description = ''
|
||||||
|
Any additional text to be appended to MediaWiki's
|
||||||
|
LocalSettings.php configuration file. For configuration
|
||||||
|
settings, see <link xlink:href="https://www.mediawiki.org/wiki/Manual:Configuration_settings"/>.
|
||||||
|
'';
|
||||||
|
default = "";
|
||||||
|
example = ''
|
||||||
|
$wgEnableEmail = false;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# implementation
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
assertions = [
|
||||||
|
{ assertion = cfg.database.createLocally -> cfg.database.type == "mysql";
|
||||||
|
message = "services.mediawiki.createLocally is currently only supported for database type 'mysql'";
|
||||||
|
}
|
||||||
|
{ assertion = cfg.database.createLocally -> cfg.database.user == user;
|
||||||
|
message = "services.mediawiki.database.user must be set to ${user} if services.mediawiki.database.createLocally is set true";
|
||||||
|
}
|
||||||
|
{ assertion = cfg.database.createLocally -> cfg.database.socket != null;
|
||||||
|
message = "services.mediawiki.database.socket must be set if services.mediawiki.database.createLocally is set to true";
|
||||||
|
}
|
||||||
|
{ assertion = cfg.database.createLocally -> cfg.database.passwordFile == null;
|
||||||
|
message = "a password cannot be specified if services.mediawiki.database.createLocally is set to true";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.mediawiki.skins = {
|
||||||
|
MonoBook = "${cfg.package}/share/mediawiki/skins/MonoBook";
|
||||||
|
Timeless = "${cfg.package}/share/mediawiki/skins/Timeless";
|
||||||
|
Vector = "${cfg.package}/share/mediawiki/skins/Vector";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.mysql = mkIf cfg.database.createLocally {
|
||||||
|
enable = true;
|
||||||
|
package = mkDefault pkgs.mariadb;
|
||||||
|
ensureDatabases = [ cfg.database.name ];
|
||||||
|
ensureUsers = [
|
||||||
|
{ name = cfg.database.user;
|
||||||
|
ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; };
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.phpfpm.pools.mediawiki = {
|
||||||
|
inherit user group;
|
||||||
|
phpEnv.MEDIAWIKI_CONFIG = "${mediawikiConfig}";
|
||||||
|
settings = {
|
||||||
|
"listen.owner" = config.services.httpd.user;
|
||||||
|
"listen.group" = config.services.httpd.group;
|
||||||
|
} // cfg.poolConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.httpd = {
|
||||||
|
enable = true;
|
||||||
|
extraModules = [ "proxy_fcgi" ];
|
||||||
|
virtualHosts.${cfg.virtualHost.hostName} = mkMerge [ cfg.virtualHost {
|
||||||
|
documentRoot = mkForce "${pkg}/share/mediawiki";
|
||||||
|
extraConfig = ''
|
||||||
|
<Directory "${pkg}/share/mediawiki">
|
||||||
|
<FilesMatch "\.php$">
|
||||||
|
<If "-f %{REQUEST_FILENAME}">
|
||||||
|
SetHandler "proxy:unix:${fpm.socket}|fcgi://localhost/"
|
||||||
|
</If>
|
||||||
|
</FilesMatch>
|
||||||
|
|
||||||
|
Require all granted
|
||||||
|
DirectoryIndex index.php
|
||||||
|
AllowOverride All
|
||||||
|
</Directory>
|
||||||
|
'' + optionalString (cfg.uploadsDir != null) ''
|
||||||
|
Alias "/images" "${cfg.uploadsDir}"
|
||||||
|
<Directory "${cfg.uploadsDir}">
|
||||||
|
Require all granted
|
||||||
|
</Directory>
|
||||||
|
'';
|
||||||
|
} ];
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d '${stateDir}' 0750 ${user} ${group} - -"
|
||||||
|
"d '${cacheDir}' 0750 ${user} ${group} - -"
|
||||||
|
] ++ optionals (cfg.uploadsDir != null) [
|
||||||
|
"d '${cfg.uploadsDir}' 0750 ${user} ${group} - -"
|
||||||
|
"Z '${cfg.uploadsDir}' 0750 ${user} ${group} - -"
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.services.mediawiki-init = {
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
before = [ "phpfpm-mediawiki.service" ];
|
||||||
|
after = optional cfg.database.createLocally "mysql.service";
|
||||||
|
script = ''
|
||||||
|
if ! test -e "${stateDir}/secret.key"; then
|
||||||
|
tr -dc A-Za-z0-9 </dev/urandom 2>/dev/null | head -c 64 > ${stateDir}/secret.key
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "exit( wfGetDB( DB_MASTER )->tableExists( 'user' ) ? 1 : 0 );" | \
|
||||||
|
${pkgs.php}/bin/php ${pkg}/share/mediawiki/maintenance/eval.php --conf ${mediawikiConfig} && \
|
||||||
|
${pkgs.php}/bin/php ${pkg}/share/mediawiki/maintenance/install.php \
|
||||||
|
--confpath /tmp \
|
||||||
|
--scriptpath ${cfg.basePath} \
|
||||||
|
--dbserver ${cfg.database.host}${optionalString (cfg.database.socket != null) ":${cfg.database.socket}"} \
|
||||||
|
--dbport ${toString cfg.database.port} \
|
||||||
|
--dbname ${cfg.database.name} \
|
||||||
|
${optionalString (cfg.database.tablePrefix != null) "--dbprefix ${cfg.database.tablePrefix}"} \
|
||||||
|
--dbuser ${cfg.database.user} \
|
||||||
|
${optionalString (cfg.database.passwordFile != null) "--dbpassfile ${cfg.database.passwordFile}"} \
|
||||||
|
--passfile ${cfg.passwordFile} \
|
||||||
|
"${cfg.name}" \
|
||||||
|
admin
|
||||||
|
|
||||||
|
${pkgs.php}/bin/php ${pkg}/share/mediawiki/maintenance/update.php --conf ${mediawikiConfig} --quick
|
||||||
|
'';
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
User = user;
|
||||||
|
Group = group;
|
||||||
|
PrivateTmp = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.httpd.after = optional (cfg.database.createLocally && cfg.database.type == "mysql") "mysql.service";
|
||||||
|
|
||||||
|
users.users.${user} = {
|
||||||
|
group = group;
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = [ mediawikiScripts ];
|
||||||
|
};
|
||||||
|
}
|
67
makefu/2configs/deployment/nixos.wiki/mediawiki.nix
Normal file
67
makefu/2configs/deployment/nixos.wiki/mediawiki.nix
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
hostAddress = "192.168.48.1";
|
||||||
|
localAddress = "192.168.48.3";
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
containers.mediawiki =
|
||||||
|
{ autoStart = true;
|
||||||
|
privateNetwork = true;
|
||||||
|
inherit hostAddress localAddress;
|
||||||
|
config = { config, pkgs, ... }:
|
||||||
|
{
|
||||||
|
# NOTE: This disabling and importing is so that the basePath can be altered
|
||||||
|
disabledModules = [ "services/web-apps/mediawiki.nix" ];
|
||||||
|
imports = [
|
||||||
|
./mediawiki.module.nix
|
||||||
|
];
|
||||||
|
time.timeZone = "America/New_York";
|
||||||
|
system.stateVersion = "20.09";
|
||||||
|
networking.defaultGateway = hostAddress;
|
||||||
|
# NOTE: you might want to change this namserver address
|
||||||
|
networking.nameservers = [ "8.8.8.8" ];
|
||||||
|
networking.firewall.allowedTCPPorts = [ 80 ];
|
||||||
|
services.mediawiki = {
|
||||||
|
enable = true;
|
||||||
|
name = "Example Containerized Wiki";
|
||||||
|
# NOTE: here is where the basePath is specified, which requires the imported mediawiki NixOS module
|
||||||
|
basePath = "/wiki";
|
||||||
|
passwordFile = ./mediawiki.password.txt;
|
||||||
|
extraConfig = ''
|
||||||
|
$wgRCFeeds['euerkrebsco'] = array(
|
||||||
|
'formatter' => 'JSONRCFeedFormatter',
|
||||||
|
'uri' => 'udp://euer.krebsco.de:5005',
|
||||||
|
'add_interwiki_prefix' => false,
|
||||||
|
'omit_bots' => true,
|
||||||
|
);
|
||||||
|
$wgRCFeeds['euerkrebscoIRC'] = array(
|
||||||
|
'formatter' => 'IRCColourfulRCFeedFormatter',
|
||||||
|
'uri' => 'udp://euer.krebsco.de:5006',
|
||||||
|
'add_interwiki_prefix' => false,
|
||||||
|
'omit_bots' => true,
|
||||||
|
);
|
||||||
|
'';
|
||||||
|
virtualHost = {
|
||||||
|
hostName = "localhost";
|
||||||
|
adminAddr = "root@localhost";
|
||||||
|
forceSSL = false;
|
||||||
|
addSSL = false;
|
||||||
|
onlySSL = false;
|
||||||
|
enableACME = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Put the MediaWiki web page behind an NGINX proxy
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts.localhost.locations."/wiki" = {
|
||||||
|
# NOTE: the slash at the end of the URI is important. It causes the location base path to be removed when passed onto the proxy
|
||||||
|
proxyPass = "http://${localAddress}:80/";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
thisisthepassword
|
6
makefu/2configs/deployment/nixos.wiki/network.nix
Normal file
6
makefu/2configs/deployment/nixos.wiki/network.nix
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
networking.networkmanager.unmanaged = [ "interface-name:ve-*" ];
|
||||||
|
networking.nat.enable = true;
|
||||||
|
networking.nat.internalInterfaces = ["ve-+"];
|
||||||
|
networking.nat.externalInterface = "wlan0";
|
||||||
|
}
|
41
makefu/2configs/deployment/ntfysh.nix
Normal file
41
makefu/2configs/deployment/ntfysh.nix
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{ lib, config, ... }:
|
||||||
|
let
|
||||||
|
web-port = 19455;
|
||||||
|
hostn = "ntfy.euer.krebsco.de";
|
||||||
|
internal-ip = config.krebs.build.host.nets.retiolum.ip4.addr;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services.ntfy-sh = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
listen-http = "127.0.0.1:${toString web-port}";
|
||||||
|
auth-file = "/var/lib/ntfy-sh/user.db";
|
||||||
|
auth-default-access = "deny-all";
|
||||||
|
behind-proxy = true;
|
||||||
|
attachment-cache-dir = "/media/cloud/ntfy-sh/attachments";
|
||||||
|
attachment-file-size-limit = "500m";
|
||||||
|
attachment-total-size-limit = "100g";
|
||||||
|
base-url = "https://ntfy.euer.krebsco.de";
|
||||||
|
attachment-expiry-duration = "48h";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.ntfy-sh.serviceConfig = {
|
||||||
|
StateDirectory = "ntfy-sh";
|
||||||
|
SupplementaryGroups = [ "download" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
enable = lib.mkDefault true;
|
||||||
|
virtualHosts."${hostn}" = {
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://localhost:${toString web-port}/";
|
||||||
|
proxyWebsockets = true;
|
||||||
|
recommendedProxySettings = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -59,7 +59,7 @@ systemd.services.postgresqlBackup-nextcloud.serviceConfig.SupplementaryGroups =
|
|||||||
users.users.nextcloud.extraGroups = [ "download" ];
|
users.users.nextcloud.extraGroups = [ "download" ];
|
||||||
services.nextcloud = {
|
services.nextcloud = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.nextcloud24;
|
package = pkgs.nextcloud25;
|
||||||
hostName = "o.euer.krebsco.de";
|
hostName = "o.euer.krebsco.de";
|
||||||
# Use HTTPS for links
|
# Use HTTPS for links
|
||||||
https = true;
|
https = true;
|
||||||
@ -97,5 +97,11 @@ systemd.services.postgresqlBackup-nextcloud.serviceConfig.SupplementaryGroups =
|
|||||||
systemd.services."nextcloud-setup" = {
|
systemd.services."nextcloud-setup" = {
|
||||||
requires = ["postgresql.service"];
|
requires = ["postgresql.service"];
|
||||||
after = ["postgresql.service"];
|
after = ["postgresql.service"];
|
||||||
|
serviceConfig.RequiresMountFor = [ "/media/cloud" ];
|
||||||
};
|
};
|
||||||
|
systemd.services."phpfpm-nextcloud".serviceConfig.RequiresMountFor = [
|
||||||
|
"/media/cloud"
|
||||||
|
"/var/lib/nextcloud/data"
|
||||||
|
];
|
||||||
|
systemd.services."phpfpm".serviceConfig.RequiresMountFor = [ "/media/cloud" ];
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,10 @@ in {
|
|||||||
enable = true;
|
enable = true;
|
||||||
databases = [ config.services.tt-rss.database.name ];
|
databases = [ config.services.tt-rss.database.name ];
|
||||||
};
|
};
|
||||||
|
systemd.services.tt-rss.serviceConfig = {
|
||||||
|
Restart = lib.mkForce "always";
|
||||||
|
};
|
||||||
|
|
||||||
systemd.services.postgresqlBackup-tt_rss.serviceConfig.SupplementaryGroups = [ "download" ];
|
systemd.services.postgresqlBackup-tt_rss.serviceConfig.SupplementaryGroups = [ "download" ];
|
||||||
|
|
||||||
services.nginx.virtualHosts."${fqdn}" = {
|
services.nginx.virtualHosts."${fqdn}" = {
|
||||||
|
@ -3,5 +3,7 @@ https://www.ebay-kleinanzeigen.de/s-stuttgart/zigbee/k0l9280
|
|||||||
https://www.ebay-kleinanzeigen.de/s-70378/d%C3%B6rrautomat/k0l9334r5
|
https://www.ebay-kleinanzeigen.de/s-70378/d%C3%B6rrautomat/k0l9334r5
|
||||||
https://www.ebay-kleinanzeigen.de/s-zu-verschenken/muehlhausen/c192l9313
|
https://www.ebay-kleinanzeigen.de/s-zu-verschenken/muehlhausen/c192l9313
|
||||||
https://www.ebay-kleinanzeigen.de/s-spielzeug/muehlhausen/brettspiel/k0c23l9313
|
https://www.ebay-kleinanzeigen.de/s-spielzeug/muehlhausen/brettspiel/k0c23l9313
|
||||||
https://www.ebay-kleinanzeigen.de/s-muehlhausen/labeldrucker/k0l9313r5
|
|
||||||
https://www.ebay-kleinanzeigen.de/s-muehlhausen/dymo/k0l9313r5
|
https://www.ebay-kleinanzeigen.de/s-muehlhausen/dymo/k0l9313r5
|
||||||
|
https://www.ebay-kleinanzeigen.de/s-zu-verschenken/muehlhausen/lautsprecher/k0c192l9313r5
|
||||||
|
https://www.ebay-kleinanzeigen.de/s-muehlhausen/preis::40/winkelschleifer/k0l9313r5
|
||||||
|
https://www.ebay-kleinanzeigen.de/s-muehlhausen/preis::40/kontaktgrill/k0l9313r5
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#"UltiSnips"
|
#"UltiSnips"
|
||||||
# vim-nix handles indentation better but does not perform sanity
|
# vim-nix handles indentation better but does not perform sanity
|
||||||
"vim-nix"
|
"vim-nix"
|
||||||
# "vim-addon-nix"
|
"vim-addon-nix"
|
||||||
"vim-better-whitespace"
|
"vim-better-whitespace"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@ -49,7 +49,6 @@ set matchtime=3
|
|||||||
set hlsearch
|
set hlsearch
|
||||||
|
|
||||||
autocmd ColorScheme * highlight ExtraWhitespace ctermbg=red guibg=red
|
autocmd ColorScheme * highlight ExtraWhitespace ctermbg=red guibg=red
|
||||||
hi MatchParen cterm=none ctermbg=green ctermfg=blue
|
|
||||||
|
|
||||||
let g:better_whitespace_enabled=1
|
let g:better_whitespace_enabled=1
|
||||||
let g:strip_whitespace_on_save=1
|
let g:strip_whitespace_on_save=1
|
||||||
@ -114,3 +113,5 @@ let g:UltiSnipsExpandTrigger = "<c-j>"
|
|||||||
let g:UltiSnipsJumpForwardTrigger = "<c-j>"
|
let g:UltiSnipsJumpForwardTrigger = "<c-j>"
|
||||||
let g:UltiSnipsJumpBackwardTrigger = "<c-p>"
|
let g:UltiSnipsJumpBackwardTrigger = "<c-p>"
|
||||||
let g:UltiSnipsListSnippets = "<c-k>" "List possible snippets based on current file
|
let g:UltiSnipsListSnippets = "<c-k>" "List possible snippets based on current file
|
||||||
|
|
||||||
|
hi MatchParen cterm=none ctermbg=green ctermfg=blue
|
||||||
|
@ -18,30 +18,28 @@ in
|
|||||||
imports = [
|
imports = [
|
||||||
./urxvtd.nix
|
./urxvtd.nix
|
||||||
./pipewire.nix
|
./pipewire.nix
|
||||||
|
./gnome.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
# services.redshift.enable = true;
|
||||||
services.xserver = {
|
services.xserver = {
|
||||||
enable = true;
|
enable = true;
|
||||||
layout = "us";
|
layout = "us";
|
||||||
xkbVariant = "altgr-intl";
|
xkbVariant = "altgr-intl";
|
||||||
xkbOptions = "ctrl:nocaps, eurosign:e";
|
xkbOptions = "ctrl:nocaps, eurosign:e";
|
||||||
|
|
||||||
windowManager = {
|
# windowManager = {
|
||||||
awesome.enable = true;
|
# awesome.enable = true;
|
||||||
awesome.noArgb = true;
|
# awesome.noArgb = true;
|
||||||
awesome.luaModules = [ pkgs.luaPackages.vicious ];
|
# awesome.luaModules = [ pkgs.luaPackages.vicious ];
|
||||||
};
|
# };
|
||||||
displayManager.defaultSession = lib.mkDefault "none+awesome";
|
# displayManager.defaultSession = lib.mkDefault "none+awesome";
|
||||||
displayManager.autoLogin = {
|
|
||||||
enable = true;
|
|
||||||
user = mainUser;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
environment.systemPackages = [ pkgs.gnome.adwaita-icon-theme ];
|
environment.systemPackages = [ pkgs.gnome.adwaita-icon-theme ];
|
||||||
# lid switch is handled via button presses
|
# lid switch is handled via button presses
|
||||||
services.logind.lidSwitch = lib.mkDefault "ignore";
|
# services.logind.lidSwitch = lib.mkDefault "ignore";
|
||||||
makefu.awesome.enable = true;
|
#makefu.awesome.enable = true;
|
||||||
console.font = "Lat2-Terminus16";
|
console.font = "Lat2-Terminus16";
|
||||||
|
|
||||||
fonts = {
|
fonts = {
|
||||||
|
63
makefu/2configs/gui/gnome.nix
Normal file
63
makefu/2configs/gui/gnome.nix
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
mainUser = config.krebs.build.user.name;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
programs.gnome-terminal.enable = true;
|
||||||
|
services.xserver = {
|
||||||
|
desktopManager.gnome.enable = true;
|
||||||
|
displayManager.gdm.enable = true;
|
||||||
|
#displayManager.autoLogin = {
|
||||||
|
# enable = true;
|
||||||
|
# user = mainUser;
|
||||||
|
#};
|
||||||
|
};
|
||||||
|
programs.dconf.enable = true;
|
||||||
|
home-manager.users.${mainUser}.dconf = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
"org/gnome/terminal/legacy" = {
|
||||||
|
mnemonics-enabled = false;
|
||||||
|
theme-variant = "dark";
|
||||||
|
};
|
||||||
|
"org/gnome/desktop/interface" = {
|
||||||
|
enable-animations = false;
|
||||||
|
enable-hot-corners = false;
|
||||||
|
show-battery-percentage = true;
|
||||||
|
};
|
||||||
|
"org/gnome/desktop/peripherals/touchpad" = {
|
||||||
|
edge-scrolling-enabled = false;
|
||||||
|
natural-scroll = false;
|
||||||
|
send-events = "enabled";
|
||||||
|
tap-to-click = true;
|
||||||
|
two-finger-scrolling-enabled = true;
|
||||||
|
};
|
||||||
|
"org/gnome/desktop/session".idle-delay = 900;
|
||||||
|
"org/gnome/desktop/wm/keybindings" = {
|
||||||
|
close=["<Shift><Super>c"];
|
||||||
|
minimize=["<Super>n"];
|
||||||
|
move-to-workspace-1=["<Shift><Super>1"];
|
||||||
|
move-to-workspace-2=["<Shift><Super>2"];
|
||||||
|
move-to-workspace-3=["<Shift><Super>3"];
|
||||||
|
move-to-workspace-4=["<Shift><Super>4"];
|
||||||
|
panel-run-dialog=["<Super>r"];
|
||||||
|
switch-to-workspace-1=["<Super>1"];
|
||||||
|
switch-to-workspace-2=["<Super>2"];
|
||||||
|
switch-to-workspace-3=["<Super>3"];
|
||||||
|
switch-to-workspace-4=["<Super>4"];
|
||||||
|
toggle-fullscreen=["<Super>f"];
|
||||||
|
};
|
||||||
|
"org/gnome/desktop/wm/preferences".num-workspaces = 4;
|
||||||
|
"org/gnome/settings-daemon/plugins/color".night-light-enabled = true;
|
||||||
|
"org/gnome/settings-daemon/plugins/media-keys" = {
|
||||||
|
custom-keybindings = [ "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/"];
|
||||||
|
};
|
||||||
|
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0" = {
|
||||||
|
binding = "<Super>Return";
|
||||||
|
command = "gnome-terminal";
|
||||||
|
name = "terminal";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -12,10 +12,9 @@
|
|||||||
|
|
||||||
services.pipewire = {
|
services.pipewire = {
|
||||||
enable = true;
|
enable = true;
|
||||||
systemWide = true;
|
# systemWide = true;
|
||||||
alsa.enable = true;
|
alsa.enable = true;
|
||||||
alsa.support32Bit = true;
|
alsa.support32Bit = true;
|
||||||
pulse.enable = true;
|
pulse.enable = true;
|
||||||
jack.enable = true;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
44
makefu/2configs/gui/snake-kiosk.nix
Normal file
44
makefu/2configs/gui/snake-kiosk.nix
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
{ pkgs, lib, ... }:
|
||||||
|
{
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
./base.nix
|
||||||
|
];
|
||||||
|
users.users.kiosk = {
|
||||||
|
# packages = [ pkgs.chromium pkgs.vscode ];
|
||||||
|
group = "kiosk";
|
||||||
|
isNormalUser = true;
|
||||||
|
uid = 1003;
|
||||||
|
extraGroups = [ "wheel" "audio" "pulse" "pipewire" ];
|
||||||
|
};
|
||||||
|
users.groups.kiosk.gid = 989 ;
|
||||||
|
services.xserver = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
windowManager = lib.mkForce { awesome.enable = false; };
|
||||||
|
displayManager.gdm.enable = true;
|
||||||
|
displayManager.gdm.autoSuspend = false;
|
||||||
|
displayManager.autoLogin = {
|
||||||
|
enable = true;
|
||||||
|
user = lib.mkForce "kiosk";
|
||||||
|
};
|
||||||
|
displayManager.defaultSession = "gnome";
|
||||||
|
desktopManager.gnome.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.targets.sleep.enable = false;
|
||||||
|
systemd.targets.suspend.enable = false;
|
||||||
|
systemd.targets.hibernate.enable = false;
|
||||||
|
systemd.targets.hybrid-sleep.enable = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
environment.systemPackages = [ pkgs.gnomeExtensions.appindicator ];
|
||||||
|
services.dbus.packages = with pkgs; [ gnome2.GConf gnome3.gnome-settings-daemon ];
|
||||||
|
|
||||||
|
services.pipewire.systemWide = lib.mkForce false;
|
||||||
|
services.pipewire.config.pipewire-pulse = {
|
||||||
|
"pulse.properties"."server.address" = [ "unix:native" "tcp:4713" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -5,11 +5,11 @@
|
|||||||
./base.nix
|
./base.nix
|
||||||
];
|
];
|
||||||
users.users.kiosk = {
|
users.users.kiosk = {
|
||||||
packages = [ pkgs.chromium pkgs.vscode ];
|
packages = with pkgs;[ chromium vscode spotify tartube-yt-dlp ];
|
||||||
group = "kiosk";
|
group = "kiosk";
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
uid = 1003;
|
uid = 1003;
|
||||||
extraGroups = [ "wheel" "audio" "pulse" ];
|
extraGroups = [ "wheel" "audio" "pulse" "pipewire" ];
|
||||||
};
|
};
|
||||||
users.groups.kiosk.gid = 989 ;
|
users.groups.kiosk.gid = 989 ;
|
||||||
services.xserver = {
|
services.xserver = {
|
||||||
@ -31,7 +31,10 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.gnomeExtensions.appindicator ];
|
environment.systemPackages = [
|
||||||
|
pkgs.gnomeExtensions.appindicator pkgs.pavucontrol pkgs.jellyfin-media-player pkgs.chromium pkgs.firefox pkgs.kodi
|
||||||
|
pkgs.pavucontrol
|
||||||
|
];
|
||||||
services.dbus.packages = with pkgs; [ gnome2.GConf gnome3.gnome-settings-daemon ];
|
services.dbus.packages = with pkgs; [ gnome2.GConf gnome3.gnome-settings-daemon ];
|
||||||
|
|
||||||
systemd.services.xset-off = {
|
systemd.services.xset-off = {
|
||||||
@ -45,5 +48,9 @@
|
|||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
services.pipewire.systemWide = lib.mkForce false;
|
||||||
|
services.pipewire.config.pipewire-pulse = {
|
||||||
|
"pulse.properties"."server.address" = [ "unix:native" "tcp:4713" ];
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,8 @@ direnv allow
|
|||||||
size = 900001;
|
size = 900001;
|
||||||
save = 900001;
|
save = 900001;
|
||||||
ignoreDups = true;
|
ignoreDups = true;
|
||||||
|
ignoreSpace = true;
|
||||||
|
|
||||||
extended = true;
|
extended = true;
|
||||||
share = true;
|
share = true;
|
||||||
};
|
};
|
||||||
@ -77,31 +79,32 @@ direnv allow
|
|||||||
xo = "mimeopen";
|
xo = "mimeopen";
|
||||||
nmap = "nmap -oN $HOME/loot/scan-`date +\%s`.nmap -oX $HOME/loot/scan-`date +%s`.xml";
|
nmap = "nmap -oN $HOME/loot/scan-`date +\%s`.nmap -oX $HOME/loot/scan-`date +%s`.xml";
|
||||||
};
|
};
|
||||||
# navi package does not come with the navi.plugin.zsh anymore so we use .src
|
#zplug = {
|
||||||
|
# enable = true;
|
||||||
|
# plugins = [
|
||||||
|
# { name = "denisidoro/navi" ; }
|
||||||
|
# { name = "zsh-users/zsh-autosuggestions" ; }
|
||||||
|
# ];
|
||||||
|
#};
|
||||||
initExtra = ''
|
initExtra = ''
|
||||||
bindkey -e
|
bindkey -e
|
||||||
|
zle -N edit-command-line
|
||||||
|
# ctrl-x ctrl-e
|
||||||
|
bindkey '^xe' edit-command-line
|
||||||
|
bindkey '^x^e' edit-command-line
|
||||||
# shift-tab
|
# shift-tab
|
||||||
bindkey '^[[Z' reverse-menu-complete
|
bindkey '^[[Z' reverse-menu-complete
|
||||||
bindkey "\e[3~" delete-char
|
bindkey "\e[3~" delete-char
|
||||||
zstyle ':completion:*' menu select
|
zstyle ':completion:*' menu select
|
||||||
|
|
||||||
setopt HIST_IGNORE_ALL_DUPS
|
setopt HIST_IGNORE_ALL_DUPS
|
||||||
setopt HIST_IGNORE_SPACE
|
|
||||||
setopt HIST_FIND_NO_DUPS
|
setopt HIST_FIND_NO_DUPS
|
||||||
|
|
||||||
compdef _pass brain
|
compdef _pass brain
|
||||||
zstyle ':completion::complete:brain::' prefix "$HOME/brain"
|
zstyle ':completion::complete:brain::' prefix "$HOME/brain"
|
||||||
|
|
||||||
compdef _pass secrets
|
compdef _pass secrets
|
||||||
zstyle ':completion::complete:secrets::' prefix "$HOME/.secrets-pass/"
|
zstyle ':completion::complete:secrets::' prefix "$HOME/.secrets-pass/"
|
||||||
|
|
||||||
# navi
|
|
||||||
. ${pkgs.navi.src}/shell/navi.plugin.zsh
|
|
||||||
# ctrl-x ctrl-e
|
|
||||||
autoload -U compinit && compinit
|
|
||||||
autoload -U edit-command-line
|
|
||||||
zle -N edit-command-line
|
|
||||||
bindkey '^xe' edit-command-line
|
|
||||||
bindkey '^x^e' edit-command-line
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
#dev = "/dev/web_cam";
|
||||||
|
dev = "/dev/video0";
|
||||||
|
in
|
||||||
{
|
{
|
||||||
services.mjpg-streamer = {
|
services.mjpg-streamer = {
|
||||||
enable = true;
|
enable = true;
|
||||||
inputPlugin = "input_uvc.so -d /dev/web_cam -r 1280x960";
|
inputPlugin = "input_uvc.so -d ${dev} -r 1280x960";
|
||||||
};
|
};
|
||||||
users.users.octoprint.extraGroups = [ "video" ];
|
users.users.octoprint.extraGroups = [ "video" ];
|
||||||
# allow octoprint to access /dev/vchiq
|
# allow octoprint to access /dev/vchiq
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
inherit (import ../lib) btn_cycle_light;
|
inherit (import ../lib) btn_cycle_light;
|
||||||
|
schlafzimmer_komode = "light.schlafzimmer_komode_osram";
|
||||||
|
schlafzimmer_button = "sensor.schlafzimmer_btn2_click";
|
||||||
in {
|
in {
|
||||||
services.home-assistant.config.automation = [
|
services.home-assistant.config.automation = [
|
||||||
# (btn_cycle_light "light.arbeitszimmerbeleuchtung" "arbeitszimmer_btn1")
|
# (btn_cycle_light "light.arbeitszimmerbeleuchtung" "arbeitszimmer_btn1")
|
||||||
(btn_cycle_light "light.schlafzimmer_komode_osram" "schlafzimmer_btn2" 128)
|
|
||||||
{
|
{
|
||||||
alias = "toggle keller";
|
alias = "toggle keller";
|
||||||
trigger = {
|
trigger = {
|
||||||
@ -32,21 +34,35 @@ in {
|
|||||||
service = "light.toggle";
|
service = "light.toggle";
|
||||||
data = {
|
data = {
|
||||||
entity_id = "light.keller_osram";
|
entity_id = "light.keller_osram";
|
||||||
brightness = 50;
|
brightness = 25;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
# (btn_cycle_light "light.wohnzimmerbeleuchtung" "wohnzimmer_btn3")
|
# (btn_cycle_light "light.wohnzimmerbeleuchtung" "wohnzimmer_btn3")
|
||||||
{
|
{
|
||||||
alias = "Turn of all lights via schlafzimmer_btn2 double click";
|
alias = "Dim Toggle schlafzimmer komode";
|
||||||
trigger = {
|
trigger = {
|
||||||
platform = "state";
|
platform = "state";
|
||||||
entity_id = "sensor.schlafzimmer_btn2_click";
|
entity_id = schlafzimmer_button;
|
||||||
|
to = "single";
|
||||||
|
};
|
||||||
|
action = {
|
||||||
|
service = "light.toggle";
|
||||||
|
entity_id = schlafzimmer_komode;
|
||||||
|
brightness = 1;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
alias = "Bright Toggle schlafzimmer komode";
|
||||||
|
trigger = {
|
||||||
|
platform = "state";
|
||||||
|
entity_id = schlafzimmer_button;
|
||||||
to = "double";
|
to = "double";
|
||||||
};
|
};
|
||||||
action = {
|
action = {
|
||||||
service = "light.turn_off";
|
service = "light.toggle";
|
||||||
entity_id = "all";
|
entity_id = schlafzimmer_komode;
|
||||||
|
brightness = 255;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
let
|
let
|
||||||
schranklicht = [
|
schranklicht = [
|
||||||
"light.wohnzimmer_schrank_osram"
|
"light.wohnzimmer_schrank_osram"
|
||||||
"light.wohnzimmer_komode_osram"
|
# "light.wohnzimmer_komode_osram"
|
||||||
];
|
];
|
||||||
weihnachtslicht = "light.wohnzimmer_fenster_lichterkette_licht";
|
weihnachtslicht = "light.wohnzimmer_fenster_lichterkette_licht";
|
||||||
fernsehlicht = "light.wled";
|
fernsehlicht = "light.wled";
|
||||||
@ -31,8 +31,8 @@ in
|
|||||||
automation =
|
automation =
|
||||||
[
|
[
|
||||||
(turn_on schranklicht "-00:30:00")
|
(turn_on schranklicht "-00:30:00")
|
||||||
#(turn_on weihnachtslicht "-00:30:00")
|
(turn_on weihnachtslicht "-00:00:00")
|
||||||
(turn_on fernsehlicht "-00:00:00")
|
#(turn_on fernsehlicht "-00:00:00")
|
||||||
|
|
||||||
{ alias = "Always turn off the urlaub lights at ${final_off}";
|
{ alias = "Always turn off the urlaub lights at ${final_off}";
|
||||||
trigger = [
|
trigger = [
|
||||||
|
@ -7,7 +7,7 @@ Heute ist {{ weekday }}, du solltest gar nicht arbeiten!
|
|||||||
{% else %}
|
{% else %}
|
||||||
Willkommen auf Arbeit Felix.
|
Willkommen auf Arbeit Felix.
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
Das aktuell gewählte Projekt ist {{ states("sensor.felix_project") }}.
|
Dein Projekt ist {{ states("sensor.felix_project") }}.
|
||||||
|
|
||||||
{% set inside = states("sensor.wohnzimmer_temp_temperature") | float | round(2) -%}
|
{% set inside = states("sensor.wohnzimmer_temp_temperature") | float | round(2) -%}
|
||||||
{% set outside = states("sensor.dark_sky_temperature") | float | round(2) -%}
|
{% set outside = states("sensor.dark_sky_temperature") | float | round(2) -%}
|
||||||
|
@ -17,6 +17,7 @@ in {
|
|||||||
./zigbee2mqtt.nix
|
./zigbee2mqtt.nix
|
||||||
# ./multi/flurlicht.nix
|
# ./multi/flurlicht.nix
|
||||||
./multi/kurzzeitwecker.nix
|
./multi/kurzzeitwecker.nix
|
||||||
|
./intents
|
||||||
./multi/the_playlist.nix
|
./multi/the_playlist.nix
|
||||||
./multi/heizung.nix
|
./multi/heizung.nix
|
||||||
# ./multi/fliegen-couter.nix
|
# ./multi/fliegen-couter.nix
|
||||||
@ -92,6 +93,7 @@ in {
|
|||||||
{ type = "homeassistant"; }
|
{ type = "homeassistant"; }
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
tasmota = {};
|
||||||
binary_sensor = [
|
binary_sensor = [
|
||||||
{ platform = "workday";
|
{ platform = "workday";
|
||||||
name = "Arbeitstag";
|
name = "Arbeitstag";
|
||||||
|
30
makefu/2configs/home/ham/docker.nix
Normal file
30
makefu/2configs/home/ham/docker.nix
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
let
|
||||||
|
confdir = "/var/lib/homeassistant-docker";
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
./nginx.nix
|
||||||
|
./mqtt.nix
|
||||||
|
./signal-rest
|
||||||
|
./signal-rest/service.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [ 8123 ];
|
||||||
|
state = [ "/var/lib/hass/known_devices.yaml" ];
|
||||||
|
virtualisation.oci-containers.containers.hass = {
|
||||||
|
image = "homeassistant/home-assistant:latest";
|
||||||
|
environment = {
|
||||||
|
TZ = "Europe/Berlin";
|
||||||
|
UMASK = "007";
|
||||||
|
};
|
||||||
|
extraOptions = ["--net=host" ];
|
||||||
|
volumes = [
|
||||||
|
"${confdir}:/config"
|
||||||
|
#"/data/music:/config/media"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
#"f ${confdir}/docker-run 0770 kiosk kiosk - -"
|
||||||
|
"d ${confdir} 0770 kiosk kiosk - -"
|
||||||
|
];
|
||||||
|
}
|
35
makefu/2configs/home/ham/intents/default.nix
Normal file
35
makefu/2configs/home/ham/intents/default.nix
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
services.home-assistant.config = {
|
||||||
|
intent_script = {
|
||||||
|
GetTime.speech.text = ''
|
||||||
|
Es ist {{ now().hour }} Uhr {{ now().minute }}
|
||||||
|
'';
|
||||||
|
GutenMorgen.speech.text = ''
|
||||||
|
Einen wunderschönen Guten Morgen wünsche ich dir
|
||||||
|
'';
|
||||||
|
WieGehtEsDir.speech.text = ''
|
||||||
|
Mir geht es sehr gut, und dir?
|
||||||
|
'';
|
||||||
|
Statusreport.speech.text = builtins.readFile ./statusbericht.txt.j2;
|
||||||
|
StartMusic = {
|
||||||
|
speech.text = "Spiele {{ music }} musik";
|
||||||
|
action_async = [
|
||||||
|
{
|
||||||
|
service = "media_player.play_media";
|
||||||
|
data_template = {
|
||||||
|
entity_id = "media_player.{{ _intent.siteId }}";
|
||||||
|
media_content_id = builtins.readFile ./music_chooser.txt.j2;
|
||||||
|
media_content_type = "music";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
GetWeather = {
|
||||||
|
#speech.text = ''
|
||||||
|
# {{ states('sensor.openweathermap_weather') }} bei {{ states('sensor.openweathermap_temperature') }} Grad
|
||||||
|
#'';
|
||||||
|
speech.text = "{{ states('sensor.swr_prognose') }}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
13
makefu/2configs/home/ham/intents/music_chooser.txt.j2
Normal file
13
makefu/2configs/home/ham/intents/music_chooser.txt.j2
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{% if music == "lounge" -%}
|
||||||
|
https://cast1.asurahosting.com/proxy/julien/stream.mp3
|
||||||
|
{% elif music == "lassulus" -%}
|
||||||
|
http://radio.lassul.us:8000/radio.mp3
|
||||||
|
{% elif music == "groove" -%}
|
||||||
|
http://ice2.somafm.com/groovesalad-128.mp3
|
||||||
|
{% elif music == "swr3" -%}
|
||||||
|
https://liveradio.swr.de/sw282p3/swr3/play.mp3
|
||||||
|
{% elif music == "swr1" -%}
|
||||||
|
https://liveradio.swr.de/sw282p3/swr1bw/play.mp3
|
||||||
|
{% elif music == "radio" -%}
|
||||||
|
https://liveradio.swr.de/sw282p3/swr1bw/play.mp3
|
||||||
|
{% endif %}
|
37
makefu/2configs/home/ham/intents/statusbericht.txt.j2
Normal file
37
makefu/2configs/home/ham/intents/statusbericht.txt.j2
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
{% set arbeit_heute = is_state("binary_sensor.arbeitstag","on") -%}
|
||||||
|
{% set weekday = ['Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag','Sonntag'][now().weekday()] -%}
|
||||||
|
{% set is_friday = now().weekday() == 4 %}
|
||||||
|
|
||||||
|
Dies ist deine Persönliche Zusammenfassung
|
||||||
|
{% set inside = states("sensor.wohnzimmer_temp_temperature") | float | round(2) -%}
|
||||||
|
{% set outside = states("sensor.dark_sky_temperature") | float | round(2) -%}
|
||||||
|
{% set arbeit_morgen = is_state("binary_sensor.arbeitstag_morgen","on") -%}
|
||||||
|
|
||||||
|
Die Wetteraussichten: {{ states("sensor.dark_sky_hourly_summary") | replace(".","")}} bei {{ states("sensor.dark_sky_temperature") }} Grad mit {{ states("sensor.dark_sky_humidity") | round(0) }}% Luftfeuchtigkeit.
|
||||||
|
{% if states("calendar.abfall_papiermuell") == "on" %}
|
||||||
|
Heute ist Papiermuell, bring noch schnell dein Papier raus
|
||||||
|
{% endif %}
|
||||||
|
{% if states("calendar.abfall_restmuell") == "on" %}
|
||||||
|
Ausserdem ist heute Restmuell.
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
{% if ( outside < inside ) and ( outside > 18 ) %}
|
||||||
|
Draussen ist es gerade {{ ((inside - outside) | round(1) )}} gerade kühler
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
{% set current_count = state_attr("sensor.dwd_weather_warnings_current_warning_level", "warning_count") %}
|
||||||
|
{% for i in range(current_count) %}
|
||||||
|
{% set idx = i + 1 %}
|
||||||
|
{% set headline = state_attr("sensor.dwd_weather_warnings_current_warning_level", "warning_" ~ idx ~ "_headline") %}
|
||||||
|
{% set description = state_attr("sensor.dwd_weather_warnings_current_warning_level", "warning_" ~ idx ~ "_description") %}
|
||||||
|
{% set level = state_attr("sensor.dwd_weather_warnings_current_warning_level", "warning_" ~ idx ~ "_level") %}
|
||||||
|
{% set time_start = state_attr("sensor.dwd_weather_warnings_current_warning_level", "warning_" ~ idx ~ "_start") %}
|
||||||
|
{% set time_end = state_attr("sensor.dwd_weather_warnings_current_warning_level", "warning_" ~ idx ~ "_end") %}
|
||||||
|
Wetterwarnung {{idx}}: {{ headline }} Stufe {{level}} von {{ time_start.strftime("%H:%M") ~ " bis " ~ time_end.strftime("%H:%M") }} Uhr
|
||||||
|
|
||||||
|
{{ description }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if is_friday %}
|
||||||
|
Endlich ist Freitag!
|
||||||
|
{% endif -%}
|
@ -27,12 +27,11 @@ in
|
|||||||
#}
|
#}
|
||||||
{ delay.seconds = 1; }
|
{ delay.seconds = 1; }
|
||||||
{ delay = ''
|
{ delay = ''
|
||||||
{% set duration = state_attr("${entity}","media_duration") %}
|
{% set duration = state_attr("${entity}","media_duration") or 0 %}
|
||||||
{% set seconds = duration % 60 %}
|
{% set seconds = (duration % 60 ) %}
|
||||||
{% set minutes = (duration / 60)|int % 60 %}
|
{% set minutes = (duration / 60)|int % 60 %}
|
||||||
{% set hours = (duration / 3600)|int %}
|
{% set hours = (duration / 3600)|int %}
|
||||||
{{ "%02i:%02i:%02i"|format(hours, minutes, seconds)}}
|
{{ "%02i:%02i:%02i"|format(hours, minutes, seconds)}}
|
||||||
|
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -6,10 +6,30 @@ let
|
|||||||
wohnzimmer_deko = [
|
wohnzimmer_deko = [
|
||||||
"light.wohnzimmer_fernseher_led_strip" # led um fernseher
|
"light.wohnzimmer_fernseher_led_strip" # led um fernseher
|
||||||
"light.wohnzimmer_lichterkette_led_strip" # led um fernsehwand
|
"light.wohnzimmer_lichterkette_led_strip" # led um fernsehwand
|
||||||
"light.kinderzimmer_lichterkette_licht" # led um fenster
|
"light.wohnzimmer_fenster_lichterkette_licht" # led um fenster
|
||||||
];
|
];
|
||||||
in {
|
in {
|
||||||
imports = [ ./tint_wohnzimmer.nix ];
|
imports = [ ./tint_wohnzimmer.nix ];
|
||||||
|
services.home-assistant.config.scene = [
|
||||||
|
{ name = "Wohnzimmer Abendlicht";
|
||||||
|
id = "living_room_evening";
|
||||||
|
entities = {
|
||||||
|
"light.wohnzimmer_komode_osram_light" = {
|
||||||
|
state = "on";
|
||||||
|
brightness = 128;
|
||||||
|
};
|
||||||
|
"light.wohnzimmer_schrank_osram_light" = {
|
||||||
|
state = "on";
|
||||||
|
brightness = 128;
|
||||||
|
};
|
||||||
|
"light.wohnzimmer_fenster_lichterkette_licht" = "on";
|
||||||
|
"light.wohnzimmer_fernseher_led_strip" = {
|
||||||
|
state = "on";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
];
|
||||||
services.home-assistant.config.wled = {};
|
services.home-assistant.config.wled = {};
|
||||||
services.home-assistant.config.light = [
|
services.home-assistant.config.light = [
|
||||||
{
|
{
|
||||||
@ -22,6 +42,11 @@ in {
|
|||||||
name = "Wohnzimmer Deko";
|
name = "Wohnzimmer Deko";
|
||||||
entities = wohnzimmer_deko;
|
entities = wohnzimmer_deko;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
platform = "group";
|
||||||
|
name = "living_room_lights";
|
||||||
|
entities = wohnzimmerbeleuchtung ++ wohnzimmer_deko;
|
||||||
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,11 +3,11 @@ let
|
|||||||
in {
|
in {
|
||||||
services.home-assistant.config = {
|
services.home-assistant.config = {
|
||||||
notify = [
|
notify = [
|
||||||
{
|
#{
|
||||||
platform = "nfandroidtv";
|
#platform = "nfandroidtv";
|
||||||
name = "FireTV Wohnzimmer Notification";
|
#name = "FireTV Wohnzimmer Notification";
|
||||||
host = firetv_stick;
|
#host = firetv_stick;
|
||||||
}
|
#}
|
||||||
];
|
];
|
||||||
media_player = [
|
media_player = [
|
||||||
#{
|
#{
|
||||||
@ -16,12 +16,12 @@ in {
|
|||||||
# host = firetv_stick;
|
# host = firetv_stick;
|
||||||
#}
|
#}
|
||||||
# Configuration needs to be done by hand via web interface "integration"
|
# Configuration needs to be done by hand via web interface "integration"
|
||||||
{ platform = "androidtv";
|
#{ platform = "androidtv";
|
||||||
name = "FireTV Stick Android";
|
# name = "FireTV Stick Android";
|
||||||
device_class = "firetv";
|
# device_class = "firetv";
|
||||||
host = firetv_stick;
|
# host = firetv_stick;
|
||||||
port = 5555;
|
# port = 5555;
|
||||||
}
|
#}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
services.mosquitto = {
|
services.mosquitto = {
|
||||||
enable = true;
|
enable = true;
|
||||||
persistence = false;
|
persistence = false;
|
||||||
settings.max_keepalive = 60;
|
settings.max_keepalive = 1060;
|
||||||
listeners = [
|
listeners = [
|
||||||
{
|
{
|
||||||
port = 1883;
|
port = 1883;
|
||||||
|
@ -9,128 +9,80 @@
|
|||||||
let
|
let
|
||||||
button = "sensor.zigbee_btn2_click";
|
button = "sensor.zigbee_btn2_click";
|
||||||
notify = "notify.signal_home";
|
notify = "notify.signal_home";
|
||||||
|
# für {{ _intent.siteId }} - name of the rhasspy instance: arbeitszimmer
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
services.home-assistant.config = {
|
services.home-assistant.config = {
|
||||||
timer.kurzzeitwecker =
|
automation = [];
|
||||||
{
|
timer.kurzzeitwecker = {
|
||||||
name = "Zigbee Kurzzeitwecker";
|
name = "Wecker Wohnung";
|
||||||
duration = 300;
|
|
||||||
};
|
};
|
||||||
script.add_5_minutes_to_kurzzeitwecker =
|
timer.wecker_arbeitszimmer = {
|
||||||
{
|
name = "Wecker Arbeitszimmer";
|
||||||
alias = "Add 5 minutes to kurzzeitwecker";
|
|
||||||
sequence = [
|
|
||||||
{ service = "timer.pause";
|
|
||||||
entity_id = "timer.kurzzeitwecker";
|
|
||||||
}
|
|
||||||
{ service = "timer.start";
|
|
||||||
data_template = {
|
|
||||||
entity_id = "timer.kurzzeitwecker";
|
|
||||||
duration = ''
|
|
||||||
{% set r = state_attr('timer.kurzzeitwecker', 'remaining') ~ '-0000' %}
|
|
||||||
{% set t = strptime(r, '%H:%M:%S.%f%z') %}
|
|
||||||
{{ (as_timestamp(t) + 300) | timestamp_custom('%H:%M:%S', false) }}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
automation =
|
timer.wecker_wohnzimmer = {
|
||||||
[
|
name = "Wecker Wohnzimmer";
|
||||||
{
|
};
|
||||||
alias = "Start Timer 5min";
|
intent = {};
|
||||||
trigger = {
|
intent_script = {
|
||||||
platform = "state";
|
TimerjobStart = {
|
||||||
entity_id = button;
|
speech.text = ''
|
||||||
to = "single";
|
{% set h = hours|default('0')|string %}
|
||||||
};
|
{% set m = minutes|default('0')|string %}
|
||||||
condition =
|
{% if h == "0" %}
|
||||||
{ condition = "state";
|
Wecker gestellt {{ m }} Minuten
|
||||||
entity_id = "timer.kurzzeitwecker";
|
{% elif m == "0" %}
|
||||||
state = "idle";
|
Wecker gestellt {{ h }} Stunden
|
||||||
};
|
{% else %}
|
||||||
|
Wecker gestellt {{ h }} Stunden und {{ m }} Minuten
|
||||||
|
{% endif %}
|
||||||
|
'';
|
||||||
|
action = [
|
||||||
|
{
|
||||||
|
service = "timer.start";
|
||||||
|
|
||||||
|
data.entity_id = "timer.kurzzeitwecker";
|
||||||
|
data.duration = ''
|
||||||
|
{% set h = hours|default("0")|int %}
|
||||||
|
{% set m = minutes|default("0")|int %}
|
||||||
|
{{ "%02d" | format(h) }}:{{ "%02d" | format(m) }}:00
|
||||||
|
'';
|
||||||
|
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
TimerjobRemaining = {
|
||||||
|
speech.text = ''
|
||||||
|
{% set timer = states('timer.kurzzeitwecker') %}
|
||||||
|
{% if timer == 'idle' %}
|
||||||
|
Wecker läuft nicht
|
||||||
|
{% elif timer == 'active' %}
|
||||||
|
{% set remaining = as_timestamp( state_attr('timer.kurzzeitwecker','finishes_at') )-( as_timestamp(now())) %}
|
||||||
|
{% set s = ((remaining % 60)) | int %}
|
||||||
|
{% set m = ((remaining % 3600) / 60) | int %}
|
||||||
|
{% set h = ((remaining % 86400) / 3600) | int %}
|
||||||
|
{% if h == 0 %}
|
||||||
|
Es verbleiben {{ m }} Minuten und {{ s }} Sekunden
|
||||||
|
{% elif m == 0 %}
|
||||||
|
Es verbleiben {{ h }} Stunden
|
||||||
|
{% elif m == 0 and h == 0 %}
|
||||||
|
Es verbleiben {{ s }} Sekunden
|
||||||
|
{% else %}
|
||||||
|
Es verbleiben {{ h }} Stunden {{ m }} Minuten
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
TimerjobStop = {
|
||||||
|
speech.text = ''
|
||||||
|
Wecker gestoppt
|
||||||
|
'';
|
||||||
action = [
|
action = [
|
||||||
{ service = "timer.start";
|
{ service = "timer.cancel";
|
||||||
entity_id = "timer.kurzzeitwecker";
|
data.entity_id = "timer.kurzzeitwecker";
|
||||||
data.duration = "00:05:00";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
service = notify;
|
|
||||||
data.message = "Timer gestartet {{state_attr('timer.kurzzeitwecker', 'remaining') }}, verbleibend ";
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
};
|
||||||
{
|
};
|
||||||
alias = "Add Timer 5min";
|
|
||||||
trigger = {
|
|
||||||
platform = "state";
|
|
||||||
entity_id = button;
|
|
||||||
to = "single";
|
|
||||||
};
|
|
||||||
condition =
|
|
||||||
{ condition = "state";
|
|
||||||
entity_id = "timer.kurzzeitwecker";
|
|
||||||
state = "active";
|
|
||||||
};
|
|
||||||
|
|
||||||
action = [
|
|
||||||
{ service = "homeassistant.turn_on";
|
|
||||||
entity_id = "script.add_5_minutes_to_kurzzeitwecker";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
service = notify;
|
|
||||||
data.message = ''Timer um 5 minuten verlängert, {{ state_attr('timer.kurzzeitwecker', 'remaining') | truncate(9,True," ") }} verbleibend '';
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
alias = "Stop timer on double click";
|
|
||||||
trigger = [
|
|
||||||
{
|
|
||||||
platform = "state";
|
|
||||||
entity_id = button;
|
|
||||||
to = "double";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
platform = "state";
|
|
||||||
entity_id = button;
|
|
||||||
to = "triple";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
condition =
|
|
||||||
{
|
|
||||||
condition = "state";
|
|
||||||
entity_id = "timer.kurzzeitwecker";
|
|
||||||
state = "active";
|
|
||||||
};
|
|
||||||
|
|
||||||
action = [
|
|
||||||
{
|
|
||||||
service = "timer.cancel";
|
|
||||||
entity_id = "timer.kurzzeitwecker";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
service = notify;
|
|
||||||
data.message = "Timer gestoppt, abgebrochen";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
alias = "Timer Finished";
|
|
||||||
trigger = {
|
|
||||||
platform = "event";
|
|
||||||
event_type = "timer.finished";
|
|
||||||
event_data.entity_id = "timer.kurzzeitwecker";
|
|
||||||
};
|
|
||||||
action = [
|
|
||||||
{
|
|
||||||
service = notify;
|
|
||||||
data.message = "Timer beendet";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -40,5 +40,16 @@
|
|||||||
{ platform = "accuweather";
|
{ platform = "accuweather";
|
||||||
api_key = "!secret accuweather";
|
api_key = "!secret accuweather";
|
||||||
}
|
}
|
||||||
|
{ platform = "scrape";
|
||||||
|
resource = "https://www.swr.de/wetter/wetter-liste-swr-100.html";
|
||||||
|
name = "SWR Prognose";
|
||||||
|
select = "p[data-refresh=\"weather-headline\"]";
|
||||||
|
}
|
||||||
|
{ platform = "scrape";
|
||||||
|
resource = "https://www.swr.de/wetter/wetter-liste-swr-100.html";
|
||||||
|
name = "SWR Prognose Langtext";
|
||||||
|
select = "p[data-refresh=\"weather-text\"]";
|
||||||
|
}
|
||||||
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -1,66 +1,34 @@
|
|||||||
{ lib, config, ... }:
|
{ lib, config, ... }:
|
||||||
|
let
|
||||||
|
port = 8096;
|
||||||
|
in
|
||||||
{
|
{
|
||||||
services.jellyfin.enable = true;
|
services.jellyfin.enable = true;
|
||||||
services.jellyfin.openFirewall = true;
|
# services.jellyfin.openFirewall = true;
|
||||||
|
networking.firewall.interfaces.wiregrill = {
|
||||||
|
allowedTCPPorts = [ 80 port 8920 ];
|
||||||
|
allowedUDPPorts = [ 1900 7359 ];
|
||||||
|
};
|
||||||
state = [ "/var/lib/jellyfin" ];
|
state = [ "/var/lib/jellyfin" ];
|
||||||
users.users.${config.services.jellyfin.user}.extraGroups = [ "download" "video" "render" ];
|
users.users.${config.services.jellyfin.user}.extraGroups = [ "download" "video" "render" ];
|
||||||
|
|
||||||
systemd.services.jellyfin = {
|
systemd.services.jellyfin = {
|
||||||
|
|
||||||
after = [ "media-cloud.mount" ];
|
after = [ "media-cloud.mount" ];
|
||||||
serviceConfig = rec {
|
serviceConfig = rec {
|
||||||
|
RequiresMountFor = [ "/media/cloud" ];
|
||||||
SupplementaryGroups = lib.mkForce [ "video" "render" "download" ];
|
SupplementaryGroups = lib.mkForce [ "video" "render" "download" ];
|
||||||
UMask = lib.mkForce "0077";
|
UMask = lib.mkForce "0077";
|
||||||
|
|
||||||
|
|
||||||
Type = lib.mkForce "simple";
|
|
||||||
StateDirectory = lib.mkForce "jellyfin";
|
|
||||||
StateDirectoryMode = lib.mkForce "0700";
|
|
||||||
CacheDirectory = lib.mkForce "jellyfin";
|
|
||||||
CacheDirectoryMode = lib.mkForce "0700";
|
|
||||||
WorkingDirectory = lib.mkForce "/var/lib/jellyfin";
|
|
||||||
Restart = lib.mkForce "on-failure";
|
|
||||||
TimeoutSec = lib.mkForce 15;
|
|
||||||
SuccessExitStatus = lib.mkForce ["0" "143"];
|
|
||||||
|
|
||||||
# Security options:
|
|
||||||
NoNewPrivileges = lib.mkForce true;
|
|
||||||
SystemCallArchitectures = lib.mkForce "native";
|
|
||||||
# AF_NETLINK needed because Jellyfin monitors the network connection
|
|
||||||
RestrictAddressFamilies = lib.mkForce [ "AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK" ];
|
|
||||||
RestrictNamespaces = lib.mkForce false;
|
|
||||||
RestrictRealtime = lib.mkForce true;
|
|
||||||
RestrictSUIDSGID = lib.mkForce true;
|
|
||||||
ProtectControlGroups = lib.mkForce false;
|
|
||||||
ProtectHostname = lib.mkForce true;
|
|
||||||
ProtectKernelLogs = lib.mkForce false;
|
|
||||||
ProtectKernelModules = lib.mkForce false;
|
|
||||||
ProtectKernelTunables = lib.mkForce false;
|
|
||||||
LockPersonality = lib.mkForce true;
|
|
||||||
PrivateTmp = lib.mkForce false;
|
|
||||||
# needed for hardware accelaration
|
|
||||||
PrivateDevices = lib.mkForce false;
|
|
||||||
PrivateUsers = lib.mkForce true;
|
|
||||||
RemoveIPC = lib.mkForce true;
|
|
||||||
|
|
||||||
SystemCallFilter = lib.mkForce [
|
|
||||||
"~@clock"
|
|
||||||
"~@aio"
|
|
||||||
"~@chown"
|
|
||||||
"~@cpu-emulation"
|
|
||||||
"~@debug"
|
|
||||||
"~@keyring"
|
|
||||||
"~@memlock"
|
|
||||||
"~@module"
|
|
||||||
"~@mount"
|
|
||||||
"~@obsolete"
|
|
||||||
"~@privileged"
|
|
||||||
"~@raw-io"
|
|
||||||
"~@reboot"
|
|
||||||
"~@setuid"
|
|
||||||
"~@swap"
|
|
||||||
];
|
|
||||||
SystemCallErrorNumber = lib.mkForce "EPERM";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
services.nginx.virtualHosts."jelly" = {
|
||||||
|
serverAliases = [
|
||||||
|
"jelly.lan" "movies.lan"
|
||||||
|
"jelly.makefu.w" "makefu.omo.w"
|
||||||
|
];
|
||||||
|
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://localhost:${toString port}";
|
||||||
|
proxyWebsockets = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,7 @@ in
|
|||||||
MusicFolder = "/media/cryptX/music/kinder";
|
MusicFolder = "/media/cryptX/music/kinder";
|
||||||
Address = "0.0.0.0";
|
Address = "0.0.0.0";
|
||||||
};
|
};
|
||||||
systemd.services.navidrome.after = [ "media-cryptX.mount" "cryptsetup.target"
|
systemd.services.navidrome.serviceConfig.RequiresMountFor = [ "/media/cryptX" ];
|
||||||
"local-fs.target" "remote-fs.target" ];
|
|
||||||
|
|
||||||
state = [ "/var/lib/navidrome" ];
|
state = [ "/var/lib/navidrome" ];
|
||||||
# networking.firewall.allowedTCPPorts = [ 4040 ];
|
# networking.firewall.allowedTCPPorts = [ 4040 ];
|
||||||
|
@ -70,15 +70,18 @@ in
|
|||||||
PHOTOPRISM_HTTP_PORT = port; # Built-in Web server port
|
PHOTOPRISM_HTTP_PORT = port; # Built-in Web server port
|
||||||
PHOTOPRISM_HTTP_COMPRESSION = "gzip"; # Improves transfer speed and bandwidth utilization (none or gzip)
|
PHOTOPRISM_HTTP_COMPRESSION = "gzip"; # Improves transfer speed and bandwidth utilization (none or gzip)
|
||||||
PHOTOPRISM_DEBUG = "false"; # Run in debug mode (shows additional log messages)
|
PHOTOPRISM_DEBUG = "false"; # Run in debug mode (shows additional log messages)
|
||||||
PHOTOPRISM_PUBLIC = "true"; # No authentication required (disables password protection)
|
# PHOTOPRISM_PUBLIC = "true"; # No authentication required (disables password protection)
|
||||||
PHOTOPRISM_READONLY = "false"; # Don't modify originals directory (reduced functionality)
|
PHOTOPRISM_READONLY = "false"; # Don't modify originals directory (reduced functionality)
|
||||||
PHOTOPRISM_EXPERIMENTAL = "true"; # Enables experimental features
|
PHOTOPRISM_EXPERIMENTAL = "true"; # Enables experimental features
|
||||||
PHOTOPRISM_DISABLE_WEBDAV = "false"; # Disables built-in WebDAV server
|
# PHOTOPRISM_DISABLE_WEBDAV = "false"; # Disables built-in WebDAV server
|
||||||
PHOTOPRISM_DISABLE_SETTINGS = "false"; # Disables Settings in Web UI
|
PHOTOPRISM_DISABLE_SETTINGS = "false"; # Disables Settings in Web UI
|
||||||
PHOTOPRISM_DISABLE_TENSORFLOW = "false"; # Disables using TensorFlow for image classification
|
PHOTOPRISM_DISABLE_TENSORFLOW = "false"; # Disables using TensorFlow for image classification
|
||||||
PHOTOPRISM_DARKTABLE_PRESETS = "false"; # Enables Darktable presets and disables concurrent RAW conversion
|
PHOTOPRISM_DARKTABLE_PRESETS = "false"; # Enables Darktable presets and disables concurrent RAW conversion
|
||||||
PHOTOPRISM_DETECT_NSFW = "false"; # Flag photos as private that MAY be offensive (requires TensorFlow)
|
PHOTOPRISM_DETECT_NSFW = "false"; # Flag photos as private that MAY be offensive (requires TensorFlow)
|
||||||
PHOTOPRISM_UPLOAD_NSFW = "true"; # Allow uploads that MAY be offensive
|
PHOTOPRISM_UPLOAD_NSFW = "true"; # Allow uploads that MAY be offensive
|
||||||
|
PHOTOPRISM_AUTH_MODE = "password";
|
||||||
|
PHOTOPRISM_ADMIN_USER = "admin";
|
||||||
|
PHOTOPRISM_ADMIN_PASSWORD = "admin";
|
||||||
|
|
||||||
#PHOTOPRISM_DATABASE_DRIVER = "postgres";
|
#PHOTOPRISM_DATABASE_DRIVER = "postgres";
|
||||||
#PHOTOPRISM_DATABASE_SERVER = "postgres-prism:5432";
|
#PHOTOPRISM_DATABASE_SERVER = "postgres-prism:5432";
|
||||||
|
40
makefu/2configs/home/rhasspy/default.nix
Normal file
40
makefu/2configs/home/rhasspy/default.nix
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{ lib,config, ... }:
|
||||||
|
# uses alsa instead of pulseaduio server
|
||||||
|
let
|
||||||
|
profiles = "/var/lib/rhasspy";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
systemd.services.docker-rhasspy.after = [ "network-online.target" ];
|
||||||
|
|
||||||
|
virtualisation.oci-containers.containers.rhasspy = {
|
||||||
|
image = "rhasspy/rhasspy:latest";
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
TZ = "Europe/Berlin";
|
||||||
|
PULSE_SERVER = "tcp:${ config.krebs.build.host.name }:4713";
|
||||||
|
};
|
||||||
|
|
||||||
|
ports = [
|
||||||
|
"12101:12101"
|
||||||
|
];
|
||||||
|
|
||||||
|
volumes = [
|
||||||
|
"/etc/localtime:/etc/localtime:ro"
|
||||||
|
"${profiles}:/profiles"
|
||||||
|
];
|
||||||
|
|
||||||
|
cmd = [ "--user-profiles" "/profiles" "--profile" "de" ];
|
||||||
|
extraOptions = [
|
||||||
|
"--device=/dev/snd:/dev/snd"
|
||||||
|
"--group-add=audio"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d ${profiles} 0770 root root - -"
|
||||||
|
];
|
||||||
|
|
||||||
|
# required to allow rhasspy to connect to pulse server
|
||||||
|
# hardware.pulseaudio.enable = lib.mkForce false;
|
||||||
|
networking.firewall.allowedTCPPorts = [ 4713 ];
|
||||||
|
|
||||||
|
}
|
23
makefu/2configs/home/rhasspy/led-control.nix
Normal file
23
makefu/2configs/home/rhasspy/led-control.nix
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
cfg = pkgs.writeText "hcl-config.json" (builtins.toJSON {
|
||||||
|
engine = "rhasspy";
|
||||||
|
pathToConfig = "/var/lib/rhasspy/de/profile.json";
|
||||||
|
hardware = "respeaker4MicArray";
|
||||||
|
pattern = "fake-name";
|
||||||
|
enableDoA = false;
|
||||||
|
});
|
||||||
|
in {
|
||||||
|
systemd.services.HermesLedControl = {
|
||||||
|
description = "Led Server for ReSpeaker 4-array";
|
||||||
|
after = [ "network-online.target" "docker-rhasspy.service" ] ;
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
# User = "nobody"; # need a user with permissions to run nix-shell
|
||||||
|
ExecStart = "${pkgs.HermesLedControl}/bin/HermesLedControl --hermesLedControlConfig=${toString cfg}";
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = 10;
|
||||||
|
PrivateTmp = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -32,6 +32,10 @@ in
|
|||||||
include_device_information = true;
|
include_device_information = true;
|
||||||
client_id = "zigbee2mqtt";
|
client_id = "zigbee2mqtt";
|
||||||
};
|
};
|
||||||
|
availability = {
|
||||||
|
active.timeout = 10;
|
||||||
|
passive.timeout = 1500;
|
||||||
|
};
|
||||||
frontend = {
|
frontend = {
|
||||||
port = webport;
|
port = webport;
|
||||||
};
|
};
|
||||||
|
7
makefu/2configs/hw/cdrip.nix
Normal file
7
makefu/2configs/hw/cdrip.nix
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
users.users.makefu = {
|
||||||
|
extraGroups = [ "cdrom" ];
|
||||||
|
packages = [ pkgs.glyr pkgs.abcde ];
|
||||||
|
};
|
||||||
|
}
|
6
makefu/2configs/hw/pseyecam.nix
Normal file
6
makefu/2configs/hw/pseyecam.nix
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# https://bugzilla.kernel.org/show_bug.cgi?id=198129
|
||||||
|
{
|
||||||
|
boot.extraModprobeConfig = ''
|
||||||
|
options snd_usb_audio ignore_ctl_error=1
|
||||||
|
'';
|
||||||
|
}
|
@ -37,7 +37,7 @@
|
|||||||
emulateWheel = true;
|
emulateWheel = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
services.tlp.enable = true;
|
services.tlp.enable = ! config.services.power-profiles-daemon.enable;
|
||||||
services.tlp.settings = {
|
services.tlp.settings = {
|
||||||
# BUG: http://linrunner.de/en/tlp/docs/tlp-faq.html#erratic-battery
|
# BUG: http://linrunner.de/en/tlp/docs/tlp-faq.html#erratic-battery
|
||||||
START_CHARGE_THRESH_BAT0 = 95;
|
START_CHARGE_THRESH_BAT0 = 95;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user