Add home-assistant functions
This commit is contained in:
parent
d19347344d
commit
82d5688ef7
|
@ -1,5 +1,37 @@
|
|||
{ pkgs, ... }:
|
||||
{ pkgs, lib, ... }:
|
||||
let
|
||||
haLib = import ./lib.nix lib;
|
||||
inherit (haLib) modules util cards conditions triggers;
|
||||
modes =
|
||||
let
|
||||
empty = {
|
||||
icon = util.mkIcon "account-off";
|
||||
title = "Leer";
|
||||
};
|
||||
heat = {
|
||||
icon = util.mkIcon "radiator";
|
||||
title = "Heizen";
|
||||
};
|
||||
active = {
|
||||
icon = util.mkIcon "account";
|
||||
title = "Aktiv";
|
||||
};
|
||||
force-active = {
|
||||
icon = util.mkIcon "lightbulb-on";
|
||||
title = "Alles An";
|
||||
};
|
||||
vacation = {
|
||||
icon = util.mkIcon "airplane";
|
||||
title = "Urlaub";
|
||||
};
|
||||
in
|
||||
{
|
||||
flat = {
|
||||
title = "Wohnung";
|
||||
name = "flat";
|
||||
options = { inherit active vacation; };
|
||||
};
|
||||
};
|
||||
inherit (import ../../../nix/sources.nix) nixos-unstable;
|
||||
homeAssistantDir = "/disk/persist/home-assistant";
|
||||
in
|
||||
|
@ -10,6 +42,7 @@ in
|
|||
];
|
||||
|
||||
imports = [
|
||||
(modules.mkModeSwitcher modes.flat { })
|
||||
"${nixos-unstable}/nixos/modules/services/misc/home-assistant.nix"
|
||||
./hexa-cards.nix
|
||||
];
|
||||
|
@ -39,16 +72,6 @@ in
|
|||
};
|
||||
};
|
||||
homeassistant = pkgs.privateValue { } "homeassistant-home";
|
||||
logger = {
|
||||
default = "info";
|
||||
logs = {
|
||||
"homeassistant.core" = "debug";
|
||||
"homeassistant.components.zha" = "debug";
|
||||
zigpy = "debug";
|
||||
zigpy_znp = "debug";
|
||||
zhaquirks = "debug";
|
||||
};
|
||||
};
|
||||
frontend.themes.ourdefault = {
|
||||
primary-color = "#858EFF";
|
||||
};
|
||||
|
@ -99,17 +122,19 @@ in
|
|||
}
|
||||
{
|
||||
alias = "Thermostatsteuerung Schlafzimmer";
|
||||
trigger = [
|
||||
{ platform = "state"; entity_id = "input_number.target_temperature_schlafzimmer"; }
|
||||
{ platform = "state"; entity_id = "sensor.schlafzimmer_temperature"; }
|
||||
{ platform = "state"; entity_id = "binary_sensor.schlafzimmerfenster"; }
|
||||
{ platform = "state"; entity_id = "climate.schlafzimmer"; }
|
||||
trigger = with triggers; [
|
||||
(stateTrigger "input_number.target_temperature_schlafzimmer")
|
||||
(stateTrigger "sensor.schlafzimmer_temperature")
|
||||
(stateTrigger "binary_sensor.schlafzimmerfenster")
|
||||
(stateTrigger "climate.schlafzimmer")
|
||||
(modeSwitchTrigger modes.flat)
|
||||
];
|
||||
action = [{
|
||||
choose = [{
|
||||
conditions = [
|
||||
{ condition = "numeric_state"; entity_id = "sensor.schlafzimmer_temperature"; below = "input_number.target_temperature_schlafzimmer"; }
|
||||
{ condition = "state"; entity_id = "binary_sensor.schlafzimmerfenster"; state = "off"; }
|
||||
(conditions.modeIs modes.flat "active")
|
||||
];
|
||||
sequence = {
|
||||
service = "climate.set_temperature";
|
||||
|
@ -125,17 +150,19 @@ in
|
|||
}
|
||||
{
|
||||
alias = "Thermostatsteuerung Küche";
|
||||
trigger = [
|
||||
trigger = with triggers; [
|
||||
{ platform = "state"; entity_id = "input_number.target_temperature_kueche"; }
|
||||
{ platform = "state"; entity_id = "sensor.kueche_temperature"; }
|
||||
{ platform = "state"; entity_id = "binary_sensor.kuechenfenster"; }
|
||||
{ platform = "state"; entity_id = "climate.kueche"; }
|
||||
(modeSwitchTrigger modes.flat)
|
||||
];
|
||||
action = [{
|
||||
choose = [{
|
||||
conditions = [
|
||||
{ condition = "numeric_state"; entity_id = "sensor.kueche_temperature"; below = "input_number.target_temperature_kueche"; }
|
||||
{ condition = "state"; entity_id = "binary_sensor.kuechenfenster"; state = "off"; }
|
||||
(conditions.modeIs modes.flat "active")
|
||||
];
|
||||
sequence = {
|
||||
service = "climate.set_temperature";
|
||||
|
@ -151,14 +178,16 @@ in
|
|||
}
|
||||
{
|
||||
alias = "Thermostatsteuerung Wohnzimmer";
|
||||
trigger = [
|
||||
trigger = with triggers; [
|
||||
{ platform = "state"; entity_id = "input_number.target_temperature_wohnzimmer"; }
|
||||
{ platform = "state"; entity_id = "binary_sensor.wohnzimmerfenster"; }
|
||||
{ platform = "state"; entity_id = "climate.wohnzimmer"; }
|
||||
(modeSwitchTrigger modes.flat)
|
||||
];
|
||||
action = [{
|
||||
choose = [{
|
||||
conditions = [{ condition = "state"; entity_id = "binary_sensor.wohnzimmerfenster"; state = "off"; }];
|
||||
conditions = [{ condition = "state"; entity_id = "binary_sensor.wohnzimmerfenster"; state = "off"; }
|
||||
(conditions.modeIs modes.flat "active")];
|
||||
sequence = {
|
||||
service = "climate.set_temperature";
|
||||
target.area_id = "wohnzimmer";
|
||||
|
@ -179,7 +208,7 @@ in
|
|||
target.entity_id = "input_number.target_temperature_kueche";
|
||||
data.value = ''
|
||||
{% if is_state('input_select.scene_kueche', 'empty') %}
|
||||
17
|
||||
18
|
||||
{% else %}
|
||||
21
|
||||
{% endif %}
|
||||
|
@ -194,7 +223,7 @@ in
|
|||
target.entity_id = "input_number.target_temperature_wohnzimmer";
|
||||
data.value = ''
|
||||
{% if is_state('input_select.scene_wohnzimmer', 'empty') %}
|
||||
17
|
||||
18
|
||||
{% else %}
|
||||
24
|
||||
{% endif %}
|
||||
|
@ -209,7 +238,7 @@ in
|
|||
target.entity_id = "input_number.target_temperature_schlafzimmer";
|
||||
data.value = ''
|
||||
{% if is_state('input_select.scene_schlafzimmer', 'empty') %}
|
||||
17
|
||||
18
|
||||
{% else %}
|
||||
21
|
||||
{% endif %}
|
||||
|
@ -245,19 +274,19 @@ in
|
|||
{
|
||||
alias = "Schlafzimmer vorheizen";
|
||||
trigger = [{ platform = "time"; at = "19:00:00"; } { platform = "time"; at = "04:00:00"; }];
|
||||
condition = [{ condition = "state"; entity_id = "input_select.scene_schlafzimmer"; state = "empty"; }];
|
||||
condition = [{ condition = "state"; entity_id = "input_select.scene_schlafzimmer"; state = "empty"; } (conditions.modeIs modes.flat "active")];
|
||||
action = [{ service = "input_select.select_option"; data.option = "heat"; entity_id = "input_select.scene_schlafzimmer"; }];
|
||||
}
|
||||
{
|
||||
alias = "Schlafzimmer nachts kühl";
|
||||
trigger = [{ platform = "time"; at = "01:00:00"; }];
|
||||
condition = [{ condition = "state"; entity_id = "input_select.scene_schlafzimmer"; state = "heat"; }];
|
||||
condition = [{ condition = "state"; entity_id = "input_select.scene_schlafzimmer"; state = "heat"; } (conditions.modeIs modes.flat "active")];
|
||||
action = [{ service = "input_select.select_option"; data.option = "empty"; entity_id = "input_select.scene_schlafzimmer"; }];
|
||||
}
|
||||
{
|
||||
alias = "Morgens Licht an";
|
||||
trigger = [{ platform = "time"; at = "08:00:00"; }];
|
||||
condition = [{ condition = "state"; entity_id = "input_select.scene_schlafzimmer"; state = "heat"; }];
|
||||
condition = [{ condition = "state"; entity_id = "input_select.scene_schlafzimmer"; state = "heat"; } (conditions.modeIs modes.flat "active")];
|
||||
action = [{ service = "input_select.select_option"; data.option = "active"; entity_id = "input_select.scene_schlafzimmer"; }];
|
||||
}
|
||||
# Warnung für offene Fenster oder Türen
|
||||
|
@ -662,6 +691,7 @@ in
|
|||
flurstack = {
|
||||
type = "vertical-stack";
|
||||
cards = [
|
||||
(cards.modeSwitcher modes.flat)
|
||||
{
|
||||
type = "custom:mini-graph-card";
|
||||
entities = [
|
||||
|
|
12
nixos/roles/home-assistant-local/jinja.nix
Normal file
12
nixos/roles/home-assistant-local/jinja.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
lib: rec {
|
||||
case = default: attrs: ''
|
||||
{% if ${lib.concatStringsSep "\n{% elseif " (lib.mapAttrsToList (condition: result: "${condition} %}\n ${result}") attrs)}
|
||||
{% else %}
|
||||
${default}
|
||||
{% endif %}
|
||||
'';
|
||||
if' = condition: ifTrue: ifFalse: case ifFalse { ${condition} = ifTrue; };
|
||||
or = lhs: rhs: "(${lhs} or ${rhs})";
|
||||
and = lhs: rhs: "(${lhs} and ${rhs})";
|
||||
isState = entity: state: "is_state('${entity}','${state}')";
|
||||
}
|
68
nixos/roles/home-assistant-local/lib.nix
Normal file
68
nixos/roles/home-assistant-local/lib.nix
Normal file
|
@ -0,0 +1,68 @@
|
|||
lib:
|
||||
let
|
||||
# name refers to an internal name
|
||||
# title refers to a human readable name
|
||||
# mode = { name, title, options = { <option_name> : { title , icon } } }
|
||||
in
|
||||
rec {
|
||||
jinja = import ./jinja.nix lib;
|
||||
tap_actions = {
|
||||
setMode = mode: option: {
|
||||
action = "call-service";
|
||||
service = "input_select.select_option";
|
||||
service_data = { entity_id = util.modeSelectEntity mode; inherit option; };
|
||||
};
|
||||
};
|
||||
util = rec {
|
||||
mkIcon = name: "mdi:${name}";
|
||||
mkMode = name: options: { inherit name options; };
|
||||
modeSelectEntity = mode: "input_select.${modeSelectName mode}";
|
||||
modeSelectName = mode: "mode_${mode.name}";
|
||||
modeBinarySensorName = mode: option: "${modeSelectName mode}_is_${option}";
|
||||
modeBinarySensorEntity = mode: option: "binary_sensor.${modeBinarySensorName mode option}";
|
||||
};
|
||||
triggers = rec {
|
||||
stateTrigger = entity: { platform = "state"; entity_id = entity; };
|
||||
modeSwitchTrigger = mode: stateTrigger (util.modeSelectEntity mode);
|
||||
};
|
||||
conditions = {
|
||||
modeIs = mode: option: { condition = "state"; entity_id = util.modeSelectEntity mode; state = option; };
|
||||
};
|
||||
modules = rec {
|
||||
mkHAConfig = attrs: {
|
||||
services.home-assistant.config = attrs;
|
||||
};
|
||||
mkModeSwitcher = mode: attrs: { ... }:
|
||||
let
|
||||
options = builtins.attrNames mode.options;
|
||||
in
|
||||
mkHAConfig {
|
||||
input_select.${util.modeSelectName mode} = { inherit options; } // attrs;
|
||||
template = builtins.map (templates.binarySensorForMode mode) options;
|
||||
};
|
||||
};
|
||||
cards = {
|
||||
modeSwitcher = mode:
|
||||
let
|
||||
mkEntity = optionName: option:
|
||||
{
|
||||
entity = util.modeBinarySensorEntity mode optionName;
|
||||
name = option.title;
|
||||
inherit (option) icon;
|
||||
tap_action = tap_actions.setMode mode optionName;
|
||||
};
|
||||
in
|
||||
{
|
||||
type = "glance";
|
||||
inherit (mode) title;
|
||||
columns = builtins.length (builtins.attrNames mode.options);
|
||||
show_state = false;
|
||||
entities = lib.mapAttrsToList mkEntity mode.options;
|
||||
};
|
||||
};
|
||||
templates = rec {
|
||||
binarySensor = state: attrs: { binary_sensor = [ ({ inherit state; } // attrs) ]; };
|
||||
binarySensorFromCondition = condition: binarySensor (jinja.if' condition "1" "0");
|
||||
binarySensorForMode = mode: option: binarySensorFromCondition (jinja.isState (util.modeSelectEntity mode) option) { name = util.modeBinarySensorName mode option; };
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue