Take down home.maralorn.de
This commit is contained in:
parent
c832adccf1
commit
a1c3681549
|
@ -14,7 +14,7 @@ in
|
|||
../../roles/fonts.nix
|
||||
../../roles/earlyoom.nix
|
||||
../../roles/standalone
|
||||
../../roles/home-assistant-local
|
||||
../../roles/home-assistant
|
||||
];
|
||||
|
||||
fileSystems =
|
||||
|
|
|
@ -25,7 +25,6 @@ in
|
|||
../../roles/kassandra-server.nix
|
||||
../../roles/foundryvtt.nix
|
||||
../../roles/mailman.nix
|
||||
../../roles/home-assistant
|
||||
../../roles/firefox-sync.nix
|
||||
../../roles/goatcounter.nix
|
||||
./web.nix
|
||||
|
|
|
@ -1,783 +0,0 @@
|
|||
{ pkgs, lib, ... }:
|
||||
let
|
||||
haLib = import ./lib.nix lib;
|
||||
inherit (haLib) modules util cards conditions triggers jinja actions tap_actions;
|
||||
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 = "Wohnungsmodus";
|
||||
name = "flat";
|
||||
options = { inherit active vacation; };
|
||||
};
|
||||
wohnzimmer = {
|
||||
title = "Wohnzimmermodus";
|
||||
name = "wohnzimmer";
|
||||
options = { inherit empty heat active force_active; };
|
||||
};
|
||||
kueche = {
|
||||
title = "Küchenmodus";
|
||||
name = "kueche";
|
||||
options = { inherit empty active; };
|
||||
};
|
||||
schlafzimmer = {
|
||||
title = "Schlafzimmermodus";
|
||||
name = "schlafzimmer";
|
||||
options = { inherit empty heat active force_active; };
|
||||
};
|
||||
};
|
||||
fenster = map (name: "binary_sensor.${name}")
|
||||
[
|
||||
"kuechenfenster"
|
||||
"wohnzimmerfenster"
|
||||
"schlafzimmerfenster"
|
||||
"wohnungstuer"
|
||||
];
|
||||
batteries = map (name: "sensor.${name}") [
|
||||
"wohnzimmerfenster_battery"
|
||||
"thermostat_kueche_battery"
|
||||
"thermostat_schlafzimmer_battery"
|
||||
"thermostat_wohnzimmer_battery"
|
||||
"klimasensor_bad_battery"
|
||||
"klimasensor_kueche_battery"
|
||||
"klimasensor_schlafzimmer_battery"
|
||||
"kuechenfenster_battery"
|
||||
"pegasus_battery_level"
|
||||
"schlafzimmerfenster_battery"
|
||||
"wohnungstuer_battery"
|
||||
];
|
||||
inherit (import ../../../nix/sources.nix) nixos-unstable;
|
||||
homeAssistantDir = "/disk/persist/home-assistant";
|
||||
in
|
||||
{
|
||||
|
||||
disabledModules = [
|
||||
"services/misc/home-assistant.nix"
|
||||
];
|
||||
|
||||
imports = [
|
||||
(modules.mkModeSwitcher modes.wohnzimmer { })
|
||||
(modules.mkModeSwitcher modes.kueche { })
|
||||
(modules.mkModeSwitcher modes.schlafzimmer { })
|
||||
(modules.mkModeSwitcher modes.flat { })
|
||||
"${nixos-unstable}/nixos/modules/services/misc/home-assistant.nix"
|
||||
./hexa-cards.nix
|
||||
];
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${homeAssistantDir} - - - - -"
|
||||
];
|
||||
|
||||
services = {
|
||||
home-assistant = {
|
||||
enable = true;
|
||||
package = pkgs.home-assistant.overrideAttrs (
|
||||
oldAttrs: {
|
||||
doInstallCheck = false;
|
||||
patches = (oldAttrs.patches or [ ]) ++ [ ./warnwetter.patch ];
|
||||
}
|
||||
);
|
||||
configDir = homeAssistantDir;
|
||||
config = {
|
||||
shopping_list = { };
|
||||
matrix = {
|
||||
homeserver = "https://matrix.maralorn.de";
|
||||
username = "@marabot:maralorn.de";
|
||||
password = pkgs.privateValue "" "matrix/marabot-pw";
|
||||
};
|
||||
notify = [{ platform = "matrix"; default_room = "#fluffy:maralorn.de"; }];
|
||||
group = {
|
||||
wohnzimmer_lights = {
|
||||
name = "Lichter Wohnzimmer";
|
||||
entities = [ "switch.blaue_lichterkette" "switch.lichterkette_schrank" "switch.lichterkette_fernseher" ];
|
||||
};
|
||||
schlafzimmer_lights = {
|
||||
name = "Lichter Schlafzimmer";
|
||||
entities = [ "switch.lichterkette_schlafzimmer" "switch.weihnachtsstern_schlafzimmer" ];
|
||||
};
|
||||
};
|
||||
homeassistant = pkgs.privateValue { } "homeassistant-home";
|
||||
frontend.themes.ourdefault = {
|
||||
primary-color = "#858EFF";
|
||||
};
|
||||
automation = [
|
||||
{
|
||||
alias = "Set theme at startup'";
|
||||
trigger = { platform = "homeassistant"; event = "start"; };
|
||||
action = { service = "frontend.set_theme"; data.name = "ourdefault"; };
|
||||
}
|
||||
{
|
||||
alias = "Entfeuchtersteuerung Schlafzimmer";
|
||||
trigger = [
|
||||
{ platform = "state"; entity_id = "sensor.schlafzimmer_humidity"; }
|
||||
{ platform = "state"; entity_id = "binary_sensor.schlafzimmerfenster"; }
|
||||
];
|
||||
action = [{
|
||||
choose = [
|
||||
{
|
||||
conditions = [{
|
||||
condition = "or";
|
||||
conditions = [
|
||||
{ condition = "numeric_state"; entity_id = "sensor.schlafzimmer_humidity"; below = 65; }
|
||||
{ condition = "state"; entity_id = "binary_sensor.schlafzimmerfenster"; state = "on"; }
|
||||
];
|
||||
}];
|
||||
sequence = { service = "switch.turn_off"; target.entity_id = "switch.luftentfeuchter"; };
|
||||
}
|
||||
{
|
||||
conditions = [{ condition = "numeric_state"; entity_id = "sensor.schlafzimmer_humidity"; above = 66; }];
|
||||
sequence = { service = "switch.turn_on"; target.entity_id = "switch.luftentfeuchter"; };
|
||||
}
|
||||
];
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Lüftungssteuerung Bad";
|
||||
trigger = [{ platform = "state"; entity_id = "sensor.bad_humidity"; }];
|
||||
action = [{
|
||||
choose = [{
|
||||
conditions = [{ condition = "numeric_state"; entity_id = "sensor.bad_humidity"; above = 66; }];
|
||||
sequence = { service = "switch.turn_on"; target.entity_id = "switch.lueftung_bad"; };
|
||||
}
|
||||
{
|
||||
conditions = [{ condition = "numeric_state"; entity_id = "sensor.bad_humidity"; below = 64; }];
|
||||
sequence = { service = "switch.turn_off"; target.entity_id = "switch.lueftung_bad"; };
|
||||
}];
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Thermostatsteuerung 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";
|
||||
target.area_id = "schlafzimmer";
|
||||
data = { temperature = 30; hvac_mode = "heat"; };
|
||||
};
|
||||
}];
|
||||
default = {
|
||||
service = "climate.turn_off";
|
||||
target.area_id = "schlafzimmer";
|
||||
};
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Thermostatsteuerung Küche";
|
||||
trigger = with triggers; [
|
||||
(stateTrigger "input_number.target_temperature_kueche")
|
||||
(stateTrigger "sensor.kueche_temperature")
|
||||
(stateTrigger "binary_sensor.kuechenfenster")
|
||||
(stateTrigger "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";
|
||||
target.area_id = "kuche";
|
||||
data = { temperature = 30; hvac_mode = "heat"; };
|
||||
};
|
||||
}];
|
||||
default = {
|
||||
service = "climate.turn_off";
|
||||
target.area_id = "kuche";
|
||||
};
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Thermostatsteuerung Wohnzimmer";
|
||||
trigger = with triggers; [
|
||||
(stateTrigger "input_number.target_temperature_wohnzimmer")
|
||||
(stateTrigger "binary_sensor.wohnzimmerfenster")
|
||||
(stateTrigger "climate.wohnzimmer")
|
||||
(modeSwitchTrigger modes.flat)
|
||||
];
|
||||
action = [{
|
||||
choose = [{
|
||||
conditions = [{ condition = "state"; entity_id = "binary_sensor.wohnzimmerfenster"; state = "off"; }
|
||||
(conditions.modeIs modes.flat "active")];
|
||||
sequence = {
|
||||
service = "climate.set_temperature";
|
||||
target.area_id = "wohnzimmer";
|
||||
data = { temperature = "{{ states('input_number.target_temperature_wohnzimmer') | int }}"; hvac_mode = "heat"; };
|
||||
};
|
||||
}];
|
||||
default = {
|
||||
service = "climate.turn_off";
|
||||
target.area_id = "wohnzimmer";
|
||||
};
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Küchentemperatur";
|
||||
trigger = [ (triggers.modeSwitchTrigger modes.kueche) ];
|
||||
action = [{
|
||||
service = "input_number.set_value";
|
||||
target.entity_id = "input_number.target_temperature_kueche";
|
||||
data.value = jinja.if' (jinja.isState (util.modeSelectEntity modes.kueche) "empty") "18" "20.5";
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Wohnzimmertemperatur";
|
||||
trigger = [ (triggers.modeSwitchTrigger modes.wohnzimmer) ];
|
||||
action = [{
|
||||
service = "input_number.set_value";
|
||||
target.entity_id = "input_number.target_temperature_wohnzimmer";
|
||||
data.value = jinja.if' (jinja.isState (util.modeSelectEntity modes.wohnzimmer) "empty") "18" "24";
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Schlafzimmertemperatur";
|
||||
trigger = [ (triggers.modeSwitchTrigger modes.schlafzimmer) ];
|
||||
action = [{
|
||||
service = "input_number.set_value";
|
||||
target.entity_id = "input_number.target_temperature_schlafzimmer";
|
||||
data.value = jinja.if' (jinja.isState (util.modeSelectEntity modes.schlafzimmer) "empty") "18" "20.5";
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Wohnzimmerlichter";
|
||||
trigger = with triggers; [
|
||||
(modeSwitchTrigger modes.wohnzimmer)
|
||||
(stateTrigger "sun.sun")
|
||||
];
|
||||
action = [{
|
||||
service = jinja.if'
|
||||
(jinja.or
|
||||
(jinja.isState (util.modeSelectEntity modes.wohnzimmer) "force_active")
|
||||
(jinja.and
|
||||
(jinja.isState (util.modeSelectEntity modes.wohnzimmer) "active")
|
||||
"state_attr('sun.sun', 'elevation') < 6"))
|
||||
"homeassistant.turn_on"
|
||||
"homeassistant.turn_off";
|
||||
target.entity_id = "group.wohnzimmer_lights";
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Schlafzimmerlichter";
|
||||
trigger = with triggers; [
|
||||
(modeSwitchTrigger modes.schlafzimmer)
|
||||
(stateTrigger "sun.sun")
|
||||
];
|
||||
action = [{
|
||||
service = jinja.if'
|
||||
(jinja.or
|
||||
(jinja.isState (util.modeSelectEntity modes.schlafzimmer) "force_active")
|
||||
(jinja.and
|
||||
(jinja.isState (util.modeSelectEntity modes.schlafzimmer) "active")
|
||||
"state_attr('sun.sun', 'elevation') < 6"))
|
||||
"homeassistant.turn_on"
|
||||
"homeassistant.turn_off";
|
||||
target.entity_id = "group.schlafzimmer_lights";
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Schlafzimmer vorheizen";
|
||||
trigger = [{ platform = "time"; at = "19:00:00"; } { platform = "time"; at = "04:00:00"; }];
|
||||
condition = [
|
||||
(conditions.modeIs modes.schlafzimmer "empty")
|
||||
(conditions.modeIs modes.flat "active")
|
||||
];
|
||||
action = [ (actions.setMode modes.schlafzimmer "heat") ];
|
||||
}
|
||||
{
|
||||
alias = "Schlafzimmer nachts kühl";
|
||||
trigger = [{ platform = "time"; at = "01:00:00"; }];
|
||||
condition = [
|
||||
(conditions.modeIs modes.schlafzimmer "heat")
|
||||
(conditions.modeIs modes.flat "active")
|
||||
];
|
||||
action = [ (actions.setMode modes.schlafzimmer "empty") ];
|
||||
}
|
||||
{
|
||||
alias = "Morgens Licht an";
|
||||
trigger = [{ platform = "time"; at = "07:00:00"; }];
|
||||
condition = [
|
||||
(conditions.modeIs modes.schlafzimmer "heat")
|
||||
(conditions.modeIs modes.flat "active")
|
||||
];
|
||||
action = [ (actions.setMode modes.schlafzimmer "force_active") ];
|
||||
}
|
||||
{
|
||||
alias = "Warnung bei niedrigem Akkustand";
|
||||
trigger = map
|
||||
(limit: {
|
||||
platform = "numeric_state";
|
||||
below = toString limit;
|
||||
entity_id = batteries;
|
||||
}) [ 25 20 15 10 5 4 3 2 1 ];
|
||||
action = [ (actions.notify "{{ trigger.to_state.name }} ist {{ trigger.to_state.value }}%.") ];
|
||||
}
|
||||
# Warnungen für hohe Luftfeuchtigkeit
|
||||
] ++ (map
|
||||
(minutes:
|
||||
{
|
||||
alias = "Warnung bei ${minutes} Minuten offenem Fenster oder offener Tür";
|
||||
trigger = map (name: triggers.stateTrigger name // { to = "on"; for = "00:${minutes}:00"; }) fenster;
|
||||
action = [ (actions.notify "{{ trigger.to_state.name }} ist seit mehr als ${minutes} Minuten offen.") ];
|
||||
})
|
||||
(map toString [ 10 20 30 40 50 60 ]));
|
||||
history = { };
|
||||
image = { };
|
||||
sun = { };
|
||||
logbook = { };
|
||||
config = { };
|
||||
mobile_app = { };
|
||||
recorder = { };
|
||||
ssdp = { };
|
||||
template = [
|
||||
{ sensor = [{ state = "{% if is_state('switch.luftentfeuchter', 'on') %}1{% else %}0{% endif %}"; name = "Luftentfeuchter"; }]; }
|
||||
{ sensor = [{ state = "{% if is_state('switch.lueftung_bad', 'on') %}1{% else %}0{% endif %}"; name = "Lüftung"; }]; }
|
||||
{ sensor = [{ state = "{% if is_state('binary_sensor.schlafzimmerfenster', 'on') %}1{% else %}0{% endif %}"; name = "Schlafzimmerfenster"; }]; }
|
||||
{ sensor = [{ state = "{% if is_state('binary_sensor.wohnzimmerfenster', 'on') %}1{% else %}0{% endif %}"; name = "Balkontür"; }]; }
|
||||
{ sensor = [{ state = "{% if is_state('binary_sensor.kuechenfenster', 'on') %}1{% else %}0{% endif %}"; name = "Küchenfenster"; }]; }
|
||||
{ sensor = [{ state = "{% if is_state('binary_sensor.wohnungstuer', 'on') %}1{% else %}0{% endif %}"; name = "Wohnungstür"; }]; }
|
||||
{ sensor = [{ state = "{% if is_state('climate.schlafzimmer', 'heat') %}1{% else %}0{% endif %}"; name = "Schlafzimmerheizung"; }]; }
|
||||
{ sensor = [{ state = "{% if is_state('climate.wohnzimmer', 'heat') %}1{% else %}0{% endif %}"; name = "Wohnzimmerheizung"; }]; }
|
||||
{ sensor = [{ state = "{% if is_state('climate.kueche', 'heat') %}1{% else %}0{% endif %}"; name = "Küchenheizung"; }]; }
|
||||
{ sensor = [{ state = "{{ state_attr('climate.wohnzimmer', 'current_temperature') }}"; name = "Temperatur Wohnzimmer"; }]; }
|
||||
];
|
||||
input_number = {
|
||||
target_temperature_schlafzimmer = {
|
||||
name = "Zieltemperatur Schlafzimmer";
|
||||
unit_of_measurement = "°C";
|
||||
min = "17";
|
||||
max = "25";
|
||||
step = "0.25";
|
||||
};
|
||||
target_temperature_wohnzimmer = {
|
||||
name = "Zieltemperatur Wohnzimmer";
|
||||
unit_of_measurement = "°C";
|
||||
min = "17";
|
||||
max = "25";
|
||||
step = "0.25";
|
||||
};
|
||||
target_temperature_kueche = {
|
||||
name = "Zieltemperatur Küche";
|
||||
unit_of_measurement = "°C";
|
||||
min = "17";
|
||||
max = "25";
|
||||
step = "0.25";
|
||||
};
|
||||
};
|
||||
system_health = { };
|
||||
zha = {
|
||||
device_config = {
|
||||
"00:12:4b:00:24:c0:ff:52-1".type = "switch"; # Lüftung Bad
|
||||
"00:12:4b:00:24:c1:00:45-1".type = "switch"; # Blaue Lichterkette
|
||||
"00:12:4b:00:24:c1:00:1b-1".type = "switch"; # Luftentfeuchter Schlafzimmer
|
||||
"00:12:4b:00:24:c1:00:05-1".type = "switch"; # Lichterkette Fernseher
|
||||
"00:12:4b:00:24:c0:ff:16-1".type = "switch"; # Lichterkette Schrank
|
||||
"00:12:4b:00:24:c0:ff:a8-1".type = "switch"; # Lichterkette Schlafzimmer
|
||||
"00:12:4b:00:24:c0:ff:ad-1".type = "switch"; # Weihnachtsstern Schlafzimmer
|
||||
};
|
||||
};
|
||||
ipp = { };
|
||||
brother = { };
|
||||
sensor = [
|
||||
{
|
||||
platform = "rmvtransport";
|
||||
next_departure = [
|
||||
{
|
||||
station = "3024634";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
weather = [
|
||||
{
|
||||
platform = "warnwetter";
|
||||
name = "DWD Darmstadt";
|
||||
station_id = "L886";
|
||||
}
|
||||
];
|
||||
http = {
|
||||
use_x_forwarded_for = true;
|
||||
trusted_proxies = [ "::1" ];
|
||||
};
|
||||
prometheus = {
|
||||
namespace = "hass";
|
||||
};
|
||||
};
|
||||
lovelaceConfig =
|
||||
let
|
||||
alertbadges = [
|
||||
{
|
||||
type = "entity-filter";
|
||||
entities = fenster;
|
||||
state_filter = [ "on" ];
|
||||
}
|
||||
{
|
||||
type = "entity-filter";
|
||||
entities = batteries;
|
||||
state_filter = [{ value = 25; operator = "<"; }];
|
||||
}
|
||||
];
|
||||
badges =
|
||||
let
|
||||
badge = mode:
|
||||
{
|
||||
type = "state-label";
|
||||
entity = util.modeSelectEntity mode;
|
||||
name = mode.title;
|
||||
tap_action = tap_actions.cycleMode mode;
|
||||
};
|
||||
in
|
||||
[
|
||||
(badge modes.wohnzimmer)
|
||||
(badge modes.kueche)
|
||||
(badge modes.schlafzimmer)
|
||||
] ++ alertbadges;
|
||||
envstack =
|
||||
{
|
||||
type = "vertical-stack";
|
||||
cards = [
|
||||
{
|
||||
type = "custom:sun-card";
|
||||
}
|
||||
{
|
||||
type = "weather-forecast";
|
||||
entity = "weather.dwd_darmstadt";
|
||||
}
|
||||
{
|
||||
type = "picture";
|
||||
image = "https://www.dwd.de/DWD/wetter/radar/radfilm_hes_akt.gif";
|
||||
}
|
||||
{
|
||||
type = "custom:rmv-card";
|
||||
entity = "sensor.darmstadt_schulstrasse";
|
||||
}
|
||||
];
|
||||
};
|
||||
wohnzimmerstack =
|
||||
{
|
||||
type = "vertical-stack";
|
||||
cards = [
|
||||
(cards.modeSwitcher modes.wohnzimmer)
|
||||
{
|
||||
type = "custom:mini-graph-card";
|
||||
entities = [
|
||||
{ entity = "sensor.temperatur_wohnzimmer"; name = "Temperatur"; show_fill = false; }
|
||||
{ entity = "input_number.target_temperature_wohnzimmer"; name = "Zieltemperatur"; show_fill = false; }
|
||||
{ entity = "sensor.wohnzimmerheizung"; name = "Heizung"; y_axis = "secondary"; show_fill = true; show_points = false; show_line = false; smoothing = false; }
|
||||
];
|
||||
show = {
|
||||
labels = true;
|
||||
labels_secondary = "hover";
|
||||
};
|
||||
lower_bound_secondary = 0;
|
||||
upper_bound_secondary = 1;
|
||||
hours_to_show = 24;
|
||||
update_interval = 30;
|
||||
line_width = 2;
|
||||
hour24 = true;
|
||||
decimals = 1;
|
||||
points_per_hour = 3;
|
||||
state_map = [
|
||||
{ value = 0; label = "Aus"; }
|
||||
{ value = 1; label = "An"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "logbook";
|
||||
entities = [ (util.modeSelectEntity modes.wohnzimmer) "binary_sensor.wohnzimmerfenster" "switch.lichterkette_fernseher" "switch.lichterkette_schrank" "switch.blaue_lichterkette" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
kuechenstack = {
|
||||
type = "vertical-stack";
|
||||
cards = [
|
||||
(cards.modeSwitcher modes.kueche)
|
||||
{
|
||||
type = "custom:mini-graph-card";
|
||||
entities = [
|
||||
{ entity = "sensor.kueche_humidity"; name = "Luftfeuchtigkeit"; show_fill = false; state_adaptive_color = true; }
|
||||
{ entity = "sensor.kuchenfenster"; name = "Fenster"; color = "#ff0000"; y_axis = "secondary"; show_fill = true; show_points = false; show_line = false; smoothing = false; }
|
||||
];
|
||||
color_thresholds = [{ value = 0; color = "#009933"; } { value = 64; color = "#ffbf00"; } { value = 66; color = "#ff0000"; }];
|
||||
color_thresholds_transition = "hard";
|
||||
show = {
|
||||
labels = true;
|
||||
labels_secondary = "hover";
|
||||
};
|
||||
lower_bound_secondary = 0;
|
||||
upper_bound_secondary = 1;
|
||||
hour24 = true;
|
||||
decimals = 1;
|
||||
points_per_hour = 3;
|
||||
hours_to_show = 24;
|
||||
update_interval = 30;
|
||||
line_width = 2;
|
||||
state_map = [
|
||||
{ value = 0; label = "Zu"; }
|
||||
{ value = 1; label = "Auf"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "custom:mini-graph-card";
|
||||
entities = [
|
||||
{ entity = "sensor.kueche_temperature"; name = "Temperatur"; show_fill = false; }
|
||||
{ entity = "input_number.target_temperature_kueche"; name = "Zieltemperatur"; show_fill = false; }
|
||||
{ entity = "sensor.kuchenheizung"; name = "Heizung"; y_axis = "secondary"; show_fill = true; show_points = false; show_line = false; smoothing = false; }
|
||||
];
|
||||
show = {
|
||||
labels = true;
|
||||
labels_secondary = "hover";
|
||||
};
|
||||
lower_bound_secondary = 0;
|
||||
upper_bound_secondary = 1;
|
||||
hours_to_show = 24;
|
||||
update_interval = 30;
|
||||
line_width = 2;
|
||||
hour24 = true;
|
||||
decimals = 1;
|
||||
points_per_hour = 3;
|
||||
state_map = [
|
||||
{ value = 0; label = "Aus"; }
|
||||
{ value = 1; label = "An"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "logbook";
|
||||
entities = [ (util.modeSelectEntity modes.kueche) "climate.kueche" "binary_sensor.kuechenfenster" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
schlafzimmerstack =
|
||||
{
|
||||
type = "vertical-stack";
|
||||
cards = [
|
||||
(cards.modeSwitcher modes.schlafzimmer)
|
||||
{
|
||||
type = "custom:mini-graph-card";
|
||||
entities = [
|
||||
{ entity = "sensor.schlafzimmer_humidity"; name = "Luftfeuchtigkeit"; show_fill = false; state_adaptive_color = true; }
|
||||
{ entity = "sensor.luftentfeuchter"; name = "Entfeuchter"; color = "#0000ff"; y_axis = "secondary"; show_fill = true; show_points = false; show_line = false; smoothing = false; }
|
||||
{ entity = "sensor.schlafzimmerfenster"; name = "Fenster"; color = "#ff0000"; y_axis = "secondary"; show_fill = true; show_points = false; show_line = false; smoothing = false; }
|
||||
];
|
||||
color_thresholds = [{ value = 0; color = "#009933"; } { value = 64; color = "#ffbf00"; } { value = 66; color = "#ff0000"; }];
|
||||
color_thresholds_transition = "hard";
|
||||
show = {
|
||||
labels = true;
|
||||
labels_secondary = "hover";
|
||||
};
|
||||
lower_bound_secondary = 0;
|
||||
upper_bound_secondary = 1;
|
||||
hour24 = true;
|
||||
decimals = 1;
|
||||
points_per_hour = 3;
|
||||
hours_to_show = 24;
|
||||
update_interval = 30;
|
||||
line_width = 2;
|
||||
state_map = [
|
||||
{ value = 0; label = "Aus/Zu"; }
|
||||
{ value = 1; label = "An/Auf"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "custom:mini-graph-card";
|
||||
entities = [
|
||||
{ entity = "sensor.schlafzimmer_temperature"; name = "Temperatur"; show_fill = false; }
|
||||
{ entity = "input_number.target_temperature_schlafzimmer"; name = "Zieltemperatur"; show_fill = false; }
|
||||
{ entity = "sensor.schlafzimmerheizung"; name = "Heizung"; y_axis = "secondary"; show_fill = true; show_points = false; show_line = false; smoothing = false; }
|
||||
];
|
||||
show = {
|
||||
labels = true;
|
||||
labels_secondary = "hover";
|
||||
};
|
||||
lower_bound_secondary = 0;
|
||||
upper_bound_secondary = 1;
|
||||
hours_to_show = 24;
|
||||
update_interval = 30;
|
||||
line_width = 2;
|
||||
hour24 = true;
|
||||
decimals = 1;
|
||||
points_per_hour = 3;
|
||||
state_map = [
|
||||
{ value = 0; label = "Aus"; }
|
||||
{ value = 1; label = "An"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "logbook";
|
||||
entities = [ (util.modeSelectEntity modes.schlafzimmer) "switch.weihnachtsstern_schlafzimmer" "switch.luftentfeuchter" "climate.schlafzimmer" "binary_sensor.schlafzimmerfenster" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
badstack =
|
||||
{
|
||||
type = "vertical-stack";
|
||||
cards = [
|
||||
{
|
||||
type = "glance";
|
||||
title = "Bad";
|
||||
columns = 4;
|
||||
show_state = false;
|
||||
entities = [ ];
|
||||
}
|
||||
{
|
||||
type = "custom:mini-graph-card";
|
||||
entities = [
|
||||
{ entity = "sensor.bad_humidity"; name = "Luftfeuchtigkeit"; show_fill = false; state_adaptive_color = true; }
|
||||
{ entity = "sensor.luftung"; name = "Lüftung"; color = "#0000ff"; y_axis = "secondary"; show_fill = true; show_points = false; show_line = false; smoothing = false; }
|
||||
];
|
||||
color_thresholds = [{ value = 0; color = "#009933"; } { value = 64; color = "#ffbf00"; } { value = 66; color = "#ff0000"; }];
|
||||
color_thresholds_transition = "hard";
|
||||
show = {
|
||||
labels = true;
|
||||
labels_secondary = "hover";
|
||||
};
|
||||
lower_bound_secondary = 0;
|
||||
upper_bound_secondary = 1;
|
||||
hour24 = true;
|
||||
decimals = 1;
|
||||
points_per_hour = 3;
|
||||
hours_to_show = 24;
|
||||
update_interval = 30;
|
||||
line_width = 2;
|
||||
state_map = [
|
||||
{ value = 0; label = "Aus"; }
|
||||
{ value = 1; label = "An"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "custom:mini-graph-card";
|
||||
entities = [
|
||||
{ entity = "sensor.bad_temperature"; name = "Temperatur"; show_fill = false; }
|
||||
];
|
||||
show = {
|
||||
labels = true;
|
||||
labels_secondary = "hover";
|
||||
};
|
||||
lower_bound_secondary = 0;
|
||||
upper_bound_secondary = 1;
|
||||
hours_to_show = 24;
|
||||
update_interval = 30;
|
||||
line_width = 2;
|
||||
hour24 = true;
|
||||
decimals = 1;
|
||||
points_per_hour = 3;
|
||||
state_map = [
|
||||
{ value = 0; label = "Aus"; }
|
||||
{ value = 1; label = "An"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "logbook";
|
||||
entities = [ "switch.lueftung_bad" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
flurstack = {
|
||||
type = "vertical-stack";
|
||||
cards = [
|
||||
(cards.modeSwitcher modes.flat)
|
||||
{
|
||||
type = "custom:mini-graph-card";
|
||||
entities = [
|
||||
{ entity = "sensor.wohnungstur"; name = "Wohnungstür"; color = "#ff0000"; show_fill = true; aggregate_func = "max"; smoothing = false; }
|
||||
];
|
||||
show = {
|
||||
labels = true;
|
||||
};
|
||||
lower_bound = 0;
|
||||
upper_bound = 1;
|
||||
hour24 = true;
|
||||
decimals = 1;
|
||||
points_per_hour = 3;
|
||||
hours_to_show = 24;
|
||||
update_interval = 30;
|
||||
line_width = 2;
|
||||
state_map = [
|
||||
{ value = 0; label = "Zu"; }
|
||||
{ value = 1; label = "Auf"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "logbook";
|
||||
entities = [ "binary_sensor.wohnungstuer" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
in
|
||||
{
|
||||
views = [
|
||||
{
|
||||
icon = "mdi:switch";
|
||||
badges = alertbadges;
|
||||
cards = [
|
||||
(cards.modeSwitcher modes.wohnzimmer)
|
||||
(cards.modeSwitcher modes.kueche)
|
||||
(cards.modeSwitcher modes.schlafzimmer)
|
||||
(cards.modeSwitcher modes.flat)
|
||||
];
|
||||
}
|
||||
{ icon = "mdi:sofa"; inherit badges; cards = [ wohnzimmerstack ]; }
|
||||
{ icon = "mdi:countertop"; inherit badges; cards = [ kuechenstack ]; }
|
||||
{ icon = "mdi:bed-king"; inherit badges; cards = [ schlafzimmerstack ]; }
|
||||
{ icon = "mdi:shower-head"; inherit badges; cards = [ badstack ]; }
|
||||
{ icon = "mdi:door-closed"; inherit badges; cards = [ flurstack ]; }
|
||||
{ icon = "mdi:city"; inherit badges; cards = [ envstack ]; }
|
||||
{ icon = "mdi:floor-plan"; badges = alertbadges; cards = [ wohnzimmerstack kuechenstack schlafzimmerstack badstack ]; }
|
||||
];
|
||||
};
|
||||
};
|
||||
nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
"home.lo.m-0.eu" = {
|
||||
serverAliases = [ "home.vpn.m-0.eu" ];
|
||||
extraConfig = "proxy_buffering off;";
|
||||
locations."/" = {
|
||||
proxyPass = "http://[::1]:8123";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
locations."/custom/" = {
|
||||
alias = "/run/hass/";
|
||||
};
|
||||
};
|
||||
"fluffy.lo.m-0.eu" = {
|
||||
default = true;
|
||||
locations."/".extraConfig = "return 301 http://home.lo.m-0.eu$request_uri;";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
{ pkgs, ... }:
|
||||
let
|
||||
nur = import pkgs.sources.hexa-nur-packages { };
|
||||
|
||||
mkLovelaceModule = name: {
|
||||
url = "custom/${name}.js?${nur.hassLovelaceModules."${name}".version}";
|
||||
type = "module";
|
||||
};
|
||||
in
|
||||
{
|
||||
systemd.tmpfiles.rules = [
|
||||
# Lovelace Cards
|
||||
"d /run/hass 0700 nginx nginx"
|
||||
"L+ /run/hass/mini-graph-card.js - - - - ${nur.hassLovelaceModules.mini-graph-card}/mini-graph-card-bundle.js"
|
||||
"L+ /run/hass/mini-media-player.js - - - - ${nur.hassLovelaceModules.mini-media-player}/mini-media-player-bundle.js"
|
||||
"L+ /run/hass/multiple-entity-row.js - - - - ${nur.hassLovelaceModules.multiple-entity-row}/multiple-entity-row.js"
|
||||
"L+ /run/hass/sun-card.js - - - - ${nur.hassLovelaceModules.sun-card}/sun-card.js"
|
||||
"L+ /run/hass/slider-button-card.js - - - - ${nur.hassLovelaceModules.slider-button-card}/slider-button-card.js"
|
||||
"L+ /run/hass/rmv-card.js - - - - ${nur.hassLovelaceModules.rmv-card}/rmv-card.js"
|
||||
"L+ /run/hass/weather-card-chart.js - - - - ${nur.hassLovelaceModules.weather-card-chart}/weather-card-chart.js"
|
||||
];
|
||||
|
||||
services.home-assistant.config.lovelace = {
|
||||
resources = [
|
||||
(mkLovelaceModule "mini-graph-card")
|
||||
(mkLovelaceModule "mini-media-player")
|
||||
(mkLovelaceModule "multiple-entity-row")
|
||||
(mkLovelaceModule "rmv-card")
|
||||
(mkLovelaceModule "weather-card-chart")
|
||||
(mkLovelaceModule "sun-card")
|
||||
(mkLovelaceModule "slider-button-card")
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
@ -1,481 +0,0 @@
|
|||
From 92f85569b2ec8beabfb7ea6aea462fba5e5af39d Mon Sep 17 00:00:00 2001
|
||||
From: Martin Weinelt <hexa@darmstadt.ccc.de>
|
||||
Date: Sat, 20 Mar 2021 17:33:14 +0100
|
||||
Subject: [PATCH] warnwetter: init
|
||||
|
||||
---
|
||||
CODEOWNERS | 1 +
|
||||
.../components/warnwetter/__init__.py | 1 +
|
||||
.../components/warnwetter/manifest.json | 7 +
|
||||
homeassistant/components/warnwetter/sensor.py | 302 ++++++++++++++++++
|
||||
.../components/warnwetter/weather.py | 115 +++++++
|
||||
5 files changed, 426 insertions(+)
|
||||
create mode 100644 homeassistant/components/warnwetter/__init__.py
|
||||
create mode 100644 homeassistant/components/warnwetter/manifest.json
|
||||
create mode 100644 homeassistant/components/warnwetter/sensor.py
|
||||
create mode 100644 homeassistant/components/warnwetter/weather.py
|
||||
|
||||
diff --git a/CODEOWNERS b/CODEOWNERS
|
||||
index 0e069f94e7..596beebec8 100644
|
||||
--- a/CODEOWNERS
|
||||
+++ b/CODEOWNERS
|
||||
@@ -525,6 +525,7 @@ homeassistant/components/vlc_telnet/* @rodripf @dmcc
|
||||
homeassistant/components/volkszaehler/* @fabaff
|
||||
homeassistant/components/volumio/* @OnFreund
|
||||
homeassistant/components/waqi/* @andrey-git
|
||||
+homeassistant/components/warnwetter/* @mtdcr
|
||||
homeassistant/components/watson_tts/* @rutkai
|
||||
homeassistant/components/weather/* @fabaff
|
||||
homeassistant/components/webostv/* @bendavid
|
||||
diff --git a/homeassistant/components/warnwetter/__init__.py b/homeassistant/components/warnwetter/__init__.py
|
||||
new file mode 100644
|
||||
index 0000000000..538fc5a2dc
|
||||
--- /dev/null
|
||||
+++ b/homeassistant/components/warnwetter/__init__.py
|
||||
@@ -0,0 +1 @@
|
||||
+"""The warnwetter component."""
|
||||
diff --git a/homeassistant/components/warnwetter/manifest.json b/homeassistant/components/warnwetter/manifest.json
|
||||
new file mode 100644
|
||||
index 0000000000..cf37e4824e
|
||||
--- /dev/null
|
||||
+++ b/homeassistant/components/warnwetter/manifest.json
|
||||
@@ -0,0 +1,7 @@
|
||||
+{
|
||||
+ "domain": "warnwetter",
|
||||
+ "name": "DWD WarnWetter API",
|
||||
+ "documentation": "https://www.home-assistant.io/integrations/warnwetter",
|
||||
+ "dependencies": ["weather"],
|
||||
+ "codeowners": ["@mtdcr"]
|
||||
+}
|
||||
diff --git a/homeassistant/components/warnwetter/sensor.py b/homeassistant/components/warnwetter/sensor.py
|
||||
new file mode 100644
|
||||
index 0000000000..65bbe2bdce
|
||||
--- /dev/null
|
||||
+++ b/homeassistant/components/warnwetter/sensor.py
|
||||
@@ -0,0 +1,302 @@
|
||||
+"""Sensor platform for data from WarnWetter."""
|
||||
+from datetime import datetime, timedelta
|
||||
+import json
|
||||
+import logging
|
||||
+from typing import Any, Dict, Optional, Union
|
||||
+
|
||||
+from aiohttp.hdrs import USER_AGENT
|
||||
+import pytz
|
||||
+import requests
|
||||
+import voluptuous as vol
|
||||
+
|
||||
+from homeassistant.components.weather import (
|
||||
+ ATTR_FORECAST_CONDITION,
|
||||
+ ATTR_FORECAST_PRECIPITATION,
|
||||
+ ATTR_FORECAST_TEMP,
|
||||
+ ATTR_FORECAST_TEMP_LOW,
|
||||
+ ATTR_FORECAST_TIME,
|
||||
+ ATTR_FORECAST_WIND_BEARING,
|
||||
+ ATTR_FORECAST_WIND_SPEED,
|
||||
+)
|
||||
+from homeassistant.const import (
|
||||
+ ATTR_ATTRIBUTION,
|
||||
+ ATTR_ICON,
|
||||
+ ATTR_TEMPERATURE,
|
||||
+ ATTR_TIME,
|
||||
+ CONF_MONITORED_CONDITIONS,
|
||||
+ CONF_NAME,
|
||||
+ DEGREE,
|
||||
+ DEVICE_CLASS_HUMIDITY,
|
||||
+ DEVICE_CLASS_PRESSURE,
|
||||
+ DEVICE_CLASS_TEMPERATURE,
|
||||
+ DEVICE_CLASS_TIMESTAMP,
|
||||
+ PERCENTAGE,
|
||||
+ PRESSURE_HPA,
|
||||
+ SPEED_KILOMETERS_PER_HOUR,
|
||||
+ TEMP_CELSIUS,
|
||||
+ TIME_HOURS,
|
||||
+ TIME_MINUTES,
|
||||
+ __version__,
|
||||
+)
|
||||
+import homeassistant.helpers.config_validation as cv
|
||||
+from homeassistant.helpers.entity import Entity
|
||||
+from homeassistant.util import Throttle
|
||||
+
|
||||
+_LOGGER = logging.getLogger(__name__)
|
||||
+
|
||||
+ATTR_STATION = "station"
|
||||
+ATTR_UPDATED = "updated"
|
||||
+ATTRIBUTION = "Data provided by WarnWetter"
|
||||
+
|
||||
+CONF_STATION_ID = "station_id"
|
||||
+
|
||||
+MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=10)
|
||||
+MIN_TIME_BETWEEN_FORECAST_UPDATES = timedelta(minutes=30)
|
||||
+
|
||||
+ATTR_DEWPOINT = "dewpoint"
|
||||
+ATTR_HUMIDITY = "humidity"
|
||||
+ATTR_MAXWIND = "maxwind"
|
||||
+ATTR_MEANWIND = "meanwind"
|
||||
+ATTR_PRECIPITATION = "precipitation"
|
||||
+ATTR_PRECIPITATION3H = "precipitation3h"
|
||||
+ATTR_PRESSURE = "pressure"
|
||||
+ATTR_SUNSHINE = "sunshine"
|
||||
+ATTR_TOTALSNOW = "totalsnow"
|
||||
+ATTR_WINDDIRECTION = "winddirection"
|
||||
+
|
||||
+SENSOR_TYPES = {
|
||||
+ ATTR_DEWPOINT: ("Dew Point", DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, 10),
|
||||
+ ATTR_HUMIDITY: ("Humidity", DEVICE_CLASS_HUMIDITY, PERCENTAGE, 10),
|
||||
+ ATTR_ICON: ("Icon", None, None, 1),
|
||||
+ ATTR_MAXWIND: ("Top Wind Speed", None, SPEED_KILOMETERS_PER_HOUR, 10),
|
||||
+ ATTR_MEANWIND: ("Wind Speed", None, SPEED_KILOMETERS_PER_HOUR, 10),
|
||||
+ ATTR_PRECIPITATION: ("Precipitation", None, f"mm/{TIME_HOURS}", 10),
|
||||
+ ATTR_PRECIPITATION3H: (
|
||||
+ f"Precipitation 3{TIME_HOURS}",
|
||||
+ None,
|
||||
+ f"mm/3{TIME_HOURS}",
|
||||
+ 10,
|
||||
+ ),
|
||||
+ ATTR_PRESSURE: ("Pressure", DEVICE_CLASS_PRESSURE, PRESSURE_HPA, 10),
|
||||
+ ATTR_SUNSHINE: ("Sun Last Hour", None, TIME_MINUTES, 10),
|
||||
+ ATTR_TEMPERATURE: ("Temperature", DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, 10),
|
||||
+ ATTR_TIME: ("Update Time", DEVICE_CLASS_TIMESTAMP, None, 1000),
|
||||
+ ATTR_TOTALSNOW: ("Snow", None, "cm", 10),
|
||||
+ ATTR_WINDDIRECTION: ("Wind Bearing", None, DEGREE, 10),
|
||||
+}
|
||||
+
|
||||
+CONDITION_CLASSES = {
|
||||
+ "cloudy": {4},
|
||||
+ "fog": {5, 6},
|
||||
+ "hail": {17, 24, 25},
|
||||
+ "lightning": {26},
|
||||
+ "lightning-rainy": {27, 28, 29, 30},
|
||||
+ "partlycloudy": {2, 3},
|
||||
+ "pouring": {18, 19},
|
||||
+ "rainy": {7, 8, 9, 10, 11},
|
||||
+ "snowy": {14, 15, 16, 22, 23},
|
||||
+ "snowy-rainy": {12, 13, 20, 21},
|
||||
+ "sunny": {1},
|
||||
+ "windy": {31},
|
||||
+}
|
||||
+
|
||||
+PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend(
|
||||
+ {
|
||||
+ vol.Required(CONF_MONITORED_CONDITIONS, default=["temperature"]): vol.All(
|
||||
+ cv.ensure_list, [vol.In(SENSOR_TYPES)]
|
||||
+ ),
|
||||
+ vol.Required(CONF_STATION_ID): cv.string,
|
||||
+ vol.Required(CONF_NAME): cv.string,
|
||||
+ }
|
||||
+)
|
||||
+
|
||||
+
|
||||
+def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
+ """Set up the WarnWetter sensor platform."""
|
||||
+ name = config[CONF_NAME]
|
||||
+ probe = WarnWetterMeasurements(config[CONF_STATION_ID])
|
||||
+
|
||||
+ add_entities(
|
||||
+ [
|
||||
+ WarnWetterSensor(probe, variable, name)
|
||||
+ for variable in config[CONF_MONITORED_CONDITIONS]
|
||||
+ ],
|
||||
+ True,
|
||||
+ )
|
||||
+
|
||||
+
|
||||
+class WarnWetterSensor(Entity):
|
||||
+ """Implementation of a WarnWetter sensor."""
|
||||
+
|
||||
+ def __init__(self, probe, variable, name):
|
||||
+ """Initialize the sensor."""
|
||||
+ self.probe = probe
|
||||
+ self.client_name = name
|
||||
+ self.variable = variable
|
||||
+
|
||||
+ @property
|
||||
+ def unique_id(self) -> Optional[str]:
|
||||
+ """Return a unique ID."""
|
||||
+ return f"{self.probe.station_id}:{self.variable}"
|
||||
+
|
||||
+ @property
|
||||
+ def name(self) -> Optional[str]:
|
||||
+ """Return the name of the entity."""
|
||||
+ return f"{self.client_name} {SENSOR_TYPES[self.variable][0]}"
|
||||
+
|
||||
+ @property
|
||||
+ def state(self) -> Union[None, str, int, float]:
|
||||
+ """Return the state of the entity."""
|
||||
+ return self.probe.data.get(self.variable)
|
||||
+
|
||||
+ @property
|
||||
+ def device_state_attributes(self) -> Optional[Dict[str, Any]]:
|
||||
+ """Return device specific state attributes."""
|
||||
+ return {
|
||||
+ ATTR_ATTRIBUTION: ATTRIBUTION,
|
||||
+ ATTR_STATION: self.probe.station_id,
|
||||
+ ATTR_UPDATED: self.probe.last_update.isoformat(),
|
||||
+ }
|
||||
+
|
||||
+ @property
|
||||
+ def device_class(self) -> Optional[str]:
|
||||
+ """Return the class of this device, from component DEVICE_CLASSES."""
|
||||
+ return SENSOR_TYPES[self.variable][1]
|
||||
+
|
||||
+ @property
|
||||
+ def unit_of_measurement(self) -> Optional[str]:
|
||||
+ """Return the unit of measurement of this entity, if any."""
|
||||
+ return SENSOR_TYPES[self.variable][2]
|
||||
+
|
||||
+ def update(self):
|
||||
+ """Delegate update to probe."""
|
||||
+ self.probe.update()
|
||||
+
|
||||
+
|
||||
+class WarnWetterClient:
|
||||
+ """Base class for static json data."""
|
||||
+
|
||||
+ API_URL = "https://s3.eu-central-1.amazonaws.com/app-prod-static.warnwetter.de/v16/%s_%s.json"
|
||||
+ API_HEADERS = {USER_AGENT: f"home-assistant.warnwetter/ {__version__}"}
|
||||
+
|
||||
+ def __init__(self, resource, station_id, interval_h):
|
||||
+ """Initialize WarnWetterClient."""
|
||||
+ self._station_id = station_id
|
||||
+ self._api_url = self.API_URL % (resource, station_id)
|
||||
+ self._interval_h = interval_h
|
||||
+ self.data = {}
|
||||
+
|
||||
+ @property
|
||||
+ def station_id(self):
|
||||
+ """Return station ID."""
|
||||
+ return self._station_id
|
||||
+
|
||||
+ @property
|
||||
+ def last_update(self):
|
||||
+ """Return the timestamp of the most recent data."""
|
||||
+ time = self.data.get("time")
|
||||
+ if time is not None:
|
||||
+ return datetime.fromtimestamp(int(time)).replace(
|
||||
+ tzinfo=pytz.timezone("Europe/Berlin")
|
||||
+ )
|
||||
+
|
||||
+ def _current_observations(self):
|
||||
+ """Fetch the latest JSON data."""
|
||||
+ try:
|
||||
+ response = requests.get(self._api_url, headers=self.API_HEADERS, timeout=15)
|
||||
+ response.raise_for_status()
|
||||
+ return json.loads(response.content)
|
||||
+ except requests.exceptions.HTTPError:
|
||||
+ _LOGGER.error("While fetching data")
|
||||
+
|
||||
+ def _fetch_json(self):
|
||||
+ """Get the latest data from WarnWetter."""
|
||||
+ if self.last_update and (
|
||||
+ self.last_update + timedelta(hours=self._interval_h)
|
||||
+ > datetime.utcnow().replace(tzinfo=pytz.utc)
|
||||
+ ):
|
||||
+ return None
|
||||
+
|
||||
+ return self._current_observations()
|
||||
+
|
||||
+ @classmethod
|
||||
+ def _icons_to_condition(cls, icons):
|
||||
+ """Convert icon numbers to conditions (first match)."""
|
||||
+ for icon in icons:
|
||||
+ for key, val in CONDITION_CLASSES.items():
|
||||
+ if icon in val:
|
||||
+ return key
|
||||
+
|
||||
+
|
||||
+class WarnWetterForecast(WarnWetterClient):
|
||||
+ """A class consuming forecast data."""
|
||||
+
|
||||
+ def __init__(self, station_id):
|
||||
+ """Initialize WarnWetterForecast."""
|
||||
+ super().__init__("forecast_mosmix", station_id, 4)
|
||||
+
|
||||
+ @Throttle(MIN_TIME_BETWEEN_FORECAST_UPDATES)
|
||||
+ def update(self):
|
||||
+ """Update state."""
|
||||
+ src = self._fetch_json()
|
||||
+ if not src:
|
||||
+ return
|
||||
+
|
||||
+ data = {
|
||||
+ "forecast": [],
|
||||
+ }
|
||||
+ for key, value in src.items():
|
||||
+ if key == "days" and isinstance(value, list):
|
||||
+ for day in value:
|
||||
+ data["forecast"].append(
|
||||
+ {
|
||||
+ ATTR_FORECAST_TIME: day.get("dayDate"),
|
||||
+ ATTR_FORECAST_TEMP_LOW: day.get("temperatureMin") / 10.0,
|
||||
+ ATTR_FORECAST_TEMP: day.get("temperatureMax") / 10.0,
|
||||
+ ATTR_FORECAST_CONDITION: self._condition(day),
|
||||
+ ATTR_FORECAST_PRECIPITATION: day.get("precipitation")
|
||||
+ / 10.0,
|
||||
+ ATTR_FORECAST_WIND_SPEED: day.get("windSpeed") / 10.0,
|
||||
+ ATTR_FORECAST_WIND_BEARING: day.get("windDirection") / 10.0,
|
||||
+ # ATTR_FORECAST_WIND_GUST: day.get('windGust') / 10.0,
|
||||
+ # ATTR_FORECAST_SUNSHINE: day.get('sunshine') / 10.0,
|
||||
+ }
|
||||
+ )
|
||||
+
|
||||
+ elif key == "forecast" and isinstance(value, dict):
|
||||
+ data["time"] = value.get("start", 0) // 1000
|
||||
+
|
||||
+ self.data = data
|
||||
+
|
||||
+ @classmethod
|
||||
+ def _condition(cls, day):
|
||||
+ keys = ("icon", "icon1", "icon2")
|
||||
+ icons = filter(None, (day.get(icon) for icon in keys))
|
||||
+ return cls._icons_to_condition(icons)
|
||||
+
|
||||
+
|
||||
+class WarnWetterMeasurements(WarnWetterClient):
|
||||
+ """A class consuming measured data."""
|
||||
+
|
||||
+ def __init__(self, station_id):
|
||||
+ """Initialize WarnWetterMeasurements."""
|
||||
+ super().__init__("current_measurement", station_id, 1)
|
||||
+
|
||||
+ @Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||
+ def update(self):
|
||||
+ """Update state."""
|
||||
+ src = self._fetch_json()
|
||||
+ if not src:
|
||||
+ return
|
||||
+
|
||||
+ data = {}
|
||||
+ for key, value in src.items():
|
||||
+ spec = SENSOR_TYPES.get(key)
|
||||
+ if spec:
|
||||
+ if isinstance(value, int) and value != 32767:
|
||||
+ if key == "icon":
|
||||
+ data[key] = self._icons_to_condition([value])
|
||||
+ else:
|
||||
+ data[key] = value / spec[3]
|
||||
+
|
||||
+ self.data = data
|
||||
diff --git a/homeassistant/components/warnwetter/weather.py b/homeassistant/components/warnwetter/weather.py
|
||||
new file mode 100644
|
||||
index 0000000000..f00155c2bf
|
||||
--- /dev/null
|
||||
+++ b/homeassistant/components/warnwetter/weather.py
|
||||
@@ -0,0 +1,115 @@
|
||||
+"""Weather platform for data from WarnWetter."""
|
||||
+import logging
|
||||
+from typing import Optional
|
||||
+
|
||||
+import voluptuous as vol
|
||||
+
|
||||
+from homeassistant.components.weather import (
|
||||
+ ATTR_FORECAST_CONDITION,
|
||||
+ PLATFORM_SCHEMA,
|
||||
+ WeatherEntity,
|
||||
+)
|
||||
+from homeassistant.const import ATTR_ICON, ATTR_TEMPERATURE, CONF_NAME, TEMP_CELSIUS
|
||||
+from homeassistant.helpers import config_validation as cv
|
||||
+
|
||||
+# Reuse data and API logic from the sensor implementation
|
||||
+from .sensor import (
|
||||
+ ATTR_HUMIDITY,
|
||||
+ ATTR_MEANWIND,
|
||||
+ ATTR_PRESSURE,
|
||||
+ ATTR_WINDDIRECTION,
|
||||
+ ATTRIBUTION,
|
||||
+ CONF_STATION_ID,
|
||||
+ WarnWetterForecast,
|
||||
+ WarnWetterMeasurements,
|
||||
+)
|
||||
+
|
||||
+_LOGGER = logging.getLogger(__name__)
|
||||
+
|
||||
+PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
+ {vol.Required(CONF_NAME): cv.string, vol.Required(CONF_STATION_ID): cv.string}
|
||||
+)
|
||||
+
|
||||
+
|
||||
+def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
+ """Set up the WarnWetter weather platform."""
|
||||
+ mprobe = WarnWetterMeasurements(config[CONF_STATION_ID])
|
||||
+ fprobe = WarnWetterForecast(config[CONF_STATION_ID])
|
||||
+ entity = WarnWetterWeather(mprobe, fprobe, config[CONF_NAME])
|
||||
+ add_entities([entity], True)
|
||||
+
|
||||
+
|
||||
+class WarnWetterWeather(WeatherEntity):
|
||||
+ """Representation of a weather condition."""
|
||||
+
|
||||
+ def __init__(self, mprobe, fprobe, stationname):
|
||||
+ """Initialize WarnWetterWeather."""
|
||||
+ self.mprobe = mprobe
|
||||
+ self.fprobe = fprobe
|
||||
+ self.stationname = stationname
|
||||
+
|
||||
+ @property
|
||||
+ def unique_id(self) -> Optional[str]:
|
||||
+ """Return a unique ID."""
|
||||
+ return self.mprobe.station_id
|
||||
+
|
||||
+ @property
|
||||
+ def name(self) -> Optional[str]:
|
||||
+ """Return the name of the entity."""
|
||||
+ return self.stationname
|
||||
+
|
||||
+ @property
|
||||
+ def temperature(self):
|
||||
+ """Return the platform temperature."""
|
||||
+ return self.mprobe.data.get(ATTR_TEMPERATURE)
|
||||
+
|
||||
+ @property
|
||||
+ def temperature_unit(self):
|
||||
+ """Return the unit of measurement."""
|
||||
+ return TEMP_CELSIUS
|
||||
+
|
||||
+ @property
|
||||
+ def pressure(self):
|
||||
+ """Return the pressure."""
|
||||
+ return self.mprobe.data.get(ATTR_PRESSURE)
|
||||
+
|
||||
+ @property
|
||||
+ def humidity(self):
|
||||
+ """Return the humidity."""
|
||||
+ return self.mprobe.data.get(ATTR_HUMIDITY)
|
||||
+
|
||||
+ @property
|
||||
+ def wind_speed(self):
|
||||
+ """Return the wind speed."""
|
||||
+ return self.mprobe.data.get(ATTR_MEANWIND)
|
||||
+
|
||||
+ @property
|
||||
+ def wind_bearing(self):
|
||||
+ """Return the wind bearing."""
|
||||
+ return self.mprobe.data.get(ATTR_WINDDIRECTION)
|
||||
+
|
||||
+ @property
|
||||
+ def attribution(self):
|
||||
+ """Return the attribution."""
|
||||
+ return ATTRIBUTION
|
||||
+
|
||||
+ @property
|
||||
+ def forecast(self):
|
||||
+ """Return the forecast."""
|
||||
+ return self.fprobe.data.get("forecast")
|
||||
+
|
||||
+ @property
|
||||
+ def condition(self):
|
||||
+ """Return the current condition."""
|
||||
+ icon = self.mprobe.data.get(ATTR_ICON)
|
||||
+ if icon:
|
||||
+ return icon
|
||||
+
|
||||
+ forecast = self.forecast
|
||||
+ if forecast:
|
||||
+ return forecast[0].get(ATTR_FORECAST_CONDITION)
|
||||
+
|
||||
+ def update(self):
|
||||
+ """Update state."""
|
||||
+ self.mprobe.update()
|
||||
+ self.fprobe.update()
|
||||
--
|
||||
2.30.1
|
||||
|
|
@ -1,92 +1,783 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
imports = [ ./hexa-cards.nix ];
|
||||
|
||||
services.home-assistant = {
|
||||
enable = true;
|
||||
package = pkgs.home-assistant.overrideAttrs (
|
||||
oldAttrs: {
|
||||
doInstallCheck = false;
|
||||
patches = (oldAttrs.patches or [ ]) ++ [ ./warnwetter.patch ];
|
||||
}
|
||||
);
|
||||
config = {
|
||||
default_config = { };
|
||||
sensor = [
|
||||
{
|
||||
platform = "rmvtransport";
|
||||
next_departure = [
|
||||
{
|
||||
station = "3024634";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
weather = [
|
||||
{
|
||||
platform = "warnwetter";
|
||||
name = "DWD Darmstadt";
|
||||
station_id = "L886";
|
||||
}
|
||||
];
|
||||
http = {
|
||||
use_x_forwarded_for = true;
|
||||
trusted_proxies = [ "::1" ];
|
||||
{ pkgs, lib, ... }:
|
||||
let
|
||||
haLib = import ./lib.nix lib;
|
||||
inherit (haLib) modules util cards conditions triggers jinja actions tap_actions;
|
||||
modes =
|
||||
let
|
||||
empty = {
|
||||
icon = util.mkIcon "account-off";
|
||||
title = "Leer";
|
||||
};
|
||||
prometheus = {
|
||||
namespace = "hass";
|
||||
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 = "Wohnungsmodus";
|
||||
name = "flat";
|
||||
options = { inherit active vacation; };
|
||||
};
|
||||
wohnzimmer = {
|
||||
title = "Wohnzimmermodus";
|
||||
name = "wohnzimmer";
|
||||
options = { inherit empty heat active force_active; };
|
||||
};
|
||||
kueche = {
|
||||
title = "Küchenmodus";
|
||||
name = "kueche";
|
||||
options = { inherit empty active; };
|
||||
};
|
||||
schlafzimmer = {
|
||||
title = "Schlafzimmermodus";
|
||||
name = "schlafzimmer";
|
||||
options = { inherit empty heat active force_active; };
|
||||
};
|
||||
};
|
||||
lovelaceConfig = {
|
||||
views = [
|
||||
fenster = map (name: "binary_sensor.${name}")
|
||||
[
|
||||
"kuechenfenster"
|
||||
"wohnzimmerfenster"
|
||||
"schlafzimmerfenster"
|
||||
"wohnungstuer"
|
||||
];
|
||||
batteries = map (name: "sensor.${name}") [
|
||||
"wohnzimmerfenster_battery"
|
||||
"thermostat_kueche_battery"
|
||||
"thermostat_schlafzimmer_battery"
|
||||
"thermostat_wohnzimmer_battery"
|
||||
"klimasensor_bad_battery"
|
||||
"klimasensor_kueche_battery"
|
||||
"klimasensor_schlafzimmer_battery"
|
||||
"kuechenfenster_battery"
|
||||
"pegasus_battery_level"
|
||||
"schlafzimmerfenster_battery"
|
||||
"wohnungstuer_battery"
|
||||
];
|
||||
inherit (import ../../../nix/sources.nix) nixos-unstable;
|
||||
homeAssistantDir = "/disk/persist/home-assistant";
|
||||
in
|
||||
{
|
||||
|
||||
disabledModules = [
|
||||
"services/misc/home-assistant.nix"
|
||||
];
|
||||
|
||||
imports = [
|
||||
(modules.mkModeSwitcher modes.wohnzimmer { })
|
||||
(modules.mkModeSwitcher modes.kueche { })
|
||||
(modules.mkModeSwitcher modes.schlafzimmer { })
|
||||
(modules.mkModeSwitcher modes.flat { })
|
||||
"${nixos-unstable}/nixos/modules/services/misc/home-assistant.nix"
|
||||
./hexa-cards.nix
|
||||
];
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${homeAssistantDir} - - - - -"
|
||||
];
|
||||
|
||||
services = {
|
||||
home-assistant = {
|
||||
enable = true;
|
||||
package = pkgs.home-assistant.overrideAttrs (
|
||||
oldAttrs: {
|
||||
doInstallCheck = false;
|
||||
patches = (oldAttrs.patches or [ ]) ++ [ ./warnwetter.patch ];
|
||||
}
|
||||
);
|
||||
configDir = homeAssistantDir;
|
||||
config = {
|
||||
shopping_list = { };
|
||||
matrix = {
|
||||
homeserver = "https://matrix.maralorn.de";
|
||||
username = "@marabot:maralorn.de";
|
||||
password = pkgs.privateValue "" "matrix/marabot-pw";
|
||||
};
|
||||
notify = [{ platform = "matrix"; default_room = "#fluffy:maralorn.de"; }];
|
||||
group = {
|
||||
wohnzimmer_lights = {
|
||||
name = "Lichter Wohnzimmer";
|
||||
entities = [ "switch.blaue_lichterkette" "switch.lichterkette_schrank" "switch.lichterkette_fernseher" ];
|
||||
};
|
||||
schlafzimmer_lights = {
|
||||
name = "Lichter Schlafzimmer";
|
||||
entities = [ "switch.lichterkette_schlafzimmer" "switch.weihnachtsstern_schlafzimmer" ];
|
||||
};
|
||||
};
|
||||
homeassistant = pkgs.privateValue { } "homeassistant-home";
|
||||
frontend.themes.ourdefault = {
|
||||
primary-color = "#858EFF";
|
||||
};
|
||||
automation = [
|
||||
{
|
||||
alias = "Set theme at startup'";
|
||||
trigger = { platform = "homeassistant"; event = "start"; };
|
||||
action = { service = "frontend.set_theme"; data.name = "ourdefault"; };
|
||||
}
|
||||
{
|
||||
alias = "Entfeuchtersteuerung Schlafzimmer";
|
||||
trigger = [
|
||||
{ platform = "state"; entity_id = "sensor.schlafzimmer_humidity"; }
|
||||
{ platform = "state"; entity_id = "binary_sensor.schlafzimmerfenster"; }
|
||||
];
|
||||
action = [{
|
||||
choose = [
|
||||
{
|
||||
conditions = [{
|
||||
condition = "or";
|
||||
conditions = [
|
||||
{ condition = "numeric_state"; entity_id = "sensor.schlafzimmer_humidity"; below = 65; }
|
||||
{ condition = "state"; entity_id = "binary_sensor.schlafzimmerfenster"; state = "on"; }
|
||||
];
|
||||
}];
|
||||
sequence = { service = "switch.turn_off"; target.entity_id = "switch.luftentfeuchter"; };
|
||||
}
|
||||
{
|
||||
conditions = [{ condition = "numeric_state"; entity_id = "sensor.schlafzimmer_humidity"; above = 66; }];
|
||||
sequence = { service = "switch.turn_on"; target.entity_id = "switch.luftentfeuchter"; };
|
||||
}
|
||||
];
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Lüftungssteuerung Bad";
|
||||
trigger = [{ platform = "state"; entity_id = "sensor.bad_humidity"; }];
|
||||
action = [{
|
||||
choose = [{
|
||||
conditions = [{ condition = "numeric_state"; entity_id = "sensor.bad_humidity"; above = 66; }];
|
||||
sequence = { service = "switch.turn_on"; target.entity_id = "switch.lueftung_bad"; };
|
||||
}
|
||||
{
|
||||
conditions = [{ condition = "numeric_state"; entity_id = "sensor.bad_humidity"; below = 64; }];
|
||||
sequence = { service = "switch.turn_off"; target.entity_id = "switch.lueftung_bad"; };
|
||||
}];
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Thermostatsteuerung 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";
|
||||
target.area_id = "schlafzimmer";
|
||||
data = { temperature = 30; hvac_mode = "heat"; };
|
||||
};
|
||||
}];
|
||||
default = {
|
||||
service = "climate.turn_off";
|
||||
target.area_id = "schlafzimmer";
|
||||
};
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Thermostatsteuerung Küche";
|
||||
trigger = with triggers; [
|
||||
(stateTrigger "input_number.target_temperature_kueche")
|
||||
(stateTrigger "sensor.kueche_temperature")
|
||||
(stateTrigger "binary_sensor.kuechenfenster")
|
||||
(stateTrigger "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";
|
||||
target.area_id = "kuche";
|
||||
data = { temperature = 30; hvac_mode = "heat"; };
|
||||
};
|
||||
}];
|
||||
default = {
|
||||
service = "climate.turn_off";
|
||||
target.area_id = "kuche";
|
||||
};
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Thermostatsteuerung Wohnzimmer";
|
||||
trigger = with triggers; [
|
||||
(stateTrigger "input_number.target_temperature_wohnzimmer")
|
||||
(stateTrigger "binary_sensor.wohnzimmerfenster")
|
||||
(stateTrigger "climate.wohnzimmer")
|
||||
(modeSwitchTrigger modes.flat)
|
||||
];
|
||||
action = [{
|
||||
choose = [{
|
||||
conditions = [{ condition = "state"; entity_id = "binary_sensor.wohnzimmerfenster"; state = "off"; }
|
||||
(conditions.modeIs modes.flat "active")];
|
||||
sequence = {
|
||||
service = "climate.set_temperature";
|
||||
target.area_id = "wohnzimmer";
|
||||
data = { temperature = "{{ states('input_number.target_temperature_wohnzimmer') | int }}"; hvac_mode = "heat"; };
|
||||
};
|
||||
}];
|
||||
default = {
|
||||
service = "climate.turn_off";
|
||||
target.area_id = "wohnzimmer";
|
||||
};
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Küchentemperatur";
|
||||
trigger = [ (triggers.modeSwitchTrigger modes.kueche) ];
|
||||
action = [{
|
||||
service = "input_number.set_value";
|
||||
target.entity_id = "input_number.target_temperature_kueche";
|
||||
data.value = jinja.if' (jinja.isState (util.modeSelectEntity modes.kueche) "empty") "18" "20.5";
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Wohnzimmertemperatur";
|
||||
trigger = [ (triggers.modeSwitchTrigger modes.wohnzimmer) ];
|
||||
action = [{
|
||||
service = "input_number.set_value";
|
||||
target.entity_id = "input_number.target_temperature_wohnzimmer";
|
||||
data.value = jinja.if' (jinja.isState (util.modeSelectEntity modes.wohnzimmer) "empty") "18" "24";
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Schlafzimmertemperatur";
|
||||
trigger = [ (triggers.modeSwitchTrigger modes.schlafzimmer) ];
|
||||
action = [{
|
||||
service = "input_number.set_value";
|
||||
target.entity_id = "input_number.target_temperature_schlafzimmer";
|
||||
data.value = jinja.if' (jinja.isState (util.modeSelectEntity modes.schlafzimmer) "empty") "18" "20.5";
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Wohnzimmerlichter";
|
||||
trigger = with triggers; [
|
||||
(modeSwitchTrigger modes.wohnzimmer)
|
||||
(stateTrigger "sun.sun")
|
||||
];
|
||||
action = [{
|
||||
service = jinja.if'
|
||||
(jinja.or
|
||||
(jinja.isState (util.modeSelectEntity modes.wohnzimmer) "force_active")
|
||||
(jinja.and
|
||||
(jinja.isState (util.modeSelectEntity modes.wohnzimmer) "active")
|
||||
"state_attr('sun.sun', 'elevation') < 6"))
|
||||
"homeassistant.turn_on"
|
||||
"homeassistant.turn_off";
|
||||
target.entity_id = "group.wohnzimmer_lights";
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Schlafzimmerlichter";
|
||||
trigger = with triggers; [
|
||||
(modeSwitchTrigger modes.schlafzimmer)
|
||||
(stateTrigger "sun.sun")
|
||||
];
|
||||
action = [{
|
||||
service = jinja.if'
|
||||
(jinja.or
|
||||
(jinja.isState (util.modeSelectEntity modes.schlafzimmer) "force_active")
|
||||
(jinja.and
|
||||
(jinja.isState (util.modeSelectEntity modes.schlafzimmer) "active")
|
||||
"state_attr('sun.sun', 'elevation') < 6"))
|
||||
"homeassistant.turn_on"
|
||||
"homeassistant.turn_off";
|
||||
target.entity_id = "group.schlafzimmer_lights";
|
||||
}];
|
||||
}
|
||||
{
|
||||
alias = "Schlafzimmer vorheizen";
|
||||
trigger = [{ platform = "time"; at = "19:00:00"; } { platform = "time"; at = "04:00:00"; }];
|
||||
condition = [
|
||||
(conditions.modeIs modes.schlafzimmer "empty")
|
||||
(conditions.modeIs modes.flat "active")
|
||||
];
|
||||
action = [ (actions.setMode modes.schlafzimmer "heat") ];
|
||||
}
|
||||
{
|
||||
alias = "Schlafzimmer nachts kühl";
|
||||
trigger = [{ platform = "time"; at = "01:00:00"; }];
|
||||
condition = [
|
||||
(conditions.modeIs modes.schlafzimmer "heat")
|
||||
(conditions.modeIs modes.flat "active")
|
||||
];
|
||||
action = [ (actions.setMode modes.schlafzimmer "empty") ];
|
||||
}
|
||||
{
|
||||
alias = "Morgens Licht an";
|
||||
trigger = [{ platform = "time"; at = "07:00:00"; }];
|
||||
condition = [
|
||||
(conditions.modeIs modes.schlafzimmer "heat")
|
||||
(conditions.modeIs modes.flat "active")
|
||||
];
|
||||
action = [ (actions.setMode modes.schlafzimmer "force_active") ];
|
||||
}
|
||||
{
|
||||
alias = "Warnung bei niedrigem Akkustand";
|
||||
trigger = map
|
||||
(limit: {
|
||||
platform = "numeric_state";
|
||||
below = toString limit;
|
||||
entity_id = batteries;
|
||||
}) [ 25 20 15 10 5 4 3 2 1 ];
|
||||
action = [ (actions.notify "{{ trigger.to_state.name }} ist {{ trigger.to_state.value }}%.") ];
|
||||
}
|
||||
# Warnungen für hohe Luftfeuchtigkeit
|
||||
] ++ (map
|
||||
(minutes:
|
||||
{
|
||||
alias = "Warnung bei ${minutes} Minuten offenem Fenster oder offener Tür";
|
||||
trigger = map (name: triggers.stateTrigger name // { to = "on"; for = "00:${minutes}:00"; }) fenster;
|
||||
action = [ (actions.notify "{{ trigger.to_state.name }} ist seit mehr als ${minutes} Minuten offen.") ];
|
||||
})
|
||||
(map toString [ 10 20 30 40 50 60 ]));
|
||||
history = { };
|
||||
image = { };
|
||||
sun = { };
|
||||
logbook = { };
|
||||
config = { };
|
||||
mobile_app = { };
|
||||
recorder = { };
|
||||
ssdp = { };
|
||||
template = [
|
||||
{ sensor = [{ state = "{% if is_state('switch.luftentfeuchter', 'on') %}1{% else %}0{% endif %}"; name = "Luftentfeuchter"; }]; }
|
||||
{ sensor = [{ state = "{% if is_state('switch.lueftung_bad', 'on') %}1{% else %}0{% endif %}"; name = "Lüftung"; }]; }
|
||||
{ sensor = [{ state = "{% if is_state('binary_sensor.schlafzimmerfenster', 'on') %}1{% else %}0{% endif %}"; name = "Schlafzimmerfenster"; }]; }
|
||||
{ sensor = [{ state = "{% if is_state('binary_sensor.wohnzimmerfenster', 'on') %}1{% else %}0{% endif %}"; name = "Balkontür"; }]; }
|
||||
{ sensor = [{ state = "{% if is_state('binary_sensor.kuechenfenster', 'on') %}1{% else %}0{% endif %}"; name = "Küchenfenster"; }]; }
|
||||
{ sensor = [{ state = "{% if is_state('binary_sensor.wohnungstuer', 'on') %}1{% else %}0{% endif %}"; name = "Wohnungstür"; }]; }
|
||||
{ sensor = [{ state = "{% if is_state('climate.schlafzimmer', 'heat') %}1{% else %}0{% endif %}"; name = "Schlafzimmerheizung"; }]; }
|
||||
{ sensor = [{ state = "{% if is_state('climate.wohnzimmer', 'heat') %}1{% else %}0{% endif %}"; name = "Wohnzimmerheizung"; }]; }
|
||||
{ sensor = [{ state = "{% if is_state('climate.kueche', 'heat') %}1{% else %}0{% endif %}"; name = "Küchenheizung"; }]; }
|
||||
{ sensor = [{ state = "{{ state_attr('climate.wohnzimmer', 'current_temperature') }}"; name = "Temperatur Wohnzimmer"; }]; }
|
||||
];
|
||||
input_number = {
|
||||
target_temperature_schlafzimmer = {
|
||||
name = "Zieltemperatur Schlafzimmer";
|
||||
unit_of_measurement = "°C";
|
||||
min = "17";
|
||||
max = "25";
|
||||
step = "0.25";
|
||||
};
|
||||
target_temperature_wohnzimmer = {
|
||||
name = "Zieltemperatur Wohnzimmer";
|
||||
unit_of_measurement = "°C";
|
||||
min = "17";
|
||||
max = "25";
|
||||
step = "0.25";
|
||||
};
|
||||
target_temperature_kueche = {
|
||||
name = "Zieltemperatur Küche";
|
||||
unit_of_measurement = "°C";
|
||||
min = "17";
|
||||
max = "25";
|
||||
step = "0.25";
|
||||
};
|
||||
};
|
||||
system_health = { };
|
||||
zha = {
|
||||
device_config = {
|
||||
"00:12:4b:00:24:c0:ff:52-1".type = "switch"; # Lüftung Bad
|
||||
"00:12:4b:00:24:c1:00:45-1".type = "switch"; # Blaue Lichterkette
|
||||
"00:12:4b:00:24:c1:00:1b-1".type = "switch"; # Luftentfeuchter Schlafzimmer
|
||||
"00:12:4b:00:24:c1:00:05-1".type = "switch"; # Lichterkette Fernseher
|
||||
"00:12:4b:00:24:c0:ff:16-1".type = "switch"; # Lichterkette Schrank
|
||||
"00:12:4b:00:24:c0:ff:a8-1".type = "switch"; # Lichterkette Schlafzimmer
|
||||
"00:12:4b:00:24:c0:ff:ad-1".type = "switch"; # Weihnachtsstern Schlafzimmer
|
||||
};
|
||||
};
|
||||
ipp = { };
|
||||
brother = { };
|
||||
sensor = [
|
||||
{
|
||||
platform = "rmvtransport";
|
||||
next_departure = [
|
||||
{
|
||||
station = "3024634";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
weather = [
|
||||
{
|
||||
platform = "warnwetter";
|
||||
name = "DWD Darmstadt";
|
||||
station_id = "L886";
|
||||
}
|
||||
];
|
||||
http = {
|
||||
use_x_forwarded_for = true;
|
||||
trusted_proxies = [ "::1" ];
|
||||
};
|
||||
prometheus = {
|
||||
namespace = "hass";
|
||||
};
|
||||
};
|
||||
lovelaceConfig =
|
||||
let
|
||||
alertbadges = [
|
||||
{
|
||||
type = "entity-filter";
|
||||
entities = fenster;
|
||||
state_filter = [ "on" ];
|
||||
}
|
||||
{
|
||||
type = "entity-filter";
|
||||
entities = batteries;
|
||||
state_filter = [{ value = 25; operator = "<"; }];
|
||||
}
|
||||
];
|
||||
badges =
|
||||
let
|
||||
badge = mode:
|
||||
{
|
||||
type = "state-label";
|
||||
entity = util.modeSelectEntity mode;
|
||||
name = mode.title;
|
||||
tap_action = tap_actions.cycleMode mode;
|
||||
};
|
||||
in
|
||||
[
|
||||
(badge modes.wohnzimmer)
|
||||
(badge modes.kueche)
|
||||
(badge modes.schlafzimmer)
|
||||
] ++ alertbadges;
|
||||
envstack =
|
||||
{
|
||||
type = "vertical-stack";
|
||||
cards = [
|
||||
{
|
||||
type = "custom:sun-card";
|
||||
}
|
||||
{
|
||||
type = "weather-forecast";
|
||||
entity = "weather.dwd_darmstadt";
|
||||
}
|
||||
{
|
||||
type = "picture";
|
||||
image = "https://www.dwd.de/DWD/wetter/radar/radfilm_hes_akt.gif";
|
||||
}
|
||||
{
|
||||
type = "custom:rmv-card";
|
||||
entity = "sensor.darmstadt_schulstrasse";
|
||||
}
|
||||
];
|
||||
};
|
||||
wohnzimmerstack =
|
||||
{
|
||||
type = "vertical-stack";
|
||||
cards = [
|
||||
(cards.modeSwitcher modes.wohnzimmer)
|
||||
{
|
||||
type = "custom:mini-graph-card";
|
||||
entities = [
|
||||
{ entity = "sensor.temperatur_wohnzimmer"; name = "Temperatur"; show_fill = false; }
|
||||
{ entity = "input_number.target_temperature_wohnzimmer"; name = "Zieltemperatur"; show_fill = false; }
|
||||
{ entity = "sensor.wohnzimmerheizung"; name = "Heizung"; y_axis = "secondary"; show_fill = true; show_points = false; show_line = false; smoothing = false; }
|
||||
];
|
||||
show = {
|
||||
labels = true;
|
||||
labels_secondary = "hover";
|
||||
};
|
||||
lower_bound_secondary = 0;
|
||||
upper_bound_secondary = 1;
|
||||
hours_to_show = 24;
|
||||
update_interval = 30;
|
||||
line_width = 2;
|
||||
hour24 = true;
|
||||
decimals = 1;
|
||||
points_per_hour = 3;
|
||||
state_map = [
|
||||
{ value = 0; label = "Aus"; }
|
||||
{ value = 1; label = "An"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "logbook";
|
||||
entities = [ (util.modeSelectEntity modes.wohnzimmer) "binary_sensor.wohnzimmerfenster" "switch.lichterkette_fernseher" "switch.lichterkette_schrank" "switch.blaue_lichterkette" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
kuechenstack = {
|
||||
type = "vertical-stack";
|
||||
cards = [
|
||||
(cards.modeSwitcher modes.kueche)
|
||||
{
|
||||
type = "custom:mini-graph-card";
|
||||
entities = [
|
||||
{ entity = "sensor.kueche_humidity"; name = "Luftfeuchtigkeit"; show_fill = false; state_adaptive_color = true; }
|
||||
{ entity = "sensor.kuchenfenster"; name = "Fenster"; color = "#ff0000"; y_axis = "secondary"; show_fill = true; show_points = false; show_line = false; smoothing = false; }
|
||||
];
|
||||
color_thresholds = [{ value = 0; color = "#009933"; } { value = 64; color = "#ffbf00"; } { value = 66; color = "#ff0000"; }];
|
||||
color_thresholds_transition = "hard";
|
||||
show = {
|
||||
labels = true;
|
||||
labels_secondary = "hover";
|
||||
};
|
||||
lower_bound_secondary = 0;
|
||||
upper_bound_secondary = 1;
|
||||
hour24 = true;
|
||||
decimals = 1;
|
||||
points_per_hour = 3;
|
||||
hours_to_show = 24;
|
||||
update_interval = 30;
|
||||
line_width = 2;
|
||||
state_map = [
|
||||
{ value = 0; label = "Zu"; }
|
||||
{ value = 1; label = "Auf"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "custom:mini-graph-card";
|
||||
entities = [
|
||||
{ entity = "sensor.kueche_temperature"; name = "Temperatur"; show_fill = false; }
|
||||
{ entity = "input_number.target_temperature_kueche"; name = "Zieltemperatur"; show_fill = false; }
|
||||
{ entity = "sensor.kuchenheizung"; name = "Heizung"; y_axis = "secondary"; show_fill = true; show_points = false; show_line = false; smoothing = false; }
|
||||
];
|
||||
show = {
|
||||
labels = true;
|
||||
labels_secondary = "hover";
|
||||
};
|
||||
lower_bound_secondary = 0;
|
||||
upper_bound_secondary = 1;
|
||||
hours_to_show = 24;
|
||||
update_interval = 30;
|
||||
line_width = 2;
|
||||
hour24 = true;
|
||||
decimals = 1;
|
||||
points_per_hour = 3;
|
||||
state_map = [
|
||||
{ value = 0; label = "Aus"; }
|
||||
{ value = 1; label = "An"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "logbook";
|
||||
entities = [ (util.modeSelectEntity modes.kueche) "climate.kueche" "binary_sensor.kuechenfenster" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
schlafzimmerstack =
|
||||
{
|
||||
type = "vertical-stack";
|
||||
cards = [
|
||||
(cards.modeSwitcher modes.schlafzimmer)
|
||||
{
|
||||
type = "custom:mini-graph-card";
|
||||
entities = [
|
||||
{ entity = "sensor.schlafzimmer_humidity"; name = "Luftfeuchtigkeit"; show_fill = false; state_adaptive_color = true; }
|
||||
{ entity = "sensor.luftentfeuchter"; name = "Entfeuchter"; color = "#0000ff"; y_axis = "secondary"; show_fill = true; show_points = false; show_line = false; smoothing = false; }
|
||||
{ entity = "sensor.schlafzimmerfenster"; name = "Fenster"; color = "#ff0000"; y_axis = "secondary"; show_fill = true; show_points = false; show_line = false; smoothing = false; }
|
||||
];
|
||||
color_thresholds = [{ value = 0; color = "#009933"; } { value = 64; color = "#ffbf00"; } { value = 66; color = "#ff0000"; }];
|
||||
color_thresholds_transition = "hard";
|
||||
show = {
|
||||
labels = true;
|
||||
labels_secondary = "hover";
|
||||
};
|
||||
lower_bound_secondary = 0;
|
||||
upper_bound_secondary = 1;
|
||||
hour24 = true;
|
||||
decimals = 1;
|
||||
points_per_hour = 3;
|
||||
hours_to_show = 24;
|
||||
update_interval = 30;
|
||||
line_width = 2;
|
||||
state_map = [
|
||||
{ value = 0; label = "Aus/Zu"; }
|
||||
{ value = 1; label = "An/Auf"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "custom:mini-graph-card";
|
||||
entities = [
|
||||
{ entity = "sensor.schlafzimmer_temperature"; name = "Temperatur"; show_fill = false; }
|
||||
{ entity = "input_number.target_temperature_schlafzimmer"; name = "Zieltemperatur"; show_fill = false; }
|
||||
{ entity = "sensor.schlafzimmerheizung"; name = "Heizung"; y_axis = "secondary"; show_fill = true; show_points = false; show_line = false; smoothing = false; }
|
||||
];
|
||||
show = {
|
||||
labels = true;
|
||||
labels_secondary = "hover";
|
||||
};
|
||||
lower_bound_secondary = 0;
|
||||
upper_bound_secondary = 1;
|
||||
hours_to_show = 24;
|
||||
update_interval = 30;
|
||||
line_width = 2;
|
||||
hour24 = true;
|
||||
decimals = 1;
|
||||
points_per_hour = 3;
|
||||
state_map = [
|
||||
{ value = 0; label = "Aus"; }
|
||||
{ value = 1; label = "An"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "logbook";
|
||||
entities = [ (util.modeSelectEntity modes.schlafzimmer) "switch.weihnachtsstern_schlafzimmer" "switch.luftentfeuchter" "climate.schlafzimmer" "binary_sensor.schlafzimmerfenster" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
badstack =
|
||||
{
|
||||
type = "vertical-stack";
|
||||
cards = [
|
||||
{
|
||||
type = "glance";
|
||||
title = "Bad";
|
||||
columns = 4;
|
||||
show_state = false;
|
||||
entities = [ ];
|
||||
}
|
||||
{
|
||||
type = "custom:mini-graph-card";
|
||||
entities = [
|
||||
{ entity = "sensor.bad_humidity"; name = "Luftfeuchtigkeit"; show_fill = false; state_adaptive_color = true; }
|
||||
{ entity = "sensor.luftung"; name = "Lüftung"; color = "#0000ff"; y_axis = "secondary"; show_fill = true; show_points = false; show_line = false; smoothing = false; }
|
||||
];
|
||||
color_thresholds = [{ value = 0; color = "#009933"; } { value = 64; color = "#ffbf00"; } { value = 66; color = "#ff0000"; }];
|
||||
color_thresholds_transition = "hard";
|
||||
show = {
|
||||
labels = true;
|
||||
labels_secondary = "hover";
|
||||
};
|
||||
lower_bound_secondary = 0;
|
||||
upper_bound_secondary = 1;
|
||||
hour24 = true;
|
||||
decimals = 1;
|
||||
points_per_hour = 3;
|
||||
hours_to_show = 24;
|
||||
update_interval = 30;
|
||||
line_width = 2;
|
||||
state_map = [
|
||||
{ value = 0; label = "Aus"; }
|
||||
{ value = 1; label = "An"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "custom:mini-graph-card";
|
||||
entities = [
|
||||
{ entity = "sensor.bad_temperature"; name = "Temperatur"; show_fill = false; }
|
||||
];
|
||||
show = {
|
||||
labels = true;
|
||||
labels_secondary = "hover";
|
||||
};
|
||||
lower_bound_secondary = 0;
|
||||
upper_bound_secondary = 1;
|
||||
hours_to_show = 24;
|
||||
update_interval = 30;
|
||||
line_width = 2;
|
||||
hour24 = true;
|
||||
decimals = 1;
|
||||
points_per_hour = 3;
|
||||
state_map = [
|
||||
{ value = 0; label = "Aus"; }
|
||||
{ value = 1; label = "An"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "logbook";
|
||||
entities = [ "switch.lueftung_bad" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
flurstack = {
|
||||
type = "vertical-stack";
|
||||
cards = [
|
||||
(cards.modeSwitcher modes.flat)
|
||||
{
|
||||
type = "custom:mini-graph-card";
|
||||
entities = [
|
||||
{ entity = "sensor.wohnungstur"; name = "Wohnungstür"; color = "#ff0000"; show_fill = true; aggregate_func = "max"; smoothing = false; }
|
||||
];
|
||||
show = {
|
||||
labels = true;
|
||||
};
|
||||
lower_bound = 0;
|
||||
upper_bound = 1;
|
||||
hour24 = true;
|
||||
decimals = 1;
|
||||
points_per_hour = 3;
|
||||
hours_to_show = 24;
|
||||
update_interval = 30;
|
||||
line_width = 2;
|
||||
state_map = [
|
||||
{ value = 0; label = "Zu"; }
|
||||
{ value = 1; label = "Auf"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "logbook";
|
||||
entities = [ "binary_sensor.wohnungstuer" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
in
|
||||
{
|
||||
cards = [
|
||||
views = [
|
||||
{
|
||||
type = "weather-forecast";
|
||||
entity = "weather.dwd_darmstadt";
|
||||
}
|
||||
{
|
||||
type = "custom:sun-card";
|
||||
}
|
||||
{
|
||||
type = "picture";
|
||||
image = "https://www.dwd.de/DWD/wetter/radar/radfilm_hes_akt.gif";
|
||||
}
|
||||
{
|
||||
type = "history-graph";
|
||||
entities = [
|
||||
"sensor.pegasus_battery_level"
|
||||
"sensor.pegasus_battery_state"
|
||||
"sensor.kalliope_battery_level"
|
||||
"sensor.kalliope_battery_state"
|
||||
icon = "mdi:switch";
|
||||
badges = alertbadges;
|
||||
cards = [
|
||||
(cards.modeSwitcher modes.wohnzimmer)
|
||||
(cards.modeSwitcher modes.kueche)
|
||||
(cards.modeSwitcher modes.schlafzimmer)
|
||||
(cards.modeSwitcher modes.flat)
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "custom:rmv-card";
|
||||
entity = "sensor.darmstadt_schulstrasse";
|
||||
}
|
||||
{ icon = "mdi:sofa"; inherit badges; cards = [ wohnzimmerstack ]; }
|
||||
{ icon = "mdi:countertop"; inherit badges; cards = [ kuechenstack ]; }
|
||||
{ icon = "mdi:bed-king"; inherit badges; cards = [ schlafzimmerstack ]; }
|
||||
{ icon = "mdi:shower-head"; inherit badges; cards = [ badstack ]; }
|
||||
{ icon = "mdi:door-closed"; inherit badges; cards = [ flurstack ]; }
|
||||
{ icon = "mdi:city"; inherit badges; cards = [ envstack ]; }
|
||||
{ icon = "mdi:floor-plan"; badges = alertbadges; cards = [ wohnzimmerstack kuechenstack schlafzimmerstack badstack ]; }
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
"home.lo.m-0.eu" = {
|
||||
serverAliases = [ "home.vpn.m-0.eu" ];
|
||||
extraConfig = "proxy_buffering off;";
|
||||
locations."/" = {
|
||||
proxyPass = "http://[::1]:8123";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
locations."/custom/" = {
|
||||
alias = "/run/hass/";
|
||||
};
|
||||
};
|
||||
"fluffy.lo.m-0.eu" = {
|
||||
default = true;
|
||||
locations."/".extraConfig = "return 301 http://home.lo.m-0.eu$request_uri;";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
virtualHosts."home.maralorn.de" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://[::1]:8123";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
locations."/custom/" = {
|
||||
alias = "/run/hass/";
|
||||
};
|
||||
extraConfig = ''
|
||||
proxy_buffering off;
|
||||
'';
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ in
|
|||
"L+ /run/hass/mini-media-player.js - - - - ${nur.hassLovelaceModules.mini-media-player}/mini-media-player-bundle.js"
|
||||
"L+ /run/hass/multiple-entity-row.js - - - - ${nur.hassLovelaceModules.multiple-entity-row}/multiple-entity-row.js"
|
||||
"L+ /run/hass/sun-card.js - - - - ${nur.hassLovelaceModules.sun-card}/sun-card.js"
|
||||
"L+ /run/hass/swipe-navigation.js - - - - ${nur.hassLovelaceModules.swipe-navigation}/swipe-navigation.js"
|
||||
"L+ /run/hass/slider-button-card.js - - - - ${nur.hassLovelaceModules.slider-button-card}/slider-button-card.js"
|
||||
"L+ /run/hass/rmv-card.js - - - - ${nur.hassLovelaceModules.rmv-card}/rmv-card.js"
|
||||
"L+ /run/hass/weather-card-chart.js - - - - ${nur.hassLovelaceModules.weather-card-chart}/weather-card-chart.js"
|
||||
];
|
||||
|
@ -28,7 +28,7 @@ in
|
|||
(mkLovelaceModule "rmv-card")
|
||||
(mkLovelaceModule "weather-card-chart")
|
||||
(mkLovelaceModule "sun-card")
|
||||
(mkLovelaceModule "swipe-navigation")
|
||||
(mkLovelaceModule "slider-button-card")
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -43,7 +43,10 @@ in
|
|||
"bach.vocalensemble-darmstadt.de:25"
|
||||
"hera.m-0.eu:25"
|
||||
])
|
||||
(makeProbe "http" [ "hera.m-0.eu:80" ])
|
||||
(makeProbe "http" [
|
||||
"hera.m-0.eu:80"
|
||||
"home.vpn.m-0.eu"
|
||||
])
|
||||
(makeProbe "https" [
|
||||
"https://hera.m-0.eu"
|
||||
|
||||
|
@ -58,7 +61,6 @@ in
|
|||
"https://element.maralorn.de"
|
||||
"https://firefox-sync.maralorn.de"
|
||||
"https://fdroid.maralorn.de/index-v1.json"
|
||||
"https://home.maralorn.de"
|
||||
"https://matrix.maralorn.de"
|
||||
"https://monitoring.maralorn.de"
|
||||
"https://rpg.maralorn.de"
|
||||
|
|
|
@ -15,15 +15,6 @@
|
|||
let alert_type = "infrastructure";
|
||||
in
|
||||
[
|
||||
{
|
||||
job_name = "home-assistant";
|
||||
metrics_path = "/api/prometheus";
|
||||
bearer_token = pkgs.privateValue "" "home-assistant";
|
||||
scheme = "https";
|
||||
static_configs = [{
|
||||
targets = [ "home.maralorn.de" ];
|
||||
}];
|
||||
}
|
||||
(
|
||||
let name = "matrix-synapse";
|
||||
in
|
||||
|
|
|
@ -50,10 +50,3 @@ groups:
|
|||
severity: warning
|
||||
annotations:
|
||||
description: "mail queue {{ $labels.queue }} of {{ $labels.name }} has accumulated a waiting time of {{ $value | humanizeDuration }}."
|
||||
- alert: battery_low
|
||||
expr: label_replace(hass_battery_percent, "device", "$1", "entity", "sensor.(.*)_battery_level") < 25 and on(device) label_replace(hass_binary_sensor_state{entity=~"binary_sensor.*_is_charging"}, "device", "$1", "entity", "binary_sensor.(.*)_is_charging") and on(entity) hass_entity_available == 1
|
||||
for: 5m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
description: "battery on {{ $labels.device }} is at {{ $value }} while discharging."
|
||||
|
|
Loading…
Reference in a new issue