pepe,porani: setup media center

This commit is contained in:
Ingolf Wagner 2020-04-10 11:36:58 +02:00
parent 219bfc4786
commit b358052c42
No known key found for this signature in database
GPG key ID: 76BF5F1928B9618B
20 changed files with 148 additions and 1305 deletions

View file

@ -5,22 +5,16 @@
<system/server> <system/server>
./hardware-configuration.nix ./hardware-configuration.nix
#./syncthing.nix ./home-assistant.nix
./kodi.nix
./syncthing.nix
./tinc.nix ./tinc.nix
./wifi-access-point.nix ./wifi-access-point.nix
./home-assistant.nix
]; ];
system.custom.wifi = {
enable = true;
interfaces = [ "wlp3s0" ];
configurationFile = <secrets/wpa_supplicant>;
};
networking.hostName = "pepe"; networking.hostName = "pepe";
services.printing.enable = false;
services.printing.enable = true;
# fonts # fonts
# ----- # -----
@ -28,14 +22,20 @@
programs.custom.xterm.fontSize = 12; programs.custom.xterm.fontSize = 12;
system.custom.fonts.dpi = 100; system.custom.fonts.dpi = 100;
virtualisation = { # networking
docker.enable = false; # ----------
system.custom.wifi = {
virtualbox = { enable = true;
host.enable = false; interfaces = [ "wlp3s0" ];
guest.x11 = false; configurationFile = <secrets/wpa_supplicant>;
guest.enable = false;
}; };
# nix-shell -p speedtest_cli --run speedtest
configuration.fireqos = {
enable = true;
interface = "wlp3s0";
input = 30000;
output = 5000;
balance = false;
}; };
} }

View file

@ -4,7 +4,30 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
{ {
imports = [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix> ]; imports = [
<nixpkgs/nixos/modules/installer/scan/not-detected.nix>
(let mediaUUID = "29ebe5ba-7599-4dd3-99a3-37b9bf8e4d61";
in {
fileSystems."/media" = {
device = "/dev/disk/by-uuid/${mediaUUID}";
fsType = "ext4";
options = [
"nofail"
"noauto"
#"x-systemd.device-timeout=1ms"
];
};
systemd.mounts = [{
enable = true;
options = "nofail,noauto";
type = "ext4";
wantedBy = [ "multi-user.target" ];
what = "/dev/disk/by-uuid/${mediaUUID}";
where = "/media";
}];
})
];
boot.initrd.availableKernelModules = boot.initrd.availableKernelModules =
[ "ehci_pci" "ahci" "usb_storage" "sd_mod" "sdhci_pci" ]; [ "ehci_pci" "ahci" "usb_storage" "sd_mod" "sdhci_pci" ];
@ -29,14 +52,6 @@
fsType = "tmpfs"; fsType = "tmpfs";
}; };
fileSystems."/browsers/" = {
#device = "/dev/ram2";
#fsType = "tmpfs";
options = [ "noatime" "nodiratime" "discard" ];
device = "/dev/secure_vg/browser";
fsType = "ext4";
};
nix.maxJobs = lib.mkDefault 4; nix.maxJobs = lib.mkDefault 4;
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";

View file

@ -10,7 +10,7 @@ in {
./home-assistant/mqtt.nix ./home-assistant/mqtt.nix
#./home-assistant/dayOfWeek.nix #./home-assistant/dayOfWeek.nix
#./home-assistant/timer.nix #./home-assistant/timer.nix
#./home-assistant/kodi.nix ./home-assistant/kodi.nix
#./home-assistant/zigbee2mqtt.nix #./home-assistant/zigbee2mqtt.nix
]; ];

38
configs/pepe/kodi.nix Normal file
View file

@ -0,0 +1,38 @@
{ config, lib, pkgs, ... }: {
services.xserver = {
enable = true;
autorun = false;
desktopManager = {
kodi.enable = true;
default = "kodi";
xterm.enable = false;
};
displayManager = {
sddm = {
enable = true;
autoLogin = {
enable = true;
relogin = true;
user = config.users.users.kodi.name;
};
};
};
};
users = {
# mutableUsers = true;
users.kodi = {
isNormalUser = true;
name = "kodi";
uid = 1338;
initialPassword = lib.fileContents <secrets/kodi/password>;
};
};
# allow everybody in the net to access the wifi
networking.firewall = {
allowedTCPPorts = [ 8080 ];
allowedUDPPorts = [ 8080 ];
};
}

View file

@ -1,4 +0,0 @@
{ config, ... }:
{
}

View file

@ -1,11 +1,21 @@
{ config, pkgs, lib, ... }: { { config, pkgs, lib, ... }: {
users.groups."syncthing".members = [ "mpd" "syncthing" "kodi" ];
custom.samba-share = {
enable = true;
folders = {
movies = config.test.services.syncthing.declarative.folders.movies.path;
music =
config.test.services.syncthing.declarative.folders.music-library.path;
samples = config.test.services.syncthing.declarative.folders.samples.path;
series = config.test.services.syncthing.declarative.folders.series.path;
};
};
test.services.syncthing = { test.services.syncthing = {
enable = true; enable = true;
openDefaultPorts = false; openDefaultPorts = true;
user = "palo";
dataDir = "/home/palo/.syncthing";
configDir = "/home/palo/.syncthing";
declarative = { declarative = {
cert = toString <secrets/syncthing/cert.pem>; cert = toString <secrets/syncthing/cert.pem>;
key = toString <secrets/syncthing/key.pem>; key = toString <secrets/syncthing/key.pem>;
@ -15,47 +25,70 @@
# on encrypted drive # on encrypted drive
# ------------------ # ------------------
desktop = {
enable = true;
path = "/home/palo/desktop";
};
finance = {
enable = true;
path = "/home/palo/finance";
};
# no need to be encrypted # no need to be encrypted
# ----------------------- # -----------------------
book = { books = {
enable = true; enable = true;
path = "/home/palo/books"; path = "/media/syncthing/books";
rescanInterval = 8 * 3600;
}; };
kruck-pepe = { movies = {
enable = true; enable = true;
path = "/home/palo/pepe-kruck"; path = "/media/syncthing/movies";
rescanInterval = 8 * 3600;
}; };
music-library = { music-library = {
enable = true; enable = true;
path = "/home/palo/music-library"; path = "/media/syncthing/music-library";
rescanInterval = 8 * 3600;
}; };
music-projects = { music-library-free = {
enable = true; enable = true;
path = "/home/palo/music-projects"; path = "/media/syncthing/music-library-free";
rescanInterval = 8 * 3600;
}; };
porani-pepe = { porn = {
enable = true; enable = true;
path = "/home/palo/pepe-porani"; path = "/media/syncthing/porn";
rescanInterval = 8 * 3600;
}; };
schasch-pepe = { samples = {
enable = true; enable = true;
path = "/home/palo/pepe-schasch"; path = "/media/syncthing/samples";
rescanInterval = 8 * 3600;
}; };
workout-pepe = { series = {
enable = true; enable = true;
path = "/home/palo/pepe-workout"; path = "/media/syncthing/series";
rescanInterval = 8 * 3600;
};
smartphone-folder = {
enable = true;
path = "/media/syncthing/smartphone-folder";
rescanInterval = 8 * 3600;
};
video-material = {
enable = true;
path = "/media/syncthing/video-material";
}; };
}; };
}; };
}; };
systemd.services."permown._media_syncthing" = {
bindsTo = [ "media.mount" ];
after = [ "media.mount" ];
};
system.permown."/media/syncthing" = {
owner = "syncthing";
group = "syncthing";
umask = "0007";
};
systemd.services."syncthing" = {
bindsTo = [ "media.mount" ];
after = [ "media.mount" ];
};
} }

View file

@ -1,7 +1,7 @@
{ lib, pkgs, ... }: { lib, pkgs, ... }:
let let
wifi = "wlp0s26u1u2"; wifi = "wlp0s29u1u1";
ipAddress = "10.23.45.1"; ipAddress = "10.23.45.1";
prefixLength = 24; prefixLength = 24;
servedAddressRange = "10.23.45.2,10.23.45.150,12h"; servedAddressRange = "10.23.45.2,10.23.45.150,12h";

View file

@ -6,11 +6,7 @@
./tinc.nix ./tinc.nix
./syncthing.nix ./syncthing.nix
#./packages.nix
#./home-assistant.nix
#./wifi-access-point.nix
./kodi.nix ./kodi.nix
#./mpd.nix
]; ];

View file

@ -1,217 +0,0 @@
{ pkgs, config, lib, ... }:
let unstablePkgs = import <nixpkgs-unstable> { };
in {
imports = [
./home-assistant/chaospott.nix
./home-assistant/holiday.nix
./home-assistant/mpd.nix
./home-assistant/sonoff.nix
./home-assistant/mqtt.nix
./home-assistant/dayOfWeek.nix
./home-assistant/timer.nix
./home-assistant/kodi.nix
./home-assistant/zigbee2mqtt.nix
];
services.homeAssistantConfig = {
# turn on to edit GUI
# lovelace = {};
homeassistant = {
latitude = 51.444847;
longitude = 6.967006;
elevation = 116;
auth_providers = [{
type = "trusted_networks";
trusted_networks =
[ config.module.cluster.services.tinc."private".networkSubnet ];
}];
};
prometheus.namespace = "hass";
automation = [
# todo when ich weis ich bin zuhause
#{
# alias = "Licht and wenn Dunkel";
# trigger = {
# platform = "state";
# entity_id = [ "binary_sensor.night" ];
# from = "off";
# to = "on";
# };
# action = [
# {
# service = "switch.turn_on";
# entity_id = "group.kitchen";
# }
# {
# service = "switch.turn_on";
# entity_id = "group.living_room";
# }
# ];
#}
#{
# alias = "Küchen Sensor An";
# trigger = {
# platform = "state";
# entity_id = [ "binary_sensor.motion_1" ];
# to = "on";
# };
# action = {
# service = "switch.turn_on";
# entity_id = "group.kitchen";
# };
#}
#{
# alias = "Küchen Sensor aus";
# trigger = {
# platform = "state";
# entity_id = [ "binary_sensor.motion_1" ];
# to = "off";
# for = "00:00:25";
# };
# action = {
# service = "switch.turn_off";
# entity_id = "group.kitchen";
# };
#}
];
group = {
bed_room = {
name = "Schlafzimmer";
view = false;
};
tv = {
name = "TV";
view = false;
};
living_room = {
name = "Wohnzimmer";
view = false;
};
kitchen = {
name = "Küche";
view = false;
};
today = {
control = "hidden";
name = "Today";
view = false;
entities = [ "sensor.weather_temperature" "sun.sun" ];
};
all_lights = {
name = "All Lights";
view = false;
};
unknown = {
control = "hidden";
name = "Not Used";
view = false;
};
view_rooms = {
name = "Räume";
view = true;
entities = [
"group.all_lights"
"group.bed_room"
"group.living_room"
"group.kitchen"
"group.tv"
];
};
view_overview = {
name = "Übersicht";
view = true;
entities = [ "group.today" ];
};
};
sun = { };
script.turn_all_off.sequence = [ ];
script.turn_all_on.sequence = [ ];
sensor = [
# Weather prediction
{
platform = "zamg";
name = "Weather";
}
];
# todo: add holidays package to home-assiatnt
binary_sensor = [
{
name = "before_workday";
platform = "workday";
country = "DE";
province = "NW";
workdays = [ "mon" "tue" "wed" "thu" "fri" ];
days_offset = 1;
}
{
name = "workday";
platform = "workday";
country = "DE";
province = "NW";
workdays = [ "mon" "tue" "wed" "thu" "fri" ];
}
];
};
services.home-assistant = {
enable = true;
package = unstablePkgs.home-assistant.override {
python3 = unstablePkgs.python36;
extraPackages = python: [
# todo : check which is still needed
python.netdisco
python.xmltodict
python.mpd2
# for mqtt
python.hbmqtt
python.paho-mqtt
# needed for platform workday
(python.buildPythonPackage rec {
pname = "holidays";
version = "0.9.10";
src = python.fetchPypi {
inherit pname version;
sha256 =
"9f06d143eb708e8732230260636938f2f57114e94defd8fa2082408e0d422d6f";
};
doCheck = false;
buildInputs = [ pkgs.dateutils ];
propagatedBuildInputs = [ python."python-dateutil" python."six" ];
meta = with pkgs.stdenv.lib; {
homepage = "https://github.com/dr-prodigy/python-holidays";
license = licenses.mit;
description = "Generate and work with holidays in Python";
maintainers = with maintainers; [ mrVanDalo ];
};
})
];
};
};
}

View file

@ -1,82 +0,0 @@
{ config, pkgs, ... }:
let
name = "chaospott";
folderPath = config.services.home-assistant.configDir;
filePath = "${folderPath}/${name}.json";
in {
services.homeAssistantConfig = {
sensor = [
{
platform = "file";
name = "${name}_aerie";
file_path = filePath;
value_template = "{{ value_json.aerie }}";
}
{
platform = "file";
name = "${name}_cellar";
file_path = filePath;
value_template = "{{ value_json.cellar }}";
}
];
homeassistant = {
whitelist_external_dirs = [ folderPath ];
customize = {
"sensor.${name}_aerie" = {
icon = "mdi:store";
entity_picture = "https://chaospott.de/images/logo.png";
friendly_name = "ChaosPott Oben";
};
"sensor.${name}_cellar" = {
icon = "mdi:store";
entity_picture = "https://chaospott.de/images/logo.png";
friendly_name = "ChaosPott Unten";
};
};
};
group = {
"${name}" = {
name = "ChaosPott (Essen)";
control = "hidden";
entities = [ "sensor.${name}_aerie" "sensor.${name}_cellar" ];
};
view_overview.entities = [ "group.${name}" ];
};
};
systemd.services."${name}" = {
enable = true;
before = [ "home-assistant.service" ];
wantedBy = [ "home-assistant.service" ];
serviceConfig = {
User = "hass";
Type = "oneshot";
};
description = "set ${name} for homeassistant";
script = # sh
''
${pkgs.curl}/bin/curl -Ls https://status.chaospott.de/api \
| ${pkgs.jq}/bin/jq --compact-output \
'.sensors.door_locked |
[.[] | { "\(.location)" : (if .value then "closed" else "open" end) }] |
reduce .[] as $item ({}; . + $item) ' \
>> ${filePath}
'';
};
systemd.timers."${name}" = {
enable = true;
wantedBy = [ "multi-user.target" ];
timerConfig = {
OnCalendar = "hourly";
Persistent = "true";
};
};
}

View file

@ -1,52 +0,0 @@
{ config, ... }:
let
folderPath = config.services.home-assistant.configDir;
filePath = "${folderPath}/dayOfWeek.json";
in {
services.homeAssistantConfig = {
sensor = [{
platform = "file";
name = "day_of_week";
file_path = filePath;
value_template = "{{ value_json.dayOfWeek }}";
}];
homeassistant = {
whitelist_external_dirs = [ folderPath ];
customize."sensor.day_of_week" = {
icon = "mdi:calendar-today";
friendly_name = "Wochen Tag";
};
};
group = { overview.entities = [ "sensor.day_of_week" ]; };
};
systemd.services.dayOfWeek = {
enable = true;
before = [ "home-assistant.service" ];
wantedBy = [ "home-assistant.service" ];
serviceConfig = {
User = "hass";
Type = "oneshot";
};
description = "set day of wek for homeassistant";
script = # sh
''
date +'{"dayOfWeek":"%A"}' >> ${filePath}
'';
};
systemd.timers.dayOfWeek = {
enable = true;
wantedBy = [ "multi-user.target" ];
timerConfig = {
OnCalendar = "00:01:00";
Persistent = "true";
};
};
}

View file

@ -1,92 +0,0 @@
{ config, pkgs, ... }:
let
state = "NW"; # NRW
# state = "BE"; # Berlin
name = "holiday";
folderPath = config.services.home-assistant.configDir;
filePath = "${folderPath}/${name}.json";
in {
services.homeAssistantConfig = {
# todo : use the python tool
sensor = [
{
platform = "file";
name = "${name}_date";
file_path = filePath;
value_template = "{{ value_json.date }}";
}
{
platform = "file";
name = "${name}_name";
file_path = filePath;
value_template = "{{ value_json.name }}";
}
];
homeassistant = {
whitelist_external_dirs = [ folderPath ];
customize = {
"sensor.${name}_date" = {
icon = "mdi:calendar";
friendly_name = "Nächster Feiertag";
};
"sensor.${name}_name" = {
icon = "mdi:calendar";
friendly_name = "Nächster Feiertag";
};
};
};
group = {
holidays = {
name = "Feiertage";
view = false;
control = "hidden";
entities = [ "sensor.${name}_date" "sensor.${name}_name" ];
};
view_overview.entities = [ "group.holidays" ];
};
};
systemd.services."${name}" = {
enable = true;
before = [ "home-assistant.service" ];
wantedBy = [ "home-assistant.service" ];
serviceConfig = {
User = "hass";
Type = "oneshot";
};
description = "set ${name} for homeassistant";
script = # sh
''
${pkgs.curl}/bin/curl \
-Ls "https://feiertage-api.de/api/?jahr=$( date +%Y )&nur_land=${state}" \
| ${pkgs.jq}/bin/jq --compact-output '
map_values( .datum ) |
to_entries |
map( { date: .value, name : .key } ) |
sort_by( .date ) |
map(select ( .date >= "'`date +%Y-%m-%d`'" )) |
.[0]' \
>> ${filePath}
'';
};
systemd.timers."${name}" = {
enable = true;
wantedBy = [ "multi-user.target" ];
timerConfig = {
OnCalendar = "daily";
Persistent = "true";
};
};
}

View file

@ -1,81 +0,0 @@
{ pkgs, config, lib, ... }: {
services.homeAssistantConfig = {
group.view_overview.entities = [ "media_player.kodi" ];
media_player = [{
platform = "kodi";
host = "127.0.0.1";
turn_on_action.service = "script.watch_tv";
turn_off_action.service = "script.stop_watch_tv";
}];
shell_command = {
start_display =
"sudo ${pkgs.systemd}/bin/systemctl start display-manager";
stop_display = "sudo ${pkgs.systemd}/bin/systemctl stop display-manager";
};
script = {
turn_all_off.sequence = [
# todo : use the shell_command here
{
alias = "turn off tv";
service = "switch.turn_off";
data.entity_id = "group.tv";
}
{
alias = "stop kodi";
service = "shell_command.stop_display";
}
];
test_display.sequence = [
{ service = "shell_command.start_display"; }
{ delay.seconds = 20; }
{ service = "shell_command.stop_display"; }
];
watch_tv = {
alias = "Watch TV";
sequence = [
{
alias = "turn on tv";
service = "switch.turn_on";
data.entity_id = "group.tv";
}
{ delay.minutes = 1; }
{
alias = "start kodi";
service = "shell_command.start_display";
}
];
};
stop_watch_tv = {
alias = "Stop TV";
sequence = [
{
alias = "turn off tv";
service = "switch.turn_off";
data.entity_id = "group.tv";
}
{
alias = "stop kodi";
service = "shell_command.stop_display";
}
];
};
};
group.tv.entities = [ "script.watch_tv" "script.stop_watch_tv" ];
};
security.sudo.extraConfig = ''
hass ALL= (root) NOPASSWD: ${pkgs.systemd}/bin/systemctl start display-manager
hass ALL= (root) NOPASSWD: ${pkgs.systemd}/bin/systemctl stop display-manager
'';
}

View file

@ -1,37 +0,0 @@
{ lib, ... }:
{
services.homeAssistantConfig = {
group.view_overview.entities = [ "media_player.mpd" ];
media_player = [{
platform = "mpd";
host = "localhost";
}];
script.turn_all_off.sequence = [{
alias = "turn mpd off";
service = "media_player.turn_off";
data.entity_id = "media_player.mpd";
}];
script.turn_all_on.sequence = [
{
alias = "turn mpd on";
service = "media_player.turn_on";
data.entity_id = "media_player.mpd";
}
{
alias = "Adjust volume";
service = "media_player.volume_set";
data = {
entity_id = "media_player.mpd";
volume_level = "0.90";
};
}
];
};
}

View file

@ -1,27 +0,0 @@
{
services.homeAssistantConfig.mqtt = {
# discovery = false;
# for mosquitto
broker = "127.0.0.1";
username = fileContents <secrets/home-assistant/mqtt-user>;
password = fileContents <secrets/home-assistant/mqtt-password>;
};
services.mosquitto = {
enable = true;
host = "0.0.0.0";
users = {
homeassistant = {
password = lib.fileContents <secrets/mosquitto/password>;
acl = [ "topic readwrite #" ];
};
zigbee = {
password = lib.fileContents <secrets/zigbee/password>;
acl = [ "topic readwrite #" ];
};
};
};
}

View file

@ -1,120 +0,0 @@
{ pkgs, config, lib, ... }:
let unstablePkgs = import <nixpkgs-unstable> { };
in {
services.homeAssistantConfig = let
sonoffSwitches = {
"pal01" = {
label = "Bett";
icon = "mdi:lightbulb-on";
};
"pal02" = {
label = "Lampe";
icon = "mdi:lightbulb-on";
};
"pal03" = {
label = "Couche";
icon = "mdi:lightbulb-on";
};
"pal06" = {
label = "Küche";
icon = "mdi:lightbulb-on";
};
"pal05" = {
label = "TV";
icon = "mdi:television";
};
"pal04" = {
label = "Nummer 4";
icon = "mdi:power-plug-off";
};
"pal07" = {
label = "Nummer 7";
icon = "mdi:power-plug-off";
};
"pal08" = {
label = "Nummer 8";
icon = "mdi:power-plug-off";
};
};
toSwitch = name: "switch.${name}";
in {
homeassistant = {
customize = lib.mapAttrs' (entity: value: {
name = toSwitch entity;
value = {
friendly_name = value.label;
icon = value.icon;
};
}) sonoffSwitches;
};
script.turn_all_off.sequence = [
{
alias = "turn off sonoff";
service = "switch.turn_off";
data.entity_id = "group.all_lights";
}
{
alias = "turn off sonoff";
service = "switch.turn_off";
data.entity_id = "group.tv";
}
];
script.turn_all_on.sequence = [{
alias = "turn on all lights";
service = "switch.turn_on";
data.entity_id = "group.all_lights";
}];
group = {
bed_room = { entities = builtins.map toSwitch [ "pal01" ]; };
living_room = { entities = builtins.map toSwitch [ "pal03" "pal02" ]; };
tv = { entities = builtins.map toSwitch [ "pal05" ]; };
kitchen = { entities = builtins.map toSwitch [ "pal06" ]; };
unknown = {
entities = builtins.map toSwitch [ "pal04" "pal07" "pal08" ];
};
all_lights = {
entities = builtins.map toSwitch [ "pal01" "pal02" "pal03" "pal06" ];
};
};
switch = let
sonoffConfigurations = builtins.map (name: {
name = name;
platform = "mqtt";
command_topic = "cmnd/${lib.toUpper name}/POWER";
state_topic = "stat/${lib.toUpper name}/POWER";
payload_on = "ON";
payload_off = "OFF";
state_on = "ON";
state_off = "OFF";
}) (builtins.attrNames sonoffSwitches);
in sonoffConfigurations;
# discover state on init
automation = [{
alias = "Sonoff initial Power state";
trigger = {
platform = "homeassistant";
event = "start";
};
action = builtins.map (name: {
service = "mqtt.publish";
data = {
topic = "cmnd/${lib.toUpper name}/power";
payload = "";
};
}) (builtins.attrNames sonoffSwitches);
}];
};
}

View file

@ -1,244 +0,0 @@
{ config, ... }: {
imports = [ ./mpd.nix ];
services.homeAssistantConfig = {
sensor = [{
platform = "time_date";
display_options = [ "time" "date" ];
}];
input_datetime = {
wakeup = {
name = "Arbeitswecker";
has_time = true;
has_date = false;
icon = "mdi:alarm";
};
leave = {
name = "Turn off Time";
has_time = true;
has_date = false;
icon = "mdi:alarm";
};
return = {
name = "Return home";
has_time = true;
has_date = false;
icon = "mdi:alarm";
};
sleep = {
name = "Turn off Time";
has_time = true;
has_date = false;
icon = "mdi:alarm";
};
};
input_boolean = {
wakeup = {
name = "enable";
icon = "mdi:toggle-switch";
};
leave = {
name = "enable";
icon = "mdi:toggle-switch";
};
return = {
name = "enable";
icon = "mdi:toggle-switch";
};
sleep = {
name = "enable";
icon = "mdi:toggle-switch";
};
};
input_select = {
wakeup = {
name = "Playlist";
icon = "mdi:library-music";
options = [ "wakeup" "wakeup1" "wakeup2" ];
};
};
binary_sensor = [
{
platform = "tod";
name = "night";
after = "sunset";
before = "sunrise";
}
{
platform = "tod";
name = "daytime";
after = "sunrise";
before = "sunset";
}
];
group = {
timer_wakeup = {
view = false;
name = "Arbeits Aufwachen";
control = "hidden";
entities = [
"input_boolean.wakeup"
"input_datetime.wakeup"
"input_select.wakeup"
];
};
timer_leave = {
view = false;
name = "Leave Time";
control = "hidden";
entities = [ "input_boolean.leave" "input_datetime.leave" ];
};
timer_return = {
view = false;
name = "Nach Hause kommen";
control = "hidden";
entities = [ "input_boolean.return" "input_datetime.return" ];
};
timer_sleep = {
view = false;
name = "Einschlafen";
control = "hidden";
entities = [ "input_boolean.sleep" "input_datetime.sleep" ];
};
timers.entities = [
"group.timer_wakeup"
"group.timer_leave"
"group.timer_return"
"group.timer_sleep"
"binary_sensor.night"
"binary_sensor.daytime"
];
today.entities = [ "sensor.date" "sensor.time" ];
view_overview.entities = [
"group.timer_wakeup"
"group.timer_leave"
"group.timer_return"
"group.timer_sleep"
];
};
automation = [
{
alias = "Wecker Arbeiten";
trigger = {
platform = "template";
value_template =
"{{ states('sensor.time') == (states.input_datetime.wakeup.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}";
};
condition = {
condition = "and";
conditions = [
{
condition = "state";
entity_id = "input_boolean.wakeup";
state = "on";
}
{
condition = "state";
entity_id = "binary_sensor.workday";
state = "on";
}
];
};
action = [
{
alias = "Play wakeup list";
service = "media_player.play_media";
data_template = {
entity_id = "media_player.mpd";
media_content_type = "playlist";
media_content_id = "{{ states('input_select.wakeup') }}";
};
}
{
alias = "turn all on";
service = "script.turn_on";
entity_id = "script.turn_all_on";
}
];
}
{
alias = "Leave Turn all off Timer";
trigger = {
platform = "template";
value_template =
"{{ states('sensor.time') == (states.input_datetime.leave.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}";
};
condition = {
condition = "and";
conditions = [{
condition = "state";
entity_id = "input_boolean.leave";
state = "on";
}];
};
action = [{
alias = "turn all off";
service = "script.turn_on";
entity_id = "script.turn_all_off";
}];
}
{
alias = "Return to Home";
trigger = {
platform = "template";
value_template =
"{{ states('sensor.time') == (states.input_datetime.return.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}";
};
condition = {
condition = "and";
conditions = [{
condition = "state";
entity_id = "input_boolean.return";
state = "on";
}];
};
action = [{
alias = "turn all on";
service = "script.turn_on";
entity_id = "script.turn_all_on";
}];
}
{
alias = "Sleep Turn all off Timer";
trigger = {
platform = "template";
value_template =
"{{ states('sensor.time') == (states.input_datetime.sleep.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}";
};
condition = {
condition = "and";
conditions = [{
condition = "state";
entity_id = "input_boolean.sleep";
state = "on";
}];
};
action = [{
alias = "turn all off";
service = "script.turn_on";
entity_id = "script.turn_all_off";
}];
}
];
};
}

View file

@ -1,279 +0,0 @@
{ pkgs, lib, config, ... }:
let
# allow new devices to join
enablePairing = true;
device = "/dev/ttyACM0";
dataFolder = "/srv/zigbee/data";
sensors = {
buttons = {
"button_1".id = "0x00158d0002b04f65";
"button_2".id = "0x00158d0002b04f09";
"button_3".id = "0x00158d0002b00e04";
};
temperature = {
"temperature_sensor_1".id = "0x00158d0002d79220";
"temperature_sensor_2".id = "0x00158d0002d7913d";
};
motion = { "motion_sensor_1".id = "0x00158d0002fbd451"; };
};
# todo : rename with allSensors
allSensors = with sensors; buttons // temperature // motion;
zigBee2MqttConfig = {
# Home Assistant integration (MQTT discovery)
homeassistant = false;
# homeassistant = true;
# allow new devices to join
permit_join = enablePairing;
# MQTT settings
mqtt = {
# MQTT base topic for zigbee2mqtt MQTT messages
base_topic = "zigbee2mqtt";
# MQTT server URL
server = "mqtt://127.0.0.1:1883";
# MQTT server authentication, uncomment if required:
user = "zigbee";
password = lib.fileContents <secrets/zigbee/password>;
};
# Serial settings
serial = {
port = "/dev/ttyACM0";
# Optional: disable LED of CC2531 USB sniffer
disable_led = true;
};
devices = lib.mapAttrs' (name:
{ id, ... }: {
name = id;
value = {
retain = false;
friendly_name = name;
};
}) allSensors;
};
configurationYaml =
pkgs.writeText "configuration.yml" (builtins.toJSON zigBee2MqttConfig);
in {
imports = [ ./mqtt.nix ];
services.homeAssistantConfig = {
# group.unknown.entities = [ "sensor.button_1" ];
sensor = let
buttons = with lib;
mapAttrsToList (name:
{ ... }: {
platform = "mqtt";
name = name;
icon = "mdi:toggle-switch";
state_topic = "zigbee2mqtt/${name}";
availability_topic = "zigbee2mqtt/bridge/state";
value_template = "{{ value_json.click }}";
}) sensors.buttons;
temperature = with lib;
mapAttrsToList (name:
{ ... }: [
{
platform = "mqtt";
name = name;
state_topic = "zigbee2mqtt/${name}";
availability_topic = "zigbee2mqtt/bridge/state";
unit_of_measurement = "°C";
device_class = "temperature";
value_template = "{{ value_json.temperature }}";
}
{
platform = "mqtt";
name = "humidity_${name}";
state_topic = "zigbee2mqtt/${name}";
availability_topic = "zigbee2mqtt/bridge/state";
unit_of_measurement = "%";
device_class = "humidity";
value_template = "{{ value_json.humidity }}";
}
{
platform = "mqtt";
name = "pressure_${name}";
state_topic = "zigbee2mqtt/${name}";
availability_topic = "zigbee2mqtt/bridge/state";
unit_of_measurement = "hPa";
device_class = "pressure";
value_template = "{{ value_json.pressure }}";
}
]) sensors.temperature;
informations = lib.mapAttrsToList (name:
{ ... }: [
{
platform = "mqtt";
name = "battery_${name}";
state_topic = "zigbee2mqtt/${name}";
availability_topic = "zigbee2mqtt/bridge/state";
unit_of_measurement = "%";
device_class = "battery";
value_template = "{{ value_json.battery }}";
}
{
name = "link_${name}";
platform = "mqtt";
state_topic = "zigbee2mqtt/${name}";
availability_topic = "zigbee2mqtt/bridge/state";
unit_of_measurement = "-";
value_template = "{{ value_json.linkquality }}";
}
]) allSensors;
in lib.flatten (buttons ++ temperature ++ informations);
binary_sensor = let
motion = lib.mapAttrsToList (name:
{ ... }: {
name = name;
platform = "mqtt";
device_class = "motion";
#icon = "mdi:motion-sensor";
state_topic = "zigbee2mqtt/${name}";
availability_topic = "zigbee2mqtt/bridge/state";
payload_on = true;
payload_off = false;
value_template = "{{ value_json.occupancy }}";
}) sensors.motion;
in lib.flatten (motion);
group = let
information = name: [ "sensor.battery_${name}" "sensor.link_${name}" ];
sensor = lib.mapAttrs' (name:
{ ... }: {
name = name;
value = {
control = "hidden";
entities = [ "sensor.${name}" ] ++ (information name);
};
}) (sensors.buttons);
sensorTemperature = lib.mapAttrs' (name:
{ ... }: {
name = name;
value = {
control = "hidden";
entities = [
"sensor.${name}"
"sensor.humidity_${name}"
"sensor.pressure_${name}"
] ++ (information name);
};
}) (sensors.temperature);
binarySensor = lib.mapAttrs' (name:
{ ... }: {
name = name;
value = {
control = "hidden";
entities = [ "binary_sensor.${name}" ] ++ (information name);
};
}) (sensors.motion);
views = {
view_sensors = {
name = "Sensoren";
control = "hidden";
view = true;
entities =
lib.mapAttrsToList (name: { ... }: "group.${name}") allSensors;
};
};
in views // sensor // binarySensor // sensorTemperature;
automation = let
lights = map (button: {
alias = "Toggle all lights, on click";
trigger = {
platform = "mqtt";
topic = "zigbee2mqtt/${button}";
};
condition = {
condition = "template";
value_template = ''{{ "single" == trigger.payload_json.click }}'';
};
action = {
service = "switch.toggle";
entity_id = "group.all_lights";
};
}) [ "button_1" "button_2" "button_3" ];
mpd = map (button: {
alias = "Toggle mpd, on double click";
trigger = {
platform = "mqtt";
topic = "zigbee2mqtt/${button}";
};
condition = {
condition = "template";
value_template = ''{{ "double" == trigger.payload_json.click }}'';
};
action = {
service = "media_player.toggle";
# todo use a group here
entity_id = "media_player.mpd";
};
}) [ "button_1" "button_2" "button_3" ];
in lights ++ mpd;
# click = double => music an aus
# click = hold => film an aus
};
virtualisation.docker.enable = true;
# todo : einen eigenen container bauen mit dockerTool : https://nixos.wiki/wiki/Docker
systemd.services."zigbee2mqtt" = {
enable = true;
description =
"Allows you to use your Zigbee devices without the vendors bridge/gateway.";
after = [ "docker.service" ];
requires = [ "docker.service" ];
# todo : udev rule erstellen, die diesen service erst startet, dieses wanted by ist labil
wantedBy = [ "home-assistant.service" ];
preStart = ''
if [ -f ${dataFolder}/configuration.yaml ]
then
rm ${dataFolder}/configuration.yaml
fi
mkdir -p ${dataFolder}
cat ${configurationYaml} | ${pkgs.yq}/bin/yq --yaml-output '.' > ${dataFolder}/configuration.yaml
'';
restartTriggers = [ configurationYaml ];
script = ''
# delete old instance to ensure update
${pkgs.docker}/bin/docker stop zigbee2mqtt || true && ${pkgs.docker}/bin/docker rm -f zigbee2mqtt || true
# start instance
${pkgs.docker}/bin/docker run \
--network="host" \
--name zigbee2mqtt \
-v ${dataFolder}:/app/data \
--device=${device} \
koenkk/zigbee2mqtt
'';
};
}

View file

@ -245,6 +245,7 @@
}) (map (name: { inherit name; }) [ }) (map (name: { inherit name; }) [
"workhorse" "workhorse"
"porani" "porani"
"pepe"
"sputnik" "sputnik"
] ]
#(lib.attrNames config.module.cluster.services.tinc."private".hosts) #(lib.attrNames config.module.cluster.services.tinc."private".hosts)

View file

@ -94,12 +94,12 @@ with lib; {
enable = lib.mkDefault false; enable = lib.mkDefault false;
id = "vatmy-c2qf4"; id = "vatmy-c2qf4";
watch = false; watch = false;
devices = [ "workhorse" "porani" ]; devices = [ "workhorse" "pepe" "porani" ];
}; };
porn = { porn = {
enable = lib.mkDefault false; enable = lib.mkDefault false;
watch = false; watch = false;
devices = [ "workhorse" ]; devices = [ "workhorse" "pepe" ];
}; };
music-library = { music-library = {
enable = lib.mkDefault false; enable = lib.mkDefault false;
@ -111,7 +111,7 @@ with lib; {
enable = lib.mkDefault false; enable = lib.mkDefault false;
id = "mu9mn-zgvsw"; id = "mu9mn-zgvsw";
watch = false; watch = false;
devices = [ "workout" "workhorse" "mors" ]; devices = [ "workout" "workhorse" "pepe" "mors" ];
}; };
music-projects = { music-projects = {
enable = lib.mkDefault false; enable = lib.mkDefault false;
@ -122,25 +122,25 @@ with lib; {
smartphone-folder = { smartphone-folder = {
enable = lib.mkDefault false; enable = lib.mkDefault false;
watch = false; watch = false;
devices = [ "workout" "workhorse" "sterni" "smartphone" ]; devices = [ "workout" "workhorse" "sterni" "smartphone" "pepe" ];
}; };
samples = { samples = {
enable = lib.mkDefault false; enable = lib.mkDefault false;
id = "pcgkj-tjucd"; id = "pcgkj-tjucd";
watch = false; watch = false;
devices = [ "workout" "workhorse" "sterni" ]; devices = [ "workout" "workhorse" "sterni" "pepe" ];
}; };
series = { series = {
enable = lib.mkDefault false; enable = lib.mkDefault false;
id = "all-series"; id = "all-series";
watch = false; watch = false;
devices = [ "workhorse" "porani" ]; devices = [ "workhorse" "porani" "pepe" ];
}; };
video-material = { video-material = {
enable = lib.mkDefault false; enable = lib.mkDefault false;
id = "wgkun-fec5h"; id = "wgkun-fec5h";
watch = false; watch = false;
devices = [ "workout" "workhorse" ]; devices = [ "workout" "workhorse" "pepe" ];
}; };
windows-sync = { windows-sync = {
@ -149,11 +149,6 @@ with lib; {
watch = false; watch = false;
devices = [ "bumba" "workout" ]; devices = [ "bumba" "workout" ];
}; };
workout-pepe = {
enable = lib.mkDefault false;
devices = [ "pepe" "workout" ];
watch = false;
};
workhorse-sterni = { workhorse-sterni = {
enable = lib.mkDefault false; enable = lib.mkDefault false;
devices = [ "workhorse" "sterni" ]; devices = [ "workhorse" "sterni" ];