ma home: deploy home-assistant via docker
This commit is contained in:
parent
dd0a6294c8
commit
be32844179
@ -1,8 +1,12 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
#dev = "/dev/web_cam";
|
||||||
|
dev = "/dev/video0";
|
||||||
|
in
|
||||||
{
|
{
|
||||||
services.mjpg-streamer = {
|
services.mjpg-streamer = {
|
||||||
enable = true;
|
enable = true;
|
||||||
inputPlugin = "input_uvc.so -d /dev/web_cam -r 1280x960";
|
inputPlugin = "input_uvc.so -d ${dev} -r 1280x960";
|
||||||
};
|
};
|
||||||
users.users.octoprint.extraGroups = [ "video" ];
|
users.users.octoprint.extraGroups = [ "video" ];
|
||||||
# allow octoprint to access /dev/vchiq
|
# allow octoprint to access /dev/vchiq
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
inherit (import ../lib) btn_cycle_light;
|
inherit (import ../lib) btn_cycle_light;
|
||||||
|
schlafzimmer_komode = "light.schlafzimmer_komode_osram";
|
||||||
|
schlafzimmer_button = "sensor.schlafzimmer_btn2_click";
|
||||||
in {
|
in {
|
||||||
services.home-assistant.config.automation = [
|
services.home-assistant.config.automation = [
|
||||||
# (btn_cycle_light "light.arbeitszimmerbeleuchtung" "arbeitszimmer_btn1")
|
# (btn_cycle_light "light.arbeitszimmerbeleuchtung" "arbeitszimmer_btn1")
|
||||||
(btn_cycle_light "light.schlafzimmer_komode_osram" "schlafzimmer_btn2" 128)
|
|
||||||
{
|
{
|
||||||
alias = "toggle keller";
|
alias = "toggle keller";
|
||||||
trigger = {
|
trigger = {
|
||||||
@ -32,21 +34,35 @@ in {
|
|||||||
service = "light.toggle";
|
service = "light.toggle";
|
||||||
data = {
|
data = {
|
||||||
entity_id = "light.keller_osram";
|
entity_id = "light.keller_osram";
|
||||||
brightness = 50;
|
brightness = 25;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
# (btn_cycle_light "light.wohnzimmerbeleuchtung" "wohnzimmer_btn3")
|
# (btn_cycle_light "light.wohnzimmerbeleuchtung" "wohnzimmer_btn3")
|
||||||
{
|
{
|
||||||
alias = "Turn of all lights via schlafzimmer_btn2 double click";
|
alias = "Dim Toggle schlafzimmer komode";
|
||||||
trigger = {
|
trigger = {
|
||||||
platform = "state";
|
platform = "state";
|
||||||
entity_id = "sensor.schlafzimmer_btn2_click";
|
entity_id = schlafzimmer_button;
|
||||||
|
to = "single";
|
||||||
|
};
|
||||||
|
action = {
|
||||||
|
service = "light.toggle";
|
||||||
|
entity_id = schlafzimmer_komode;
|
||||||
|
brightness = 1;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
alias = "Bright Toggle schlafzimmer komode";
|
||||||
|
trigger = {
|
||||||
|
platform = "state";
|
||||||
|
entity_id = schlafzimmer_button;
|
||||||
to = "double";
|
to = "double";
|
||||||
};
|
};
|
||||||
action = {
|
action = {
|
||||||
service = "light.turn_off";
|
service = "light.toggle";
|
||||||
entity_id = "all";
|
entity_id = schlafzimmer_komode;
|
||||||
|
brightness = 255;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
let
|
let
|
||||||
schranklicht = [
|
schranklicht = [
|
||||||
"light.wohnzimmer_schrank_osram"
|
"light.wohnzimmer_schrank_osram"
|
||||||
"light.wohnzimmer_komode_osram"
|
# "light.wohnzimmer_komode_osram"
|
||||||
];
|
];
|
||||||
weihnachtslicht = "light.wohnzimmer_fenster_lichterkette_licht";
|
weihnachtslicht = "light.wohnzimmer_fenster_lichterkette_licht";
|
||||||
fernsehlicht = "light.wled";
|
fernsehlicht = "light.wled";
|
||||||
@ -31,8 +31,8 @@ in
|
|||||||
automation =
|
automation =
|
||||||
[
|
[
|
||||||
(turn_on schranklicht "-00:30:00")
|
(turn_on schranklicht "-00:30:00")
|
||||||
#(turn_on weihnachtslicht "-00:30:00")
|
(turn_on weihnachtslicht "-00:00:00")
|
||||||
(turn_on fernsehlicht "-00:00:00")
|
#(turn_on fernsehlicht "-00:00:00")
|
||||||
|
|
||||||
{ alias = "Always turn off the urlaub lights at ${final_off}";
|
{ alias = "Always turn off the urlaub lights at ${final_off}";
|
||||||
trigger = [
|
trigger = [
|
||||||
|
@ -7,7 +7,7 @@ Heute ist {{ weekday }}, du solltest gar nicht arbeiten!
|
|||||||
{% else %}
|
{% else %}
|
||||||
Willkommen auf Arbeit Felix.
|
Willkommen auf Arbeit Felix.
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
Das aktuell gewählte Projekt ist {{ states("sensor.felix_project") }}.
|
Dein Projekt ist {{ states("sensor.felix_project") }}.
|
||||||
|
|
||||||
{% set inside = states("sensor.wohnzimmer_temp_temperature") | float | round(2) -%}
|
{% set inside = states("sensor.wohnzimmer_temp_temperature") | float | round(2) -%}
|
||||||
{% set outside = states("sensor.dark_sky_temperature") | float | round(2) -%}
|
{% set outside = states("sensor.dark_sky_temperature") | float | round(2) -%}
|
||||||
|
@ -17,6 +17,7 @@ in {
|
|||||||
./zigbee2mqtt.nix
|
./zigbee2mqtt.nix
|
||||||
# ./multi/flurlicht.nix
|
# ./multi/flurlicht.nix
|
||||||
./multi/kurzzeitwecker.nix
|
./multi/kurzzeitwecker.nix
|
||||||
|
./intents
|
||||||
./multi/the_playlist.nix
|
./multi/the_playlist.nix
|
||||||
./multi/heizung.nix
|
./multi/heizung.nix
|
||||||
# ./multi/fliegen-couter.nix
|
# ./multi/fliegen-couter.nix
|
||||||
@ -92,6 +93,7 @@ in {
|
|||||||
{ type = "homeassistant"; }
|
{ type = "homeassistant"; }
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
tasmota = {};
|
||||||
binary_sensor = [
|
binary_sensor = [
|
||||||
{ platform = "workday";
|
{ platform = "workday";
|
||||||
name = "Arbeitstag";
|
name = "Arbeitstag";
|
||||||
|
30
makefu/2configs/home/ham/docker.nix
Normal file
30
makefu/2configs/home/ham/docker.nix
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
let
|
||||||
|
confdir = "/var/lib/homeassistant-docker";
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
./nginx.nix
|
||||||
|
./mqtt.nix
|
||||||
|
./signal-rest
|
||||||
|
./signal-rest/service.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [ 8123 ];
|
||||||
|
state = [ "/var/lib/hass/known_devices.yaml" ];
|
||||||
|
virtualisation.oci-containers.containers.hass = {
|
||||||
|
image = "homeassistant/home-assistant:latest";
|
||||||
|
environment = {
|
||||||
|
TZ = "Europe/Berlin";
|
||||||
|
UMASK = "007";
|
||||||
|
};
|
||||||
|
extraOptions = ["--net=host" ];
|
||||||
|
volumes = [
|
||||||
|
"${confdir}:/config"
|
||||||
|
#"/data/music:/config/media"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
#"f ${confdir}/docker-run 0770 kiosk kiosk - -"
|
||||||
|
"d ${confdir} 0770 kiosk kiosk - -"
|
||||||
|
];
|
||||||
|
}
|
35
makefu/2configs/home/ham/intents/default.nix
Normal file
35
makefu/2configs/home/ham/intents/default.nix
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
services.home-assistant.config = {
|
||||||
|
intent_script = {
|
||||||
|
GetTime.speech.text = ''
|
||||||
|
Es ist {{ now().hour }} Uhr {{ now().minute }}
|
||||||
|
'';
|
||||||
|
GutenMorgen.speech.text = ''
|
||||||
|
Einen wunderschönen Guten Morgen wünsche ich dir
|
||||||
|
'';
|
||||||
|
WieGehtEsDir.speech.text = ''
|
||||||
|
Mir geht es sehr gut, und dir?
|
||||||
|
'';
|
||||||
|
Statusreport.speech.text = builtins.readFile ./statusbericht.txt.j2;
|
||||||
|
StartMusic = {
|
||||||
|
speech.text = "Spiele {{ music }} musik";
|
||||||
|
action_async = [
|
||||||
|
{
|
||||||
|
service = "media_player.play_media";
|
||||||
|
data_template = {
|
||||||
|
entity_id = "media_player.{{ _intent.siteId }}";
|
||||||
|
media_content_id = builtins.readFile ./music_chooser.txt.j2;
|
||||||
|
media_content_type = "music";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
GetWeather = {
|
||||||
|
#speech.text = ''
|
||||||
|
# {{ states('sensor.openweathermap_weather') }} bei {{ states('sensor.openweathermap_temperature') }} Grad
|
||||||
|
#'';
|
||||||
|
speech.text = "{{ states('sensor.swr_prognose') }}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
13
makefu/2configs/home/ham/intents/music_chooser.txt.j2
Normal file
13
makefu/2configs/home/ham/intents/music_chooser.txt.j2
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{% if music == "lounge" -%}
|
||||||
|
https://cast1.asurahosting.com/proxy/julien/stream.mp3
|
||||||
|
{% elif music == "lassulus" -%}
|
||||||
|
http://radio.lassul.us:8000/radio.mp3
|
||||||
|
{% elif music == "groove" -%}
|
||||||
|
http://ice2.somafm.com/groovesalad-128.mp3
|
||||||
|
{% elif music == "swr3" -%}
|
||||||
|
https://liveradio.swr.de/sw282p3/swr3/play.mp3
|
||||||
|
{% elif music == "swr1" -%}
|
||||||
|
https://liveradio.swr.de/sw282p3/swr1bw/play.mp3
|
||||||
|
{% elif music == "radio" -%}
|
||||||
|
https://liveradio.swr.de/sw282p3/swr1bw/play.mp3
|
||||||
|
{% endif %}
|
37
makefu/2configs/home/ham/intents/statusbericht.txt.j2
Normal file
37
makefu/2configs/home/ham/intents/statusbericht.txt.j2
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
{% set arbeit_heute = is_state("binary_sensor.arbeitstag","on") -%}
|
||||||
|
{% set weekday = ['Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag','Sonntag'][now().weekday()] -%}
|
||||||
|
{% set is_friday = now().weekday() == 4 %}
|
||||||
|
|
||||||
|
Dies ist deine Persönliche Zusammenfassung
|
||||||
|
{% set inside = states("sensor.wohnzimmer_temp_temperature") | float | round(2) -%}
|
||||||
|
{% set outside = states("sensor.dark_sky_temperature") | float | round(2) -%}
|
||||||
|
{% set arbeit_morgen = is_state("binary_sensor.arbeitstag_morgen","on") -%}
|
||||||
|
|
||||||
|
Die Wetteraussichten: {{ states("sensor.dark_sky_hourly_summary") | replace(".","")}} bei {{ states("sensor.dark_sky_temperature") }} Grad mit {{ states("sensor.dark_sky_humidity") | round(0) }}% Luftfeuchtigkeit.
|
||||||
|
{% if states("calendar.abfall_papiermuell") == "on" %}
|
||||||
|
Heute ist Papiermuell, bring noch schnell dein Papier raus
|
||||||
|
{% endif %}
|
||||||
|
{% if states("calendar.abfall_restmuell") == "on" %}
|
||||||
|
Ausserdem ist heute Restmuell.
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
{% if ( outside < inside ) and ( outside > 18 ) %}
|
||||||
|
Draussen ist es gerade {{ ((inside - outside) | round(1) )}} gerade kühler
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
{% set current_count = state_attr("sensor.dwd_weather_warnings_current_warning_level", "warning_count") %}
|
||||||
|
{% for i in range(current_count) %}
|
||||||
|
{% set idx = i + 1 %}
|
||||||
|
{% set headline = state_attr("sensor.dwd_weather_warnings_current_warning_level", "warning_" ~ idx ~ "_headline") %}
|
||||||
|
{% set description = state_attr("sensor.dwd_weather_warnings_current_warning_level", "warning_" ~ idx ~ "_description") %}
|
||||||
|
{% set level = state_attr("sensor.dwd_weather_warnings_current_warning_level", "warning_" ~ idx ~ "_level") %}
|
||||||
|
{% set time_start = state_attr("sensor.dwd_weather_warnings_current_warning_level", "warning_" ~ idx ~ "_start") %}
|
||||||
|
{% set time_end = state_attr("sensor.dwd_weather_warnings_current_warning_level", "warning_" ~ idx ~ "_end") %}
|
||||||
|
Wetterwarnung {{idx}}: {{ headline }} Stufe {{level}} von {{ time_start.strftime("%H:%M") ~ " bis " ~ time_end.strftime("%H:%M") }} Uhr
|
||||||
|
|
||||||
|
{{ description }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if is_friday %}
|
||||||
|
Endlich ist Freitag!
|
||||||
|
{% endif -%}
|
@ -27,12 +27,11 @@ in
|
|||||||
#}
|
#}
|
||||||
{ delay.seconds = 1; }
|
{ delay.seconds = 1; }
|
||||||
{ delay = ''
|
{ delay = ''
|
||||||
{% set duration = state_attr("${entity}","media_duration") %}
|
{% set duration = state_attr("${entity}","media_duration") or 0 %}
|
||||||
{% set seconds = duration % 60 %}
|
{% set seconds = (duration % 60 ) %}
|
||||||
{% set minutes = (duration / 60)|int % 60 %}
|
{% set minutes = (duration / 60)|int % 60 %}
|
||||||
{% set hours = (duration / 3600)|int %}
|
{% set hours = (duration / 3600)|int %}
|
||||||
{{ "%02i:%02i:%02i"|format(hours, minutes, seconds)}}
|
{{ "%02i:%02i:%02i"|format(hours, minutes, seconds)}}
|
||||||
|
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -6,10 +6,30 @@ let
|
|||||||
wohnzimmer_deko = [
|
wohnzimmer_deko = [
|
||||||
"light.wohnzimmer_fernseher_led_strip" # led um fernseher
|
"light.wohnzimmer_fernseher_led_strip" # led um fernseher
|
||||||
"light.wohnzimmer_lichterkette_led_strip" # led um fernsehwand
|
"light.wohnzimmer_lichterkette_led_strip" # led um fernsehwand
|
||||||
"light.kinderzimmer_lichterkette_licht" # led um fenster
|
"light.wohnzimmer_fenster_lichterkette_licht" # led um fenster
|
||||||
];
|
];
|
||||||
in {
|
in {
|
||||||
imports = [ ./tint_wohnzimmer.nix ];
|
imports = [ ./tint_wohnzimmer.nix ];
|
||||||
|
services.home-assistant.config.scene = [
|
||||||
|
{ name = "Wohnzimmer Abendlicht";
|
||||||
|
id = "living_room_evening";
|
||||||
|
entities = {
|
||||||
|
"light.wohnzimmer_komode_osram_light" = {
|
||||||
|
state = "on";
|
||||||
|
brightness = 128;
|
||||||
|
};
|
||||||
|
"light.wohnzimmer_schrank_osram_light" = {
|
||||||
|
state = "on";
|
||||||
|
brightness = 128;
|
||||||
|
};
|
||||||
|
"light.wohnzimmer_fenster_lichterkette_licht" = "on";
|
||||||
|
"light.wohnzimmer_fernseher_led_strip" = {
|
||||||
|
state = "on";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
];
|
||||||
services.home-assistant.config.wled = {};
|
services.home-assistant.config.wled = {};
|
||||||
services.home-assistant.config.light = [
|
services.home-assistant.config.light = [
|
||||||
{
|
{
|
||||||
@ -22,6 +42,11 @@ in {
|
|||||||
name = "Wohnzimmer Deko";
|
name = "Wohnzimmer Deko";
|
||||||
entities = wohnzimmer_deko;
|
entities = wohnzimmer_deko;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
platform = "group";
|
||||||
|
name = "living_room_lights";
|
||||||
|
entities = wohnzimmerbeleuchtung ++ wohnzimmer_deko;
|
||||||
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,11 +3,11 @@ let
|
|||||||
in {
|
in {
|
||||||
services.home-assistant.config = {
|
services.home-assistant.config = {
|
||||||
notify = [
|
notify = [
|
||||||
{
|
#{
|
||||||
platform = "nfandroidtv";
|
#platform = "nfandroidtv";
|
||||||
name = "FireTV Wohnzimmer Notification";
|
#name = "FireTV Wohnzimmer Notification";
|
||||||
host = firetv_stick;
|
#host = firetv_stick;
|
||||||
}
|
#}
|
||||||
];
|
];
|
||||||
media_player = [
|
media_player = [
|
||||||
#{
|
#{
|
||||||
@ -16,12 +16,12 @@ in {
|
|||||||
# host = firetv_stick;
|
# host = firetv_stick;
|
||||||
#}
|
#}
|
||||||
# Configuration needs to be done by hand via web interface "integration"
|
# Configuration needs to be done by hand via web interface "integration"
|
||||||
{ platform = "androidtv";
|
#{ platform = "androidtv";
|
||||||
name = "FireTV Stick Android";
|
# name = "FireTV Stick Android";
|
||||||
device_class = "firetv";
|
# device_class = "firetv";
|
||||||
host = firetv_stick;
|
# host = firetv_stick;
|
||||||
port = 5555;
|
# port = 5555;
|
||||||
}
|
#}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
services.mosquitto = {
|
services.mosquitto = {
|
||||||
enable = true;
|
enable = true;
|
||||||
persistence = false;
|
persistence = false;
|
||||||
settings.max_keepalive = 60;
|
settings.max_keepalive = 1060;
|
||||||
listeners = [
|
listeners = [
|
||||||
{
|
{
|
||||||
port = 1883;
|
port = 1883;
|
||||||
|
@ -9,128 +9,80 @@
|
|||||||
let
|
let
|
||||||
button = "sensor.zigbee_btn2_click";
|
button = "sensor.zigbee_btn2_click";
|
||||||
notify = "notify.signal_home";
|
notify = "notify.signal_home";
|
||||||
|
# für {{ _intent.siteId }} - name of the rhasspy instance: arbeitszimmer
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
services.home-assistant.config = {
|
services.home-assistant.config = {
|
||||||
timer.kurzzeitwecker =
|
automation = [];
|
||||||
{
|
timer.kurzzeitwecker = {
|
||||||
name = "Zigbee Kurzzeitwecker";
|
name = "Wecker Wohnung";
|
||||||
duration = 300;
|
|
||||||
};
|
};
|
||||||
script.add_5_minutes_to_kurzzeitwecker =
|
timer.wecker_arbeitszimmer = {
|
||||||
|
name = "Wecker Arbeitszimmer";
|
||||||
|
};
|
||||||
|
timer.wecker_wohnzimmer = {
|
||||||
|
name = "Wecker Wohnzimmer";
|
||||||
|
};
|
||||||
|
intent = {};
|
||||||
|
intent_script = {
|
||||||
|
TimerjobStart = {
|
||||||
|
speech.text = ''
|
||||||
|
{% set h = hours|default('0')|string %}
|
||||||
|
{% set m = minutes|default('0')|string %}
|
||||||
|
{% if h == "0" %}
|
||||||
|
Wecker gestellt {{ m }} Minuten
|
||||||
|
{% elif m == "0" %}
|
||||||
|
Wecker gestellt {{ h }} Stunden
|
||||||
|
{% else %}
|
||||||
|
Wecker gestellt {{ h }} Stunden und {{ m }} Minuten
|
||||||
|
{% endif %}
|
||||||
|
'';
|
||||||
|
action = [
|
||||||
{
|
{
|
||||||
alias = "Add 5 minutes to kurzzeitwecker";
|
service = "timer.start";
|
||||||
sequence = [
|
|
||||||
{ service = "timer.pause";
|
data.entity_id = "timer.kurzzeitwecker";
|
||||||
entity_id = "timer.kurzzeitwecker";
|
data.duration = ''
|
||||||
|
{% set h = hours|default("0")|int %}
|
||||||
|
{% set m = minutes|default("0")|int %}
|
||||||
|
{{ "%02d" | format(h) }}:{{ "%02d" | format(m) }}:00
|
||||||
|
'';
|
||||||
|
|
||||||
}
|
}
|
||||||
{ service = "timer.start";
|
];
|
||||||
data_template = {
|
};
|
||||||
entity_id = "timer.kurzzeitwecker";
|
TimerjobRemaining = {
|
||||||
duration = ''
|
speech.text = ''
|
||||||
{% set r = state_attr('timer.kurzzeitwecker', 'remaining') ~ '-0000' %}
|
{% set timer = states('timer.kurzzeitwecker') %}
|
||||||
{% set t = strptime(r, '%H:%M:%S.%f%z') %}
|
{% if timer == 'idle' %}
|
||||||
{{ (as_timestamp(t) + 300) | timestamp_custom('%H:%M:%S', false) }}
|
Wecker läuft nicht
|
||||||
|
{% elif timer == 'active' %}
|
||||||
|
{% set remaining = as_timestamp( state_attr('timer.kurzzeitwecker','finishes_at') )-( as_timestamp(now())) %}
|
||||||
|
{% set s = ((remaining % 60)) | int %}
|
||||||
|
{% set m = ((remaining % 3600) / 60) | int %}
|
||||||
|
{% set h = ((remaining % 86400) / 3600) | int %}
|
||||||
|
{% if h == 0 %}
|
||||||
|
Es verbleiben {{ m }} Minuten und {{ s }} Sekunden
|
||||||
|
{% elif m == 0 %}
|
||||||
|
Es verbleiben {{ h }} Stunden
|
||||||
|
{% elif m == 0 and h == 0 %}
|
||||||
|
Es verbleiben {{ s }} Sekunden
|
||||||
|
{% else %}
|
||||||
|
Es verbleiben {{ h }} Stunden {{ m }} Minuten
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
TimerjobStop = {
|
||||||
];
|
speech.text = ''
|
||||||
};
|
Wecker gestoppt
|
||||||
automation =
|
'';
|
||||||
[
|
|
||||||
{
|
|
||||||
alias = "Start Timer 5min";
|
|
||||||
trigger = {
|
|
||||||
platform = "state";
|
|
||||||
entity_id = button;
|
|
||||||
to = "single";
|
|
||||||
};
|
|
||||||
condition =
|
|
||||||
{ condition = "state";
|
|
||||||
entity_id = "timer.kurzzeitwecker";
|
|
||||||
state = "idle";
|
|
||||||
};
|
|
||||||
|
|
||||||
action = [
|
action = [
|
||||||
{ service = "timer.start";
|
{ service = "timer.cancel";
|
||||||
entity_id = "timer.kurzzeitwecker";
|
data.entity_id = "timer.kurzzeitwecker";
|
||||||
data.duration = "00:05:00";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
service = notify;
|
|
||||||
data.message = "Timer gestartet {{state_attr('timer.kurzzeitwecker', 'remaining') }}, verbleibend ";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
alias = "Add Timer 5min";
|
|
||||||
trigger = {
|
|
||||||
platform = "state";
|
|
||||||
entity_id = button;
|
|
||||||
to = "single";
|
|
||||||
};
|
|
||||||
condition =
|
|
||||||
{ condition = "state";
|
|
||||||
entity_id = "timer.kurzzeitwecker";
|
|
||||||
state = "active";
|
|
||||||
};
|
|
||||||
|
|
||||||
action = [
|
|
||||||
{ service = "homeassistant.turn_on";
|
|
||||||
entity_id = "script.add_5_minutes_to_kurzzeitwecker";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
service = notify;
|
|
||||||
data.message = ''Timer um 5 minuten verlängert, {{ state_attr('timer.kurzzeitwecker', 'remaining') | truncate(9,True," ") }} verbleibend '';
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
alias = "Stop timer on double click";
|
|
||||||
trigger = [
|
|
||||||
{
|
|
||||||
platform = "state";
|
|
||||||
entity_id = button;
|
|
||||||
to = "double";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
platform = "state";
|
|
||||||
entity_id = button;
|
|
||||||
to = "triple";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
condition =
|
|
||||||
{
|
|
||||||
condition = "state";
|
|
||||||
entity_id = "timer.kurzzeitwecker";
|
|
||||||
state = "active";
|
|
||||||
};
|
|
||||||
|
|
||||||
action = [
|
|
||||||
{
|
|
||||||
service = "timer.cancel";
|
|
||||||
entity_id = "timer.kurzzeitwecker";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
service = notify;
|
|
||||||
data.message = "Timer gestoppt, abgebrochen";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
alias = "Timer Finished";
|
|
||||||
trigger = {
|
|
||||||
platform = "event";
|
|
||||||
event_type = "timer.finished";
|
|
||||||
event_data.entity_id = "timer.kurzzeitwecker";
|
|
||||||
};
|
|
||||||
action = [
|
|
||||||
{
|
|
||||||
service = notify;
|
|
||||||
data.message = "Timer beendet";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -40,5 +40,16 @@
|
|||||||
{ platform = "accuweather";
|
{ platform = "accuweather";
|
||||||
api_key = "!secret accuweather";
|
api_key = "!secret accuweather";
|
||||||
}
|
}
|
||||||
|
{ platform = "scrape";
|
||||||
|
resource = "https://www.swr.de/wetter/wetter-liste-swr-100.html";
|
||||||
|
name = "SWR Prognose";
|
||||||
|
select = "p[data-refresh=\"weather-headline\"]";
|
||||||
|
}
|
||||||
|
{ platform = "scrape";
|
||||||
|
resource = "https://www.swr.de/wetter/wetter-liste-swr-100.html";
|
||||||
|
name = "SWR Prognose Langtext";
|
||||||
|
select = "p[data-refresh=\"weather-text\"]";
|
||||||
|
}
|
||||||
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -1,66 +1,34 @@
|
|||||||
{ lib, config, ... }:
|
{ lib, config, ... }:
|
||||||
|
let
|
||||||
|
port = 8096;
|
||||||
|
in
|
||||||
{
|
{
|
||||||
services.jellyfin.enable = true;
|
services.jellyfin.enable = true;
|
||||||
services.jellyfin.openFirewall = true;
|
# services.jellyfin.openFirewall = true;
|
||||||
|
networking.firewall.interfaces.wiregrill = {
|
||||||
|
allowedTCPPorts = [ 80 port 8920 ];
|
||||||
|
allowedUDPPorts = [ 1900 7359 ];
|
||||||
|
};
|
||||||
state = [ "/var/lib/jellyfin" ];
|
state = [ "/var/lib/jellyfin" ];
|
||||||
users.users.${config.services.jellyfin.user}.extraGroups = [ "download" "video" "render" ];
|
users.users.${config.services.jellyfin.user}.extraGroups = [ "download" "video" "render" ];
|
||||||
|
|
||||||
systemd.services.jellyfin = {
|
systemd.services.jellyfin = {
|
||||||
|
|
||||||
after = [ "media-cloud.mount" ];
|
after = [ "media-cloud.mount" ];
|
||||||
serviceConfig = rec {
|
serviceConfig = rec {
|
||||||
|
RequiresMountFor = [ "/media/cloud" ];
|
||||||
SupplementaryGroups = lib.mkForce [ "video" "render" "download" ];
|
SupplementaryGroups = lib.mkForce [ "video" "render" "download" ];
|
||||||
UMask = lib.mkForce "0077";
|
UMask = lib.mkForce "0077";
|
||||||
|
};
|
||||||
|
};
|
||||||
Type = lib.mkForce "simple";
|
services.nginx.virtualHosts."jelly" = {
|
||||||
StateDirectory = lib.mkForce "jellyfin";
|
serverAliases = [
|
||||||
StateDirectoryMode = lib.mkForce "0700";
|
"jelly.lan" "movies.lan"
|
||||||
CacheDirectory = lib.mkForce "jellyfin";
|
"jelly.makefu.w" "makefu.omo.w"
|
||||||
CacheDirectoryMode = lib.mkForce "0700";
|
|
||||||
WorkingDirectory = lib.mkForce "/var/lib/jellyfin";
|
|
||||||
Restart = lib.mkForce "on-failure";
|
|
||||||
TimeoutSec = lib.mkForce 15;
|
|
||||||
SuccessExitStatus = lib.mkForce ["0" "143"];
|
|
||||||
|
|
||||||
# Security options:
|
|
||||||
NoNewPrivileges = lib.mkForce true;
|
|
||||||
SystemCallArchitectures = lib.mkForce "native";
|
|
||||||
# AF_NETLINK needed because Jellyfin monitors the network connection
|
|
||||||
RestrictAddressFamilies = lib.mkForce [ "AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK" ];
|
|
||||||
RestrictNamespaces = lib.mkForce false;
|
|
||||||
RestrictRealtime = lib.mkForce true;
|
|
||||||
RestrictSUIDSGID = lib.mkForce true;
|
|
||||||
ProtectControlGroups = lib.mkForce false;
|
|
||||||
ProtectHostname = lib.mkForce true;
|
|
||||||
ProtectKernelLogs = lib.mkForce false;
|
|
||||||
ProtectKernelModules = lib.mkForce false;
|
|
||||||
ProtectKernelTunables = lib.mkForce false;
|
|
||||||
LockPersonality = lib.mkForce true;
|
|
||||||
PrivateTmp = lib.mkForce false;
|
|
||||||
# needed for hardware accelaration
|
|
||||||
PrivateDevices = lib.mkForce false;
|
|
||||||
PrivateUsers = lib.mkForce true;
|
|
||||||
RemoveIPC = lib.mkForce true;
|
|
||||||
|
|
||||||
SystemCallFilter = lib.mkForce [
|
|
||||||
"~@clock"
|
|
||||||
"~@aio"
|
|
||||||
"~@chown"
|
|
||||||
"~@cpu-emulation"
|
|
||||||
"~@debug"
|
|
||||||
"~@keyring"
|
|
||||||
"~@memlock"
|
|
||||||
"~@module"
|
|
||||||
"~@mount"
|
|
||||||
"~@obsolete"
|
|
||||||
"~@privileged"
|
|
||||||
"~@raw-io"
|
|
||||||
"~@reboot"
|
|
||||||
"~@setuid"
|
|
||||||
"~@swap"
|
|
||||||
];
|
];
|
||||||
SystemCallErrorNumber = lib.mkForce "EPERM";
|
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://localhost:${toString port}";
|
||||||
|
proxyWebsockets = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,7 @@ in
|
|||||||
MusicFolder = "/media/cryptX/music/kinder";
|
MusicFolder = "/media/cryptX/music/kinder";
|
||||||
Address = "0.0.0.0";
|
Address = "0.0.0.0";
|
||||||
};
|
};
|
||||||
systemd.services.navidrome.after = [ "media-cryptX.mount" "cryptsetup.target"
|
systemd.services.navidrome.serviceConfig.RequiresMountFor = [ "/media/cryptX" ];
|
||||||
"local-fs.target" "remote-fs.target" ];
|
|
||||||
|
|
||||||
state = [ "/var/lib/navidrome" ];
|
state = [ "/var/lib/navidrome" ];
|
||||||
# networking.firewall.allowedTCPPorts = [ 4040 ];
|
# networking.firewall.allowedTCPPorts = [ 4040 ];
|
||||||
|
@ -70,15 +70,18 @@ in
|
|||||||
PHOTOPRISM_HTTP_PORT = port; # Built-in Web server port
|
PHOTOPRISM_HTTP_PORT = port; # Built-in Web server port
|
||||||
PHOTOPRISM_HTTP_COMPRESSION = "gzip"; # Improves transfer speed and bandwidth utilization (none or gzip)
|
PHOTOPRISM_HTTP_COMPRESSION = "gzip"; # Improves transfer speed and bandwidth utilization (none or gzip)
|
||||||
PHOTOPRISM_DEBUG = "false"; # Run in debug mode (shows additional log messages)
|
PHOTOPRISM_DEBUG = "false"; # Run in debug mode (shows additional log messages)
|
||||||
PHOTOPRISM_PUBLIC = "true"; # No authentication required (disables password protection)
|
# PHOTOPRISM_PUBLIC = "true"; # No authentication required (disables password protection)
|
||||||
PHOTOPRISM_READONLY = "false"; # Don't modify originals directory (reduced functionality)
|
PHOTOPRISM_READONLY = "false"; # Don't modify originals directory (reduced functionality)
|
||||||
PHOTOPRISM_EXPERIMENTAL = "true"; # Enables experimental features
|
PHOTOPRISM_EXPERIMENTAL = "true"; # Enables experimental features
|
||||||
PHOTOPRISM_DISABLE_WEBDAV = "false"; # Disables built-in WebDAV server
|
# PHOTOPRISM_DISABLE_WEBDAV = "false"; # Disables built-in WebDAV server
|
||||||
PHOTOPRISM_DISABLE_SETTINGS = "false"; # Disables Settings in Web UI
|
PHOTOPRISM_DISABLE_SETTINGS = "false"; # Disables Settings in Web UI
|
||||||
PHOTOPRISM_DISABLE_TENSORFLOW = "false"; # Disables using TensorFlow for image classification
|
PHOTOPRISM_DISABLE_TENSORFLOW = "false"; # Disables using TensorFlow for image classification
|
||||||
PHOTOPRISM_DARKTABLE_PRESETS = "false"; # Enables Darktable presets and disables concurrent RAW conversion
|
PHOTOPRISM_DARKTABLE_PRESETS = "false"; # Enables Darktable presets and disables concurrent RAW conversion
|
||||||
PHOTOPRISM_DETECT_NSFW = "false"; # Flag photos as private that MAY be offensive (requires TensorFlow)
|
PHOTOPRISM_DETECT_NSFW = "false"; # Flag photos as private that MAY be offensive (requires TensorFlow)
|
||||||
PHOTOPRISM_UPLOAD_NSFW = "true"; # Allow uploads that MAY be offensive
|
PHOTOPRISM_UPLOAD_NSFW = "true"; # Allow uploads that MAY be offensive
|
||||||
|
PHOTOPRISM_AUTH_MODE = "password";
|
||||||
|
PHOTOPRISM_ADMIN_USER = "admin";
|
||||||
|
PHOTOPRISM_ADMIN_PASSWORD = "admin";
|
||||||
|
|
||||||
#PHOTOPRISM_DATABASE_DRIVER = "postgres";
|
#PHOTOPRISM_DATABASE_DRIVER = "postgres";
|
||||||
#PHOTOPRISM_DATABASE_SERVER = "postgres-prism:5432";
|
#PHOTOPRISM_DATABASE_SERVER = "postgres-prism:5432";
|
||||||
|
40
makefu/2configs/home/rhasspy/default.nix
Normal file
40
makefu/2configs/home/rhasspy/default.nix
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{ lib,config, ... }:
|
||||||
|
# uses alsa instead of pulseaduio server
|
||||||
|
let
|
||||||
|
profiles = "/var/lib/rhasspy";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
systemd.services.docker-rhasspy.after = [ "network-online.target" ];
|
||||||
|
|
||||||
|
virtualisation.oci-containers.containers.rhasspy = {
|
||||||
|
image = "rhasspy/rhasspy:latest";
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
TZ = "Europe/Berlin";
|
||||||
|
PULSE_SERVER = "tcp:${ config.krebs.build.host.name }:4713";
|
||||||
|
};
|
||||||
|
|
||||||
|
ports = [
|
||||||
|
"12101:12101"
|
||||||
|
];
|
||||||
|
|
||||||
|
volumes = [
|
||||||
|
"/etc/localtime:/etc/localtime:ro"
|
||||||
|
"${profiles}:/profiles"
|
||||||
|
];
|
||||||
|
|
||||||
|
cmd = [ "--user-profiles" "/profiles" "--profile" "de" ];
|
||||||
|
extraOptions = [
|
||||||
|
"--device=/dev/snd:/dev/snd"
|
||||||
|
"--group-add=audio"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d ${profiles} 0770 root root - -"
|
||||||
|
];
|
||||||
|
|
||||||
|
# required to allow rhasspy to connect to pulse server
|
||||||
|
# hardware.pulseaudio.enable = lib.mkForce false;
|
||||||
|
networking.firewall.allowedTCPPorts = [ 4713 ];
|
||||||
|
|
||||||
|
}
|
23
makefu/2configs/home/rhasspy/led-control.nix
Normal file
23
makefu/2configs/home/rhasspy/led-control.nix
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
cfg = pkgs.writeText "hcl-config.json" (builtins.toJSON {
|
||||||
|
engine = "rhasspy";
|
||||||
|
pathToConfig = "/var/lib/rhasspy/de/profile.json";
|
||||||
|
hardware = "respeaker4MicArray";
|
||||||
|
pattern = "fake-name";
|
||||||
|
enableDoA = false;
|
||||||
|
});
|
||||||
|
in {
|
||||||
|
systemd.services.HermesLedControl = {
|
||||||
|
description = "Led Server for ReSpeaker 4-array";
|
||||||
|
after = [ "network-online.target" "docker-rhasspy.service" ] ;
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
# User = "nobody"; # need a user with permissions to run nix-shell
|
||||||
|
ExecStart = "${pkgs.HermesLedControl}/bin/HermesLedControl --hermesLedControlConfig=${toString cfg}";
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = 10;
|
||||||
|
PrivateTmp = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -32,6 +32,10 @@ in
|
|||||||
include_device_information = true;
|
include_device_information = true;
|
||||||
client_id = "zigbee2mqtt";
|
client_id = "zigbee2mqtt";
|
||||||
};
|
};
|
||||||
|
availability = {
|
||||||
|
active.timeout = 10;
|
||||||
|
passive.timeout = 1500;
|
||||||
|
};
|
||||||
frontend = {
|
frontend = {
|
||||||
port = webport;
|
port = webport;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user