diff options
Diffstat (limited to 'makefu/2configs/home')
25 files changed, 1393 insertions, 0 deletions
diff --git a/makefu/2configs/home/ham/automation/firetv_restart.nix b/makefu/2configs/home/ham/automation/firetv_restart.nix new file mode 100644 index 000000000..12e0e845a --- /dev/null +++ b/makefu/2configs/home/ham/automation/firetv_restart.nix @@ -0,0 +1,37 @@ +let + cmd = command: { + service = "androidtv.adb_command"; + data = { + entity_id = "media_player.firetv_stick"; + inherit command; + }; + }; + sec = seconds: { delay.seconds = seconds; }; +in +{ + services.home-assistant.config.automation = + [ + { + alias = "Nightly reboot of firetv"; + trigger = { + platform = "time"; + at = "03:00:00"; + }; + action = [ + (cmd "reboot") + (sec 90) # go to my music because apparently select_source does not seem to always work + (cmd "HOME") + (sec 2) + (cmd "DOWN") + (sec 2) + (cmd "DOWN") + (sec 2) + (cmd "ENTER") + (sec 4) + (cmd "RIGHT") + (sec 2) + (cmd "RIGHT") + ]; + } + ]; +} diff --git a/makefu/2configs/home/ham/automation/giesskanne.nix b/makefu/2configs/home/ham/automation/giesskanne.nix new file mode 100644 index 000000000..4b0fb61dd --- /dev/null +++ b/makefu/2configs/home/ham/automation/giesskanne.nix @@ -0,0 +1,102 @@ +# uses: +# switch.crafting_giesskanne_relay +let + cam = { + name = "chilicam"; + camera = "camera.espcam_02"; + light = "light.espcam_02_light"; + seconds = 60; # default shutoff to protect the LED from burning out + }; + seconds = 60; + pump = "switch.arbeitszimmer_giesskanne_relay"; + # sensor = "sensor.statistics_for_sensor_crafting_brotbox_soil_moisture"; +in +{ + services.home-assistant.config = + { + #sensor = map ( entity_id: { + # platform = "statistics"; + # name = "Statistics for ${entity_id}"; + # inherit entity_id; + # max_age.minutes = "60"; + # sampling_size = 1000; + # }) [ "sensor.crafting_brotbox_soil_moisture" ]; + + automation = + [ + + ##### brotbox + { alias = "Water the plant for ${toString seconds} seconds"; + trigger = [ + { # trigger at 23:15 no matter what + # TODO: retry or run only if switch.wasser is available + platform = "time"; + at = "23:15:00"; + } + ]; + action = + [ + { # take a snapshot before watering + service = "homeassistant.turn_on"; + entity_id = [ cam.light ]; + } + { # TODO: we could also create a recording with camera.record + service = "camera.snapshot"; + data = { + entity_id = cam.camera; + # TODO: create /var/lib/hass/cam/ - now being done manually + filename = "/var/lib/hass/cam/${cam.name}_{{ now().strftime('%Y%m%d-%H%M%S') }}.jpg"; + }; + } + + { # now turn on the pumping services + # i do not start hte pump and light before the snapshot because i do + # not know how long it takes (do not want to water the plants for too long) + service = "homeassistant.turn_on"; + entity_id = [ pump ]; + } + { delay.seconds = seconds; } + { + service = "homeassistant.turn_off"; + entity_id = [ pump cam.light ]; + } + ]; + } + { alias = "Always turn off the light after ${toString (cam.seconds)}s"; + trigger = [ + { + platform = "state"; + entity_id = cam.light; + to = "on"; + for.seconds = cam.seconds; + } + ]; + action = + [ + { + service = "homeassistant.turn_off"; + entity_id = [ pump cam.light ]; + } + ]; + } + + { alias = "Always turn off water after ${toString (seconds * 2)}s"; + trigger = [ + { + platform = "state"; + entity_id = pump; + to = "on"; + for.seconds = seconds*2; + } + ]; + action = + [ + { + service = "homeassistant.turn_off"; + entity_id = [ pump cam.light ]; + } + ]; + } + ]; + }; +} diff --git a/makefu/2configs/home/ham/automation/light_buttons.nix b/makefu/2configs/home/ham/automation/light_buttons.nix new file mode 100644 index 000000000..32d134ecc --- /dev/null +++ b/makefu/2configs/home/ham/automation/light_buttons.nix @@ -0,0 +1,44 @@ +# light.wohnzimmerbeleuchtung +# light.wohnzimmer_deko +# light.arbeitszimmerbeleuchtung +# light.arbeitszimmer_deko +# light.schlafzimmerbeleuchtung + +let + toggle = light: btn: + { + alias = "Toggle Light ${light} via ${btn}"; + trigger = { + platform = "state"; + entity_id = "sensor.${btn}_click"; + to = "single"; + }; + action = { + service = "light.toggle"; + data.entity_id = light; + data.transition = 0; + }; + }; + turn_off_all = btn: + { + alias = "Turn of all lights via ${btn} double click"; + trigger = { + platform = "state"; + entity_id = "sensor.${btn}_click"; + to = "double"; + }; + action = { + service = "light.turn_off"; + entity_id = "all"; + }; + }; +in { + services.home-assistant.config.automation = [ + (toggle "light.arbeitszimmerbeleuchtung" "arbeitszimmer_btn1") + (toggle "light.schlafzimmerbeleuchtung" "schlafzimmer_btn2") + (toggle "light.wohnzimmerbeleuchtung" "wohnzimmer_btn3") + (turn_off_all "arbeitszimmer_btn1") + (turn_off_all "schlafzimmer_btn2") + (turn_off_all "wohnzimmer_btn3") + ]; +} diff --git a/makefu/2configs/home/ham/automation/moodlight.nix b/makefu/2configs/home/ham/automation/moodlight.nix new file mode 100644 index 000000000..d0e336851 --- /dev/null +++ b/makefu/2configs/home/ham/automation/moodlight.nix @@ -0,0 +1,46 @@ +# uses: + +let + wohnzimmer = "light.wohnzimmer_fenster_lichterkette_licht"; + arbeitszimmer = "light.box_led_status"; + final_off = "01:00"; + + turn_on = entity_id: at: extra: + { alias = "Turn on ${entity_id} at ${at}"; + trigger = [ + { platform = "time"; inherit at; } + ]; + action = + [ + ({ service = "light.turn_on"; + data = { + inherit entity_id; + + } // extra; + }) + ]; + }; +in +{ + services.home-assistant.config = + { + automation = + [ + # (turn_on wohnzimmer "17:30") + (turn_on arbeitszimmer "9:00" { effect = "Slow Random Twinkle";}) + + { alias = "Always turn off the lights at ${final_off}"; + trigger = [ + { platform = "time"; at = final_off; } + ]; + action = + [ + { + service = "light.turn_off"; + entity_id = [ wohnzimmer arbeitszimmer]; + } + ]; + } + ]; + }; +} diff --git a/makefu/2configs/home/ham/automation/urlaub.nix b/makefu/2configs/home/ham/automation/urlaub.nix new file mode 100644 index 000000000..a6b9be96f --- /dev/null +++ b/makefu/2configs/home/ham/automation/urlaub.nix @@ -0,0 +1,44 @@ +# uses: +# light.wohnzimmer_schrank_osram +# light.wohnzimmer_fernseher_led_strip +# "all" lights + +let + schranklicht = "light.wohnzimmer_schrank_osram"; + fernsehlicht = "light.wohnzimmer_fernseher_led_strip"; + final_off = "01:00"; + + turn_on = entity_id: at: + { alias = "Turn on ${entity_id} at ${at}"; + trigger = [ + { platform = "time"; inherit at; } + ]; + action = + [ + { service = "light.turn_on"; inherit entity_id; } + ]; + }; +in +{ + services.home-assistant.config = + { + automation = + [ + (turn_on schranklicht "17:30") + (turn_on fernsehlicht "19:00") + + { alias = "Always turn off the urlaub lights at ${final_off}"; + trigger = [ + { platform = "time"; at = final_off; } + ]; + action = + [ + { + service = "light.turn_off"; + entity_id = [ schranklicht fernsehlicht ]; + } + ]; + } + ]; + }; +} diff --git a/makefu/2configs/home/ham/automation/wohnzimmer_rf_fernbedienung.nix b/makefu/2configs/home/ham/automation/wohnzimmer_rf_fernbedienung.nix new file mode 100644 index 000000000..4303cdfa5 --- /dev/null +++ b/makefu/2configs/home/ham/automation/wohnzimmer_rf_fernbedienung.nix @@ -0,0 +1,135 @@ +# This module maps the RF433 Remote Control to zigbee and wifi lights +let + rf_turn_off = code: light: + { + alias = "Turn off ${light} via rf code ${code}"; + trigger = { + platform = "event"; + event_type = "esphome.rf_code_received"; + event_data.code = code; + }; + action = { + service = "light.turn_off"; + data.entity_id = light; + }; + }; + rf_turn_on = code: light: + { + alias = "Turn on ${light} via rf code ${code}"; + trigger = { + platform = "event"; + event_type = "esphome.rf_code_received"; + event_data.code = code; + }; + action = { + service = "light.turn_on"; + data.entity_id = light; + }; + }; + rf_state = code: light: halfbright: + let + maxbright = 255; + transition = 0.2; # seconds + in + # this function implements a simple state machine based on the state and brightness of the light (light must support brightness + { + alias = "Cycle through states of ${light} via rf code ${code}"; + trigger = { + platform = "event"; + event_type = "esphome.rf_code_received"; + event_data.code = code; + }; + action = { + choose = [ + { + # state 0: off to half + conditions = { + condition = "template"; + value_template = ''{{ states("${light}") == "off" }}''; + }; + sequence = [ + { + service = "light.turn_on"; + data = { + entity_id = light; + brightness = halfbright; + }; + } + ]; + } + { + # state 1: half to full + conditions = { + condition = "template"; + value_template = ''{{ states('${light}') == 'on' and ( ${toString (halfbright - 1)} <= state_attr("${light}","brightness") <= ${toString (halfbright + 1)})}}''; + }; + sequence = [ + { + service = "light.turn_on"; + data = { + entity_id = light; + brightness = maxbright; + }; + } + ]; + } + { + # state 2: full to off + conditions = { + condition = "template"; + # TODO: it seems like the devices respond with brightness-1 , maybe off-by-one somewhere? + value_template = ''{{ states("${light}") == "on" and state_attr("${light}","brightness") >= ${toString (maxbright - 1)}}}''; + }; + sequence = [ + { + service = "light.turn_off"; + data = { + entity_id = light; + }; + } + ]; + } + ]; + # default: on to off + # this works because state 0 checks for "state == off" + default = [{ + service = "light.turn_off"; + data = { + entity_id = light; + }; + }]; + }; + } +; + rf_toggle = code: light: + { + alias = "Toggle ${light} via rf code ${code}"; + trigger = { + platform = "event"; + event_type = "esphome.rf_code_received"; + event_data.code = code; + }; + action = { + service = "light.toggle"; + data.entity_id = light; + }; + }; +in +{ + services.home-assistant.config.automation = [ + (rf_toggle "400551" "light.wohnzimmer_fernseher_led_strip") # A + (rf_state "401151" "light.wohnzimmer_stehlampe_osram" 128) # B + (rf_state "401451" "light.wohnzimmer_komode_osram" 128) # C + (rf_state "401511" "light.wohnzimmer_schrank_osram" 128) # D + + # OFF Lane + (rf_turn_off "400554" "all") # A + (rf_toggle "401154" "light.wohnzimmer_fenster_lichterkette_licht") # B + (rf_toggle "401454" "light.wohnzimmer_fernsehwand_led") # C + # (rf_toggle "401514" "") # D + ]; + # "400554" # A OFF + # "401154" # B OFF + # "401454" # C OFF + # "401514" # D OFF +} diff --git a/makefu/2configs/home/ham/calendar/nextcloud.nix b/makefu/2configs/home/ham/calendar/nextcloud.nix new file mode 100644 index 000000000..80e51b348 --- /dev/null +++ b/makefu/2configs/home/ham/calendar/nextcloud.nix @@ -0,0 +1,13 @@ +let + cred = import <secrets/ham/nextcloud-calendar>; +in +{ + services.home-assistant.config.calendar = + [ + { + platform = "caldav"; + inherit (cred) username password; + url = "https://o.euer.krebsco.de/remote.php/dav"; + } + ]; +} diff --git a/makefu/2configs/home/ham/default.nix b/makefu/2configs/home/ham/default.nix new file mode 100644 index 000000000..8ed5f8f3c --- /dev/null +++ b/makefu/2configs/home/ham/default.nix @@ -0,0 +1,198 @@ +{ pkgs, lib, config, ... }: + +# Ideas: +## wake-on-lan server +## +let + prefix = (import ./lib).prefix; + firetv_stick = "192.168.1.24"; + hassdir = "/var/lib/hass"; + unstable = import (pkgs.fetchFromGitHub { + owner = "nixos"; + repo = "nixpkgs"; + rev = (lib.importJSON ../../../krebs/nixpkgs-unstable.json).rev; + sha256 = (lib.importJSON ../../../krebs/nixpkgs-unstable.json).sha256; + }) {}; + + +in { + imports = [ + ./nginx.nix + ./mqtt.nix + ./zigbee2mqtt + ./signal-rest + + # hass config + ./zigbee2mqtt/hass.nix + # ./multi/flurlicht.nix + ./multi/kurzzeitwecker.nix + ./multi/the_playlist.nix + # ./multi/fliegen-couter.nix + + ./device_tracker/openwrt.nix + + ./sensor/outside.nix + + ./calendar/nextcloud.nix + + ./automation/fenster_auf.nix + ./automation/firetv_restart.nix + ./automation/light_buttons.nix + ./automation/wohnzimmer_rf_fernbedienung.nix + ./automation/giesskanne.nix + #./automation/urlaub.nix + ./automation/moodlight.nix + + ./light/arbeitszimmer.nix + ./light/schlafzimmer.nix + ./light/wohnzimmer.nix + ]; + + services.home-assistant = { + package = (unstable.home-assistant.overrideAttrs (old: { + doInstallCheck = false; + })).override { + extraPackages = p: [ + (p.callPackage ./deps/dwdwfsapi.nix {}) + (p.callPackage ./deps/pykodi.nix {}) + p.APScheduler ]; + }; + + config = { + influxdb = { + database = "ham"; + host = "localhost"; + tags = { + instance = "omo"; + source = "hass"; + }; + }; + + config = {}; + homeassistant = { + name = "Home"; time_zone = "Europe/Berlin"; + latitude = "48.7687"; + longitude = "9.2478"; + elevation = 247; + auth_providers = [ + { type = "trusted_networks"; + trusted_networks = [ "192.168.1.0/24" ]; + allow_bypass_login = true; + } + { type = "homeassistant"; } + ]; + }; + discovery = {}; + conversation = {}; + history = {}; + logbook = {}; + logger = { + default = "info"; + }; + rest_command = {}; + tts = [ + { platform = "google_translate"; + language = "de"; + time_memory = 57600; + service_name = "google_say"; + } + ]; + api = {}; + esphome = {}; + camera = []; + #telegram_bot = [ + # # secrets file: { + # # "platform": "broadcast", + # # "api_key": "", # talk to Botfather /newbot + # # "allowed_chat_ids": [ ID ] # curl -X GET # https://api.telegram.org/bot<YOUR_API_TOKEN>/getUpdates + # # } + # (builtins.fromJSON + # (builtins.readFile <secrets/hass/telegram-bot.json>)) + #]; + notify = [ + { + platform = "kodi"; + name = "Kodi Wohnzimmer"; + host = firetv_stick; + } + { + platform = "nfandroidtv"; + name = "FireTV Wohnzimmer"; + host = firetv_stick; + } + #{ + # platform = "telegram"; + # name = "telegrambot"; + # chat_id = builtins.elemAt + # (builtins.fromJSON (builtins.readFile + # <secrets/hass/telegram-bot.json>)).allowed_chat_ids 0; + #} + ]; + sun.elevation = 247; + recorder = {}; + media_player = [ + { platform = "kodi"; + name = "FireTV Stick kodi"; + host = firetv_stick; + } + { platform = "androidtv"; + name = "FireTV Stick"; + device_class = "firetv"; + # adb_server_ip = firetv_stick; + host = firetv_stick; + port = 5555; + } + ]; + mqtt = { + broker = "localhost"; + discovery = true; #enable esphome discovery + discovery_prefix = "homeassistant"; + port = 1883; + client_id = "home-assistant"; + username = "hass"; + password = lib.removeSuffix "\n" (builtins.readFile <secrets/mqtt/hass>); + keepalive = 60; + protocol = 3.1; + birth_message = { + topic = "${prefix}/hass/tele/LWT"; + payload = "Online"; + qos = 1; + retain = true; + }; + will_message = { + topic = "${prefix}/hass/tele/LWT"; + payload = "Offline"; + qos = 1; + retain = true; + }; + }; + luftdaten = { + show_on_map = true; + sensor_id = 10529; + sensors.monitored_conditions = [ "P1" "P2" ]; + }; + #binary_sensor = + # flurlicht.binary_sensor; + sensor = [ + { platform = "speedtest"; + monitored_conditions = [ "ping" "download" "upload" ]; + } + # https://www.home-assistant.io/cookbook/automation_for_rainy_days/ + ]; + frontend = { }; + http = { + use_x_forwarded_for = true; + server_host = "127.0.0.1"; + trusted_proxies = [ "127.0.0.1" ]; + #trusted_proxies = [ "192.168.1.0/24" ]; + }; + switch = []; + automation = []; + script = { }; + }; + enable = true; + configDir = hassdir; + }; + + state = [ "/var/lib/hass/known_devices.yaml" ]; +} diff --git a/makefu/2configs/home/ham/deps/dwdwfsapi.nix b/makefu/2configs/home/ham/deps/dwdwfsapi.nix new file mode 100644 index 000000000..d59dfa9e8 --- /dev/null +++ b/makefu/2configs/home/ham/deps/dwdwfsapi.nix @@ -0,0 +1,38 @@ +{ lib +, buildPythonPackage +, fetchPypi +, requests +, ciso8601 +, urllib3 +}: + +buildPythonPackage rec { + pname = "dwdwfsapi"; + version = "1.0.3"; + + disabled = false; # requires python version >=3.6 + + src = fetchPypi { + inherit pname version; + sha256 = "3d7d5bd66b1a647f07295068dc653b4ceafc2e8ec834b8e32419031c7b3a9b39"; + }; + + # # Package conditions to handle + # # might have to sed setup.py and egg.info in patchPhase + # # sed -i "s/<package>.../<package>/" + # requests>=2.23.0,<3 + # ciso8601>=2.1.3,<3 + # urllib3>=1.25.8,<2 + propagatedBuildInputs = [ + requests + ciso8601 + urllib3 + ]; + + meta = with lib; { + description = "Python client to retrieve data provided by DWD via their geoserver WFS API"; + homepage = https://github.com/stephan192/dwdwfsapi; + license = licenses.mit; + # maintainers = [ maintainers. ]; + }; +} diff --git a/makefu/2configs/home/ham/deps/pykodi.nix b/makefu/2configs/home/ham/deps/pykodi.nix new file mode 100644 index 000000000..85a541f8a --- /dev/null +++ b/makefu/2configs/home/ham/deps/pykodi.nix @@ -0,0 +1,37 @@ +{ lib +, buildPythonPackage +, fetchPypi +, jsonrpc-async +, jsonrpc-websocket +, aiohttp +}: + +buildPythonPackage rec { + pname = "pykodi"; + version = "0.2.2"; + + disabled = false; # requires python version >=3.7.0 + + src = fetchPypi { + inherit pname version; + sha256 = "43e7036a00a76f65c34dc5e7f1065a3ef071eea7619c2e6228e521b638e640bc"; + }; + + # # Package conditions to handle + # # might have to sed setup.py and egg.info in patchPhase + # # sed -i "s/<package>.../<package>/" + # jsonrpc-async>=1.1.0 + # jsonrpc-websocket>=1.2.1 + propagatedBuildInputs = [ + jsonrpc-async + jsonrpc-websocket + aiohttp + ]; + + meta = with lib; { + description = "An async python interface for Kodi over JSON-RPC"; + homepage = https://github.com/OnFreund/PyKodi; + license = licenses.mit; + # maintainers = [ maintainers. ]; + }; +} diff --git a/makefu/2configs/home/ham/device_tracker/openwrt.nix b/makefu/2configs/home/ham/device_tracker/openwrt.nix new file mode 100644 index 000000000..0a34f702a --- /dev/null +++ b/makefu/2configs/home/ham/device_tracker/openwrt.nix @@ -0,0 +1,13 @@ +{ + services.home-assistant.config.device_tracker = + [ + { platform = "luci"; + host = "192.168.1.5"; + username = "root"; + password = import <secrets/hass/router.nix>; + interval_seconds = 30; # instead of 12seconds + consider_home = 300; # 5 minutes timeout + new_device_defaults.track_new_devices = true; + } + ]; +} diff --git a/makefu/2configs/home/ham/lib/default.nix b/makefu/2configs/home/ham/lib/default.nix new file mode 100644 index 000000000..45c86138b --- /dev/null +++ b/makefu/2configs/home/ham/lib/default.nix @@ -0,0 +1,44 @@ +let + prefix = "/ham"; +in +{ + inherit prefix; + say = let + # returns a list of actions to be performed on an mpd to say something + tts = { message, entity }: + [ + { + service = "media_player.turn_on"; + data.entity_id = entity; + } + { + service = "media_player.play_media"; + data = { + entity_id = entity; + media_content_type = "playlist"; + media_content_id = "ansage"; + }; + } + { + service = "media_player.turn_on"; + data.entity_id = entity; + } + { delay.seconds = 8; } + { + service = "tts.say"; + entity_id = entity; + data_template = { + inherit message; + language = "de"; + }; + } + ]; + in + { + firetv = message: tts { + inherit message; + entity = "firetv"; + }; + }; + zigbee.prefix = "/ham/zigbee"; +} diff --git a/makefu/2configs/home/ham/light/arbeitszimmer.nix b/makefu/2configs/home/ham/light/arbeitszimmer.nix new file mode 100644 index 000000000..bc60678b3 --- /dev/null +++ b/makefu/2configs/home/ham/light/arbeitszimmer.nix @@ -0,0 +1,24 @@ +let + arbeitszimmer_deko = [ + "light.led_wand" + "light.box_led_status" + "light.arbeitszimmer_led1_led_strip" # LED-Kreis in cube + ]; + arbeitszimmerbeleuchtung = [ + "light.arbeitszimmer_schrank_dimmer" + "light.arbeitszimmer_kerze" # arbeitszimmer_kerze + ]; +in { + services.home-assistant.config.light = [ + { + platform = "group"; + name = "Arbeitszimmerbeleuchtung"; + entities = arbeitszimmerbeleuchtung; + } + { + platform = "group"; + name = "Arbeitszimmer Deko"; + entities = arbeitszimmer_deko; + } + ]; +} diff --git a/makefu/2configs/home/ham/light/schlafzimmer.nix b/makefu/2configs/home/ham/light/schlafzimmer.nix new file mode 100644 index 000000000..e5370e3f8 --- /dev/null +++ b/makefu/2configs/home/ham/light/schlafzimmer.nix @@ -0,0 +1,14 @@ +let + schlafzimmer_licht = [ + "light.schlafzimmer_komode_osram" + # "light.schlafzimmer_schrank_osram" + ]; +in { + services.home-assistant.config.light = [ + { + platform = "group"; + name = "Schlafzimmerbeleuchtung"; + entities = schlafzimmer_licht; + } + ]; +} diff --git a/make |