nixos-config/configs/pepe/home-assistant.nix

685 lines
20 KiB
Nix
Raw Normal View History

2020-04-08 16:43:09 +02:00
{ pkgs, config, lib, ... }:
let unstablePkgs = import <nixpkgs-unstable> { };
in {
imports = [
#./home-assistant/mpd.nix
#./home-assistant/timer.nix
2020-04-17 20:59:12 +02:00
./home-assistant/chaospott.nix
2020-04-10 11:36:58 +02:00
./home-assistant/kodi.nix
2020-04-12 13:36:15 +02:00
./home-assistant/mqtt.nix
./home-assistant/sonoff.nix
2020-04-17 20:59:12 +02:00
./home-assistant/stocks.nix
2020-04-12 13:36:15 +02:00
./home-assistant/weather.nix
./home-assistant/workday.nix
2020-04-10 13:50:20 +02:00
./home-assistant/zigbee2mqtt.nix
2020-04-08 16:43:09 +02:00
];
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";
2020-04-16 02:58:44 +02:00
# manual state
# ------------
2020-04-16 01:26:02 +02:00
input_select.situation = {
icon = "mdi:brightness-auto";
2020-04-17 20:59:12 +02:00
options = [
# it is dark outside and I want it to be bright inside
"dark"
# it is bright outside, so no need to be bright inside
"bright"
# it is dark ouside, but I don't want it bright inside
"essential"
];
2020-04-16 01:26:02 +02:00
};
input_boolean.situation_toggle.icon = "mdi:toggle-switch";
2020-04-14 17:29:00 +02:00
# enable presents_tracking
input_boolean.presents_tracking.icon = "mdi:account";
2020-05-02 00:45:54 +02:00
input_select.room_present = {
icon = "mdi:map-marker";
options = [
"kitchen_room_present"
"bath_room_present"
"living_room_present"
"bed_room_present"
"floor_room_present"
"bath_room_present"
];
};
automation = let
2020-04-16 02:58:44 +02:00
# a help function that flattens even 2 times
flatMap = function: list: lib.flatten (map function (lib.flatten list));
allRooms =
[ "living_room" "floor_room" "bath_room" "bed_room" "kitchen_room" ];
# presents <-> absents : light settings
# -------------------------------------
roomSwitches = let
roomPresents = {
# group of the room that should be turned on
roomGroup,
# group of the room that should be turned off
turnOffGroup ? roomGroup,
# group of the room that that indicates presents in the room
presentsGroup,
# global situation
situation,
# brightness for dimable lights
brightness ? 255 }: [
{
alias =
"presents in ${presentsGroup} -> turn lights on in ${roomGroup} for ${situation}";
trigger = {
platform = "state";
entity_id = "group.${presentsGroup}";
from = "off";
to = "on";
};
condition = {
condition = "template";
value_template =
"{{ states( 'input_select.situation' ) == '${situation}' }}";
};
action = [
{
service = "switch.turn_on";
data.entity_id = "group.${roomGroup}";
}
{
service = "light.turn_on";
data = {
entity_id = "group.${roomGroup}";
brightness = brightness;
};
}
];
}
{
alias =
"absents in ${presentsGroup} -> turn lights off ${turnOffGroup} in ${situation}";
trigger = map (minutes: {
platform = "state";
entity_id = "group.${presentsGroup}";
from = "on";
to = "off";
for.seconds = minutes * 60;
}) [ 2 5 10 15 20 25 30 35 40 45 50 55 ];
condition = {
condition = "and";
conditions = [
{
condition = "template";
value_template =
"{{ states( 'input_select.situation' ) == '${situation}' }}";
}
{
condition = "or";
conditions = [
{
condition = "template";
value_template =
"{{ states( 'input_select.room_present' ) != '${presentsGroup}' }}";
}
{
condition = "template";
value_template =
"{{ states( 'input_boolean.presents_tracking' ) == 'off' }}";
}
];
}
];
};
action = [
{
service = "switch.turn_off";
data.entity_id = "group.${turnOffGroup}";
}
{
service = "light.turn_off";
data.entity_id = "group.${turnOffGroup}";
}
];
}
{
alias =
"finally absents in ${presentsGroup} -> turn lights off ${turnOffGroup} in ${situation}";
trigger = [{
platform = "state";
entity_id = "group.${presentsGroup}";
from = "on";
to = "off";
for.seconds = 60 * 60;
}];
condition = {
condition = "template";
value_template =
"{{ states( 'input_select.situation' ) == '${situation}' }}";
};
action = [
{
service = "switch.turn_off";
data.entity_id = "group.${turnOffGroup}";
}
{
service = "light.turn_off";
data.entity_id = "group.${turnOffGroup}";
}
];
}
];
onOffArguments = flatMap (name: [
2020-04-16 01:26:02 +02:00
{
presentsGroup = "${name}_present";
roomGroup = "${name}_lights";
situation = "dark";
2020-04-16 01:26:02 +02:00
}
{
brightness = 30;
presentsGroup = "${name}_present";
roomGroup = "${name}_essential";
situation = "essential";
turnOffGroup = "${name}_lights";
}
{
presentsGroup = "${name}_present";
roomGroup = "${name}_bright";
turnOffGroup = "${name}_lights";
situation = "bright";
}
]) allRooms;
in (flatMap roomPresents onOffArguments);
roomPresentSwitches = let
allRoomPresentGroups = map (name: "${name}_present") allRooms;
switchPresentsTracking =
# group to determine presents
presentGroup:
let
otherRoomPresentGroups =
(builtins.filter (name: name != presentGroup)
allRoomPresentGroups);
in [
{
alias =
"select ${presentGroup} if all other rooms are longer not present/active";
trigger = {
platform = "state";
entity_id = "group.${presentGroup}";
from = "on";
to = "off";
for.seconds = (2 * 60) - 15;
};
condition = {
condition = "and";
conditions = flatMap (otherRoomPresent: {
condition = "state";
entity_id = "group.${otherRoomPresent}";
state = "off";
for.seconds = 1 * 60;
}) otherRoomPresentGroups;
};
action = [{
service = "input_select.select_option";
data = {
entity_id = "input_select.room_present";
option = presentGroup;
};
}];
}
{
alias =
"select ${presentGroup} if no other room is present/active but ${presentGroup} is";
trigger = {
platform = "time_pattern";
minutes = "/1";
};
condition = {
condition = "and";
conditions = [{
condition = "state";
entity_id = "group.${presentGroup}";
state = "on";
for.seconds = 1 * 60;
}] ++ (flatMap (otherRoomPresent: {
condition = "state";
entity_id = "group.${otherRoomPresent}";
state = "off";
for.seconds = 1 * 60;
}) otherRoomPresentGroups);
};
action = [{
service = "input_select.select_option";
data = {
entity_id = "input_select.room_present";
option = presentGroup;
};
}];
}
{
alias = "select ${presentGroup} when entering the room";
trigger = {
platform = "state";
entity_id = "group.${presentGroup}";
from = "off";
to = "on";
};
action = [{
service = "input_select.select_option";
data = {
entity_id = "input_select.room_present";
option = presentGroup;
};
}];
}
];
in (flatMap switchPresentsTracking allRoomPresentGroups);
# change light scene in rooms when changing situation
# ---------------------------------------------------
situationSwitches = let
situationSwitch = {
# old group to turn off
fromRoomGroup,
# new group to turn on
toRoomGroup,
# group to determine presents
presentsGroup,
# old situation
fromSituation,
# new situation
toSituation,
# brightness for dimable lights
brightness ? 255 }: [
{
alias =
"${fromSituation} -> ${toSituation} for ${fromRoomGroup} -> ${toRoomGroup} on";
trigger = {
platform = "state";
entity_id = "input_select.situation";
from = fromSituation;
to = toSituation;
};
condition = {
condition = "state";
entity_id = "group.${presentsGroup}";
state = "on";
};
action = [
{
service = "switch.turn_off";
data.entity_id = "group.${fromRoomGroup}";
}
2020-05-02 00:45:54 +02:00
{
service = "light.turn_off";
data.entity_id = "group.${fromRoomGroup}";
2020-05-02 00:45:54 +02:00
}
{
service = "switch.turn_on";
data.entity_id = "group.${toRoomGroup}";
2020-05-02 00:45:54 +02:00
}
{
service = "light.turn_on";
data = {
entity_id = "group.${toRoomGroup}";
brightness = brightness;
};
2020-05-02 00:45:54 +02:00
}
];
}
{
alias =
"${fromSituation} -> ${toSituation} for ${fromRoomGroup} -> ${toRoomGroup} off";
trigger = {
platform = "state";
entity_id = "input_select.situation";
from = fromSituation;
to = toSituation;
};
condition = {
condition = "state";
entity_id = "group.${presentsGroup}";
state = "off";
};
action = [
{
service = "switch.turn_off";
data.entity_id = "group.${fromRoomGroup}";
}
{
service = "light.turn_off";
data.entity_id = "group.${fromRoomGroup}";
}
];
}
];
allArguments = flatMap (name: [
# essential <-> dark
{
presentsGroup = "${name}_present";
fromSituation = "dark";
toSituation = "essential";
fromRoomGroup = "${name}_lights";
toRoomGroup = "${name}_essential";
brightness = 30;
}
{
presentsGroup = "${name}_present";
fromSituation = "essential";
toSituation = "dark";
fromRoomGroup = "${name}_essential";
toRoomGroup = "${name}_lights";
}
# bright <-> dark
{
presentsGroup = "${name}_present";
fromSituation = "dark";
toSituation = "bright";
fromRoomGroup = "${name}_lights";
toRoomGroup = "${name}_bright";
}
{
presentsGroup = "${name}_present";
fromSituation = "bright";
toSituation = "dark";
fromRoomGroup = "${name}_bright";
toRoomGroup = "${name}_lights";
}
# bright <-> essential
{
presentsGroup = "${name}_present";
fromSituation = "bright";
toSituation = "essential";
fromRoomGroup = "${name}_bright";
toRoomGroup = "${name}_essential";
brightness = 30;
}
{
presentsGroup = "${name}_present";
fromSituation = "essential";
toSituation = "bright";
fromRoomGroup = "${name}_essential";
toRoomGroup = "${name}_bright";
}
]) allRooms;
in flatMap situationSwitch allArguments;
in situationSwitches ++ roomSwitches ++ roomPresentSwitches ++ [
2020-04-17 20:59:12 +02:00
# control situation with buttons
2020-04-16 01:26:02 +02:00
{
alias = "set essential";
trigger = {
platform = "state";
entity_id = "input_boolean.situation_toggle";
from = "off";
to = "on";
};
action = {
service = "input_select.select_option";
data = {
entity_id = "input_select.situation";
option = "essential";
};
};
}
{
alias = "unset essential";
trigger = {
platform = "state";
entity_id = "input_boolean.situation_toggle";
from = "on";
to = "off";
};
action = {
service = "input_select.select_option";
data = {
entity_id = "input_select.situation";
2020-04-17 20:59:12 +02:00
option = "dark";
2020-04-16 01:26:02 +02:00
};
};
2020-04-16 00:22:29 +02:00
}
# trigger outside
{
alias = "set essential";
trigger = [
{
platform = "state";
entity_id = "group.outside";
from = "off";
to = "on";
}
{
platform = "state";
entity_id = "group.outside";
from = "on";
to = "off";
}
];
action = {
service = "input_boolean.turn_off";
data.entity_id = "input_boolean.presents_tracking";
};
}
];
2020-04-08 16:43:09 +02:00
2020-04-14 11:38:40 +02:00
group = let
create_room = { name, description }: {
2020-04-14 11:38:40 +02:00
"${name}" = {
2020-04-16 00:22:29 +02:00
name = "${description}";
2020-04-14 11:38:40 +02:00
view = false;
2020-04-16 00:22:29 +02:00
control = "hidden";
entities = [ ];
};
"${name}_lights" = {
name = "${description} Beleuchtung";
view = false;
entities = [ ];
2020-04-14 11:38:40 +02:00
};
"${name}_present" = {
control = "hidden";
name = "${description} Anwesend";
view = false;
2020-04-15 18:08:27 +02:00
entities = [ ];
2020-04-14 11:38:40 +02:00
};
"${name}_essential" = {
control = "hidden";
name = "${description} Minimale Beleuchtung";
view = false;
entities = [ ];
};
2020-05-03 06:55:38 +02:00
"${name}_bright" = {
control = "hidden";
name = "${description} Tages Beleuchtung";
view = false;
entities = [ ];
};
2020-04-16 00:22:29 +02:00
"view_${name}" = {
name = description;
view = true;
entities = [
"group.${name}"
2020-05-03 06:55:38 +02:00
"group.${name}_bright"
"group.${name}_essential"
2020-04-16 00:22:29 +02:00
"group.${name}_lights"
"group.${name}_present"
];
2020-04-14 11:38:40 +02:00
};
};
create_rooms = rooms:
lib.foldr (a: b: a // b) { } (map create_room rooms);
2020-04-12 21:05:55 +02:00
# rooms
# -----
2020-04-14 11:38:40 +02:00
in (create_rooms [
{
name = "floor_room";
description = "Flur";
}
{
name = "bed_room";
description = "Schlafzimmer";
}
{
name = "living_room";
description = "Wohnzimmer";
}
{
name = "kitchen_room";
description = "Küche";
}
2020-04-15 18:08:27 +02:00
{
name = "bath_room";
description = "Klo";
}
2020-04-14 11:38:40 +02:00
]) // {
2020-04-08 16:43:09 +02:00
view_rooms = {
name = "Räume";
view = true;
entities = [
2020-05-02 00:45:54 +02:00
"group.today"
"group.floor_room"
2020-04-08 16:43:09 +02:00
"group.bed_room"
"group.living_room"
2020-04-12 21:05:55 +02:00
"group.kitchen_room"
2020-04-15 18:08:27 +02:00
"group.bath_room"
];
};
2020-04-12 21:05:55 +02:00
all_room_presents = {
name = "Alle Anwesenheits Raum Sensoren";
entities = [
"group.floor_room_present"
"group.bed_room_present"
"group.living_room_present"
"group.kitchen_room_present"
"group.bath_room_present"
];
};
outside = {
name = "Draußen";
entities = [ ];
};
2020-04-12 21:05:55 +02:00
# overview
# --------
all_sensors = {
2020-04-16 00:10:12 +02:00
name = "Alle Sensoren";
2020-04-12 21:05:55 +02:00
control = "hidden";
};
today = {
control = "hidden";
name = "Today";
view = false;
2020-05-02 00:45:54 +02:00
entities = [
"input_select.situation"
"input_select.room_present"
"input_boolean.presents_tracking"
2020-05-02 00:45:54 +02:00
];
2020-04-12 21:05:55 +02:00
};
2020-04-08 16:43:09 +02:00
view_overview = {
name = "Übersicht";
view = true;
entities = [ "group.today" ];
2020-04-12 19:57:49 +02:00
};
2020-04-12 21:05:55 +02:00
# other stuff
# -----------
tv = {
name = "TV";
view = false;
};
all_lights = {
name = "Alle Lampen";
2020-04-12 21:05:55 +02:00
view = false;
};
unknown = {
2020-04-12 19:57:49 +02:00
control = "hidden";
2020-04-12 21:05:55 +02:00
name = "Not Used";
view = false;
entities = [ ];
2020-04-08 16:43:09 +02:00
};
};
script.turn_all_off.sequence = [ ];
script.turn_all_lights_off.sequence = [ ];
2020-04-08 16:43:09 +02:00
};
services.home-assistant = {
enable = true;
package = unstablePkgs.home-assistant.override {
python3 = unstablePkgs.python37;
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 ];
# };
#})
2020-04-17 20:59:12 +02:00
2020-04-08 16:43:09 +02:00
];
2020-04-17 20:59:12 +02:00
2020-04-08 16:43:09 +02:00
};
};
2020-04-09 01:19:00 +02:00
# host nginx setup
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
"iot.pepe.private" = {
2020-04-09 16:51:39 +02:00
serverAliases = [ "hass.pepe.private" "home.pepe.private" ];
locations."/" = { proxyPass = "http://pepe.private:8123"; };
2020-04-09 01:19:00 +02:00
};
};
};
2020-04-08 16:43:09 +02:00
}