From e2fcbd0919015085b310d72198fb2e0250b5d1cd Mon Sep 17 00:00:00 2001 From: makefu Date: Wed, 15 Jan 2020 09:11:03 +0100 Subject: shack/muellshack: bump to latest master adds new static data for 2020 --- krebs/2configs/shack/muellshack.nix | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/krebs/2configs/shack/muellshack.nix b/krebs/2configs/shack/muellshack.nix index c67d8f52..e894b939 100644 --- a/krebs/2configs/shack/muellshack.nix +++ b/krebs/2configs/shack/muellshack.nix @@ -4,8 +4,9 @@ let pkg = pkgs.callPackage ( pkgs.fetchgit { url = "https://git.shackspace.de/rz/muellshack"; - rev = "c3d1f70325e5b90f280c5be60110e14f4de653ae"; - sha256 = "1dd4kqwdr4v413rmkvmyjzzvw8id9747nifp96pg0c2cy6bhzj24"; + rev = "dc80cf1edaa3d86ec2bebae8596ad1d4c4e3650a"; + sha256 = "1yipr66zhrg5m20pf3rzvgvvl78an6ddkq6zc45rxb2r0i7ipkyh"; + }) { mkYarnPackage = pkgs.yarn2nix-moretea.mkYarnPackage; }; home = "/var/lib/muellshack"; port = "8081"; -- cgit v1.2.3 From 6508c853da3596b701aa00e99a5260d31ebeaa24 Mon Sep 17 00:00:00 2001 From: makefu Date: Thu, 23 Jan 2020 23:51:05 +0100 Subject: shack/glados: schlechte_luft add rz --- krebs/2configs/shack/glados/multi/schlechte_luft.nix | 5 +++++ makefu/2configs/default.nix | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/krebs/2configs/shack/glados/multi/schlechte_luft.nix b/krebs/2configs/shack/glados/multi/schlechte_luft.nix index 9cd2c56f..4625f684 100644 --- a/krebs/2configs/shack/glados/multi/schlechte_luft.nix +++ b/krebs/2configs/shack/glados/multi/schlechte_luft.nix @@ -15,6 +15,11 @@ in (glados.esphome.temp { host = "fablab_feinstaub";}) (glados.esphome.dust_25m { host = "fablab_feinstaub";}) (glados.esphome.dust_100m { host = "fablab_feinstaub";}) + + (glados.esphome.temp { host = "rz_feinstaub";}) + (glados.esphome.hum { host = "rz_feinstaub";}) + (glados.esphome.dust_25m { host = "rz_feinstaub";}) + (glados.esphome.dust_100m { host = "rz_feinstaub";}) ]; automation = [ diff --git a/makefu/2configs/default.nix b/makefu/2configs/default.nix index 5faf3ce9..0cbb5efe 100644 --- a/makefu/2configs/default.nix +++ b/makefu/2configs/default.nix @@ -28,6 +28,7 @@ with import ; openssh.authorizedKeys.keys = [ config.krebs.users.makefu.pubkey ]; }; }; + nix.trustedUsers = [ config.krebs.build.user.name ]; boot.kernelPackages = lib.mkDefault pkgs.linuxPackages_latest; @@ -41,8 +42,6 @@ with import ; }; - - boot.tmpOnTmpfs = true; systemd.tmpfiles.rules = [ "d /tmp 1777 root root - -" @@ -61,7 +60,7 @@ with import ; environment.shellAliases = { # TODO: see .aliases lsl = "ls -lAtr"; - dmesg = "journalctl -kb | cat"; + dmesg = "dmesg -L --reltime"; psg = "ps -ef | grep"; nmap = "nmap -oN $HOME/loot/scan-`date +\%s`.nmap -oX $HOME/loot/scan-`date +%s`.xml"; grep = "grep --color=auto"; -- cgit v1.2.3 From c12411d79f21f6e462251d02485c8b2a139cb93e Mon Sep 17 00:00:00 2001 From: makefu Date: Thu, 23 Jan 2020 23:52:39 +0100 Subject: shack/glados: add shack-startup --- .../shack/glados/automation/hass-restart.nix | 3 +- .../shack/glados/automation/shack-startup.nix | 82 ++++++++++++++++++++++ krebs/2configs/shack/glados/default.nix | 13 +++- krebs/2configs/shack/glados/lib/default.nix | 40 +++++++++++ 4 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 krebs/2configs/shack/glados/automation/shack-startup.nix diff --git a/krebs/2configs/shack/glados/automation/hass-restart.nix b/krebs/2configs/shack/glados/automation/hass-restart.nix index e8735497..1b380204 100644 --- a/krebs/2configs/shack/glados/automation/hass-restart.nix +++ b/krebs/2configs/shack/glados/automation/hass-restart.nix @@ -6,12 +6,13 @@ platform = "homeassistant"; event = "start"; }; + # trigger good/bad air action = [ { service = "light.turn_on"; data = { entity_id = "light.fablab_led"; effect = "Rainbow"; - color_name = "yellow"; + color_name = "purple"; }; } ]; diff --git a/krebs/2configs/shack/glados/automation/shack-startup.nix b/krebs/2configs/shack/glados/automation/shack-startup.nix new file mode 100644 index 00000000..10051d60 --- /dev/null +++ b/krebs/2configs/shack/glados/automation/shack-startup.nix @@ -0,0 +1,82 @@ +# needs: +# binary_sensor.portal_lock +# sensor.keyholder +# media_player.lounge +let + glados = import ../lib; +in +[ + { + alias = "Greet new keyholder for key exchange"; + initial_state = true; + trigger = { + platform = "state"; + entity_id = "sensor.keyholder"; + }; + condition = { + condition = "template"; + value_template = "{{ trigger.from_state.state != 'No Keyholder' }}"; + }; + #action = glados.say.lounge "Danke {{trigger.to_state.state}} für das Übernehmen des Keys von {{trigger.from_state.state}}"; + action = []; + } + + { + alias = "Start Music on portal lock on"; + # TODO: use "power" trigger + trigger = { + platform = "state"; + entity_id = "binary_sensor.portal_lock"; + to = "on"; + for.seconds = 30; + }; + condition = { + condition = "and"; + conditions = + [ + { # only start if a keyholder opened the door and if the lounge mpd is currently not playing anything + condition = "template"; + value_template = "{{ state('sensor.keyholder') != 'No Keyholder' }}"; + } + { + condition = "state"; + entity_id = "media_player.lounge"; + state = "idle"; + } + ]; + }; + action = [ + { + service = "media_player.volume_set"; + data = { + entity_id = "media_player.lounge"; + volume_level = 1.0; + }; + } + { + service = "media_player.play_media"; + data = { + entity_id = "media_player.lounge"; + media_content_type = "playlist"; + media_content_id = "ansage"; + }; + } + { delay.seconds = 8; } + { + service = "media_player.volume_set"; + data = { + entity_id = "media_player.lounge"; + volume_level = 0.6; + }; + } + { + service = "media_player.play_media"; + data = { + entity_id = "media_player.lounge"; + media_content_type = "playlist"; + media_content_id = "lassulus superradio"; + }; + } + ]; + } +] diff --git a/krebs/2configs/shack/glados/default.nix b/krebs/2configs/shack/glados/default.nix index e48a5455..ef22ccb0 100644 --- a/krebs/2configs/shack/glados/default.nix +++ b/krebs/2configs/shack/glados/default.nix @@ -93,6 +93,7 @@ in { light = badair.light; media_player = [ { platform = "mpd"; + name = "lounge"; host = "lounge.mpd.shack"; } ]; @@ -117,19 +118,27 @@ in { #conversation = {}; history = {}; logbook = {}; + logger = { + default = "info"; + }; recorder = {}; tts = [ { platform = "google_translate"; + service_name = "say"; language = "de"; + cache = true; + time_memory = 57600; } #{ platform = "picotts"; # language = "de-DE"; + # service_name = "say"; #} ]; sun = {}; - automation = wasser.automation - ++ badair.automation + automation = wasser.automation + ++ badair.automation + ++ (import ./automation/shack-startup.nix) ++ (import ./automation/hass-restart.nix); device_tracker = []; diff --git a/krebs/2configs/shack/glados/lib/default.nix b/krebs/2configs/shack/glados/lib/default.nix index 6737af84..16cbc683 100644 --- a/krebs/2configs/shack/glados/lib/default.nix +++ b/krebs/2configs/shack/glados/lib/default.nix @@ -2,6 +2,46 @@ let prefix = "glados"; in { + + 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 = "media_player.lounge"; + } + { service = "media_player.play_media"; + data = { + entity_id = "media_player.lounge"; + media_content_type = "playlist"; + media_content_id = "ansage"; + }; + } + { + service = "media_player.turn_on"; + data.entity_id = "media_player.lounge"; + } + { delay.seconds = 8; } + { service = "tts.say"; + entity_id = "media_player.lounge"; + data_template = { + inherit message; + language = "de"; + }; + } + ]; + in + { + lounge = message: tts { + inherit message; + entity = "lounge"; + }; + herrenklo = message: tts { + inherit message; + entity = "herrenklo"; + }; + }; esphome = { temp = {host, topic ? "temperature" }: -- cgit v1.2.3 From e38f61c7ff54031d5f48e57b96eff0062feb99b2 Mon Sep 17 00:00:00 2001 From: makefu Date: Thu, 30 Jan 2020 08:12:24 +0100 Subject: ma: update omo pubkey --- krebs/3modules/makefu/sshd/omo.pub | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/krebs/3modules/makefu/sshd/omo.pub b/krebs/3modules/makefu/sshd/omo.pub index 63bbbc70..5b943541 100644 --- a/krebs/3modules/makefu/sshd/omo.pub +++ b/krebs/3modules/makefu/sshd/omo.pub @@ -1 +1 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPTBGboU/P00yYiwYje53G0oqDFWmcSJ+hIpMsl4f/HH +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIujMZ3ZFxKpWeB/cjfKfYRr77+VRZk0Eik+92t03NoA -- cgit v1.2.3 From 89032b3ac2aff2373377ef442804e90db9694c91 Mon Sep 17 00:00:00 2001 From: makefu Date: Tue, 4 Feb 2020 18:26:59 +0100 Subject: ma homeautomation: init with zigbee --- makefu/2configs/homeautomation/default.nix | 224 +++++---------- makefu/2configs/homeautomation/lib/default.nix | 318 +++++++++++++++++++++ makefu/2configs/homeautomation/multi/timer.nix | 123 ++++++++ .../2configs/homeautomation/multi/zigbee2mqtt.nix | 165 +++++++++++ makefu/2configs/homeautomation/sensor/outside.nix | 26 ++ 5 files changed, 704 insertions(+), 152 deletions(-) create mode 100644 makefu/2configs/homeautomation/lib/default.nix create mode 100644 makefu/2configs/homeautomation/multi/timer.nix create mode 100644 makefu/2configs/homeautomation/multi/zigbee2mqtt.nix create mode 100644 makefu/2configs/homeautomation/sensor/outside.nix diff --git a/makefu/2configs/homeautomation/default.nix b/makefu/2configs/homeautomation/default.nix index 4e9ac0ee..56acc2d0 100644 --- a/makefu/2configs/homeautomation/default.nix +++ b/makefu/2configs/homeautomation/default.nix @@ -2,106 +2,21 @@ # Ideas: ## wake-on-lan server -## +## let - tasmota_rgb = name: topic: -# LED WS2812b -# effect_state_topic: "stat/led/Scheme" -# effect_command_topic: "cmnd/led/Scheme" -# effect_value_template: "{{ value_json.Scheme }}" - { platform = "mqtt"; - inherit name; - retain = false; - qos = 1; - optimistic = false; - # state - # TODO: currently broken, will not use the custom state topic - #state_topic = "/ham/${topic}/stat/POWER"; - state_topic = "/ham/${topic}/stat/POWER"; - command_topic = "/ham/${topic}/cmnd/POWER"; - availability_topic = "/ham/${topic}/tele/LWT"; - payload_on= "ON"; - payload_off= "OFF"; - payload_available= "Online"; - payload_not_available= "Offline"; - # brightness - brightness_state_topic = "/ham/${topic}/stat/Dimmer"; - brightness_command_topic = "/ham/${topic}/cmnd/Dimmer"; - brightness_value_template = "{{ value_json.Dimmer }}"; - brightness_scale = 100; - # color - rgb_state_topic = "/ham/${topic}/stat/Color"; - rgb_command_topic = "/ham/${topic}/cmnd/MEM1"; # use enabled tasmota rule - rgb_command_mode = "hex"; - rgb_command_template = "{{ '%02x%02x%02x' | format(red, green, blue)}}"; - # effects - effect_state_topic = "/ham/${topic}/stat/Scheme"; - effect_command_topic = "/ham/${topic}/cmnd/Scheme"; - effect_value_template = "{{ value_json.Scheme }}"; - effect_list = [ 0 1 2 3 4 5 6 7 8 9 10 11 12 ]; -}; - # switchmode 1 - also toggle power - # switchtopic flurlicht - tasmota_motion = name: topic: - { platform = "mqtt"; - device_class = "motion"; - inherit name; - # TODO: currently broken, will not use the custom state topic - state_topic = "/ham/${topic}/stat/POWER"; - payload_on = "ON"; - payload_off = "OFF"; - availability_topic = "/ham/${topic}/tele/LWT"; - payload_available = "Online"; - payload_not_available = "Offline"; - }; - + hlib = (import ./lib); + prefix = hlib.prefix; + tasmota = hlib.tasmota; firetv = "192.168.1.183"; + kodi-host = firetv; hassdir = "/var/lib/hass"; - tasmota_plug = name: topic: - { platform = "mqtt"; - inherit name; - state_topic = "/ham/${topic}/stat/POWER1"; - command_topic = "/ham/${topic}/cmnd/POWER1"; - availability_topic = "/ham/${topic}/tele/LWT"; - payload_on= "ON"; - payload_off= "OFF"; - payload_available= "Online"; - payload_not_available= "Offline"; - }; - tasmota_bme = name: topic: - [ { platform = "mqtt"; - name = "${name} Temperatur"; - state_topic = "/ham/${topic}/tele/SENSOR"; - value_template = "{{ value_json.BME280.Temperature }}"; - unit_of_measurement = "°C"; - } - { platform = "mqtt"; - name = "${name} Luftfeuchtigkeit"; - state_topic = "/ham/${topic}/tele/SENSOR"; - value_template = "{{ value_json.BME280.Humidity }}"; - unit_of_measurement = "%"; - } - { platform = "mqtt"; - name = "${name} Luftdruck"; - state_topic = "/ham/${topic}/tele/SENSOR"; - value_template = "{{ value_json.BME280.Pressure }}"; - unit_of_measurement = "hPa"; - } - ]; - tasmota_am2301 = name: topic: - [ { platform = "mqtt"; - name = "${name} Temperatur"; - state_topic = "/ham/${topic}/tele/SENSOR"; - value_template = "{{ value_json.AM2301.Temperature }}"; - unit_of_measurement = "°C"; - } - { platform = "mqtt"; - name = "${name} Luftfeuchtigkeit"; - state_topic = "/ham/${topic}/tele/SENSOR"; - value_template = "{{ value_json.AM2301.Humidity }}"; - unit_of_measurement = "%"; - } - ]; + zigbee = import ./multi/zigbee2mqtt.nix; +# switch +# automation +# binary_sensor +# sensor +# input_select +# timer in { imports = [ ./mqtt.nix @@ -109,6 +24,8 @@ in { services.home-assistant = { config = { + input_select = zigbee.input_select; # dict + timer = zigbee.timer; # dict homeassistant = { name = "Home"; time_zone = "Europe/Berlin"; latitude = "48.7687"; @@ -120,8 +37,36 @@ in { history = {}; logbook = {}; tts = [ - { platform = "google";} + { platform = "google_translate"; + language = "de"; + time_memory = 57600; + service_name = "google_say"; + } ]; + + telegram_bot = [ + # secrets file: { + # "platform": "broadcast", + # "api_key": "", # talk to Botfather /newbot + # "allowed_chat_ids": [ ID ] # curl -X GET # https://api.telegram.org/bot/getUpdates + #} + (builtins.fromJSON + (builtins.readFile )) + ]; + notify = [ + { + platform = "kodi"; + name = "wohnzimmer"; + host = kodi-host; + } + { + platform = "telegram"; + name = "telegrambot"; + chat_id = builtins.elemAt + (builtins.fromJSON (builtins.readFile + )).allowed_chat_ids 0; + } + ]; sun.elevation = 247; recorder = {}; media_player = [ @@ -143,56 +88,32 @@ in { keepalive = 60; protocol = 3.1; birth_message = { - topic = "/ham/hass/tele/LWT"; + topic = "${prefix}/hass/tele/LWT"; payload = "Online"; qos = 1; retain = true; }; will_message = { - topic = "/ham/hass/tele/LWT"; + topic = "${prefix}/hass/tele/LWT"; payload = "Offline"; qos = 1; retain = true; }; }; binary_sensor = [ - (tasmota_motion "Flur Bewegung" "flurlicht") - ]; + (tasmota.motion { name = "Flur Bewegung"; host = "flurlicht";}) + ] ++ zigbee.binary_sensor; sensor = [ # broken #{ platform = "speedtest"; # monitored_conditions = [ "ping" "download" "upload" ]; #} - { platform = "luftdaten"; - name = "Wangen"; - sensorid = "663"; - monitored_conditions = [ "P1" "P2" ]; - } # https://www.home-assistant.io/cookbook/automation_for_rainy_days/ - { platform = "darksky"; - api_key = lib.removeSuffix "\n" - (builtins.readFile ); - language = "de"; - monitored_conditions = [ "summary" "icon" - "nearest_storm_distance" "precip_probability" - "precip_intensity" - "temperature" - "apparent_temperature" - "hourly_summary" - "humidity" - "pressure" - "uv_index" ]; - units = "si" ; - update_interval = { - days = 0; - hours = 0; - minutes = 30; - seconds = 0; - }; - } ] - ++ (tasmota_bme "Schlafzimmer" "schlafzimmer") - ++ (tasmota_am2301 "Arbeitszimmer" "arbeitszimmer"); + ++ ((import ./sensor/outside.nix) {inherit lib;}) + ++ zigbee.sensor + ++ (tasmota.bme { name = "Schlafzimmer"; host = "schlafzimmer";}) + ++ (tasmota.am2301 { name= "Arbeitszimmer" ; host = "arbeitszimmer"; }); frontend = { }; group = { default_view = @@ -218,8 +139,10 @@ in { draussen = [ "sensor.dark_sky_temperature" "sensor.dark_sky_hourly_summary" - "sensor.wangen_pm10" - "sensor.wangen_pm25" + "sensor.dark_sky_humidity" + "sensor.dark_sky_pressure" + "sensor.muehlhausen_pm10" + "sensor.muehlhausen_pm25" ]; schlafzimmer = [ "sensor.schlafzimmer_temperatur" @@ -235,10 +158,10 @@ in { }; http = { }; switch = [ - (tasmota_plug "Lichterkette Schlafzimmer" "schlafzimmer") - (tasmota_plug "Strom Staubsauger" "arbeitszimmer") - ]; - light = [ (tasmota_rgb "Flurlicht" "flurlicht" ) ]; + (tasmota.plug { name = "Lichterkette Schlafzimmer"; host = "schlafzimmer";}) + (tasmota.plug { name = "Strom Staubsauger"; host = "arbeitszimmer"; } ) + ] ++ zigbee.switch; + light = [ (tasmota.rgb { name = "Flurlicht"; host = "flurlicht";} ) ]; automation = [ { alias = "Dunkel bei Sonnenuntergang"; trigger = { @@ -281,25 +204,22 @@ in { } ]; } - { alias = "Staubsauger Strom aus nach 6h"; - trigger = { - platform = "state"; - entity_id = "switch.strom_staubsauger"; - to = "on"; - for.hours = 6; - }; - action = { - service= "homeassistant.turn_off"; - entity_id= "switch.strom_staubsauger"; - }; - } - ]; + #{ alias = "Staubsauger Strom aus nach 6h"; + # trigger = { + # platform = "state"; + # entity_id = "switch.strom_staubsauger"; + # to = "on"; + # for.hours = 6; + # }; + # action = { + # service= "homeassistant.turn_off"; + # entity_id= "switch.strom_staubsauger"; + # }; + #} + ] ++ zigbee.automation; }; enable = true; configDir = hassdir; }; - nixpkgs.config.permittedInsecurePackages = [ - "homeassistant-0.77.2" - ]; } diff --git a/makefu/2configs/homeautomation/lib/default.nix b/makefu/2configs/homeautomation/lib/default.nix new file mode 100644 index 00000000..8bc54431 --- /dev/null +++ b/makefu/2configs/homeautomation/lib/default.nix @@ -0,0 +1,318 @@ +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 = let + prefix = "/ham/zigbee"; + in + { + inherit prefix; + state = name: { + platform = "mqtt"; + name = "zigbee ${name} connectivity"; + state_topic = "${prefix}/${name}"; + availability_topic = "${prefix}/bridge/state"; + payload_on = true; + payload_off = false; + value_template = "{{ value_json.state }}"; + device_class = "connectivity"; + }; + battery = name: { + platform = "mqtt"; + name = "zigbee ${name} battery"; + state_topic = "${prefix}/${name}"; + availability_topic = "${prefix}/bridge/state"; + unit_of_measurement = "%"; + device_class = "battery"; + value_template = "{{ value_json.battery }}"; + }; + linkquality = name: { + platform = "mqtt"; + name = "zigbee ${name} linkquality"; + state_topic = "${prefix}/${name}"; + availability_topic = "${prefix}/bridge/state"; + unit_of_measurement = "-"; + value_template = "{{ value_json.linkquality }}"; + }; + temperature = name: { + platform = "mqtt"; + name = "zigbee ${name} temperature"; + state_topic = "${prefix}/${name}"; + availability_topic = "${prefix}/bridge/state"; + unit_of_measurement = "°C"; + device_class = "temperature"; + value_template = "{{ value_json.temperature }}"; + }; + humidity = name: { + platform = "mqtt"; + name = "zigbee ${name} humidity"; + state_topic = "${prefix}/${name}"; + availability_topic = "${prefix}/bridge/state"; + unit_of_measurement = "%"; + device_class = "humidity"; + value_template = "{{ value_json.humidity }}"; + }; + pressure = name: { + platform = "mqtt"; + state_topic = "${prefix}/${name}"; + name = "zigbee ${name} pressure"; + availability_topic = "${prefix}/bridge/state"; + unit_of_measurement = "hPa"; + device_class = "pressure"; + value_template = "{{ value_json.pressure }}" ; + }; + click = name: + { + platform = "mqtt"; + name = "zigbee ${name} click"; + state_topic = "${prefix}/${name}"; + availability_topic = "${prefix}/bridge/state"; + icon = "mdi:toggle-switch"; + value_template = "{{ value_json.click }}"; + }; + contact = name: { + platform = "mqtt"; + name = "zigbee ${name} contact"; + state_topic = "${prefix}/${name}"; + availability_topic = "${prefix}/bridge/state"; + payload_on = false; + payload_off = true; + value_template = "{{ value_json.contact }}"; + device_class = "door"; + }; + }; + esphome = + { + temp = {host, topic ? "temperature" }: + { + platform = "mqtt"; + name = "${host} Temperature"; + device_class = "temperature"; + unit_of_measurement = "°C"; + icon = "mdi:thermometer"; + state_topic = "${prefix}/${host}/sensor/${topic}/state"; + availability_topic = "${prefix}/${host}/status"; + payload_available = "online"; + payload_not_available = "offline"; + }; + hum = {host, topic ? "humidity" }: + { + platform = "mqtt"; + unit_of_measurement = "%"; + icon = "mdi:water-percent"; + device_class = "humidity"; + name = "${host} Humidity"; + state_topic = "${prefix}/${host}/sensor/${topic}/state"; + availability_topic = "${prefix}/${host}/status"; + payload_available = "online"; + payload_not_available = "offline"; + }; + # copied from "homeassistant/light/fablab_led/led_ring/config" + led = {host, topic ? "led", name ? host}: + { # name: fablab_led + # topic: led_ring + platform = "mqtt"; + inherit name; + schema = "json"; + brightness = true; + rgb = true; + effect = true; + effect_list = [ # TODO: may be different + "Random" + "Strobe" + "Rainbow" + "Color Wipe" + "Scan" + "Twinkle" + "Fireworks" + "Addressable Flicker" + "None" + ]; + state_topic = "${prefix}/${host}/light/${topic}/state"; + command_topic = "${prefix}/${host}/light/${topic}/command"; + availability_topic = "${prefix}/${host}/status"; + payload_available = "online"; + payload_not_available = "offline"; + qos = 1; + }; + # Feinstaub + dust_25m = { host, name ? "${host} < 2.5µm", topic ? "particulate_matter_25m_concentration" }: + { + platform = "mqtt"; + unit_of_measurement = "µg/m³"; + icon = "mdi:chemical-weapon"; + inherit name; + state_topic = "${prefix}/${host}/sensor/${topic}/state"; + availability_topic = "${prefix}/${host}/status"; + }; + dust_100m = {host, name ? "${host} < 10µm", topic ? "particulate_matter_100m_concentration" }: + { + platform = "mqtt"; + unit_of_measurement = "µg/m³"; + icon = "mdi:chemical-weapon"; + inherit name; + state_topic = "${prefix}/${host}/sensor/${topic}/state"; + availability_topic = "${prefix}/${host}/status"; + }; + ip = {host, name ? "${host} IP", topic ? "ip_address" }: + { + platform = "mqtt"; + inherit name; + state_topic = "${prefix}/${host}/sensor/${topic}/state"; + availability_topic = "${prefix}/${host}/status"; + }; + wifi = {host, name ? "${host} Wifi Signal", topic ? "wifi_signal" }: + { + platform = "mqtt"; + unit_of_measurement = "dB"; + icon = "mdi:wifi"; + inherit name; + state_topic = "${prefix}/${host}/sensor/${topic}/state"; + availability_topic = "${prefix}/${host}/status"; + }; + switch = {host, name ? "${host} Button", topic ? "btn" }: + # host: ampel + # name: Button 1 + # topic: btn1 + { + inherit name; + platform = "mqtt"; + state_topic = "${prefix}/${host}/sensor/${topic}/state"; + command_topic = "${prefix}/${host}/switch/${topic}/state"; + availability_topic = "${prefix}/${host}/status"; + }; + }; + tasmota = + { + plug = {host, name ? host, topic ? host}: + { + platform = "mqtt"; + inherit name; + state_topic = "sonoff/stat/${topic}/POWER1"; + command_topic = "sonoff/cmnd/${topic}/POWER1"; + availability_topic = "sonoff/tele/${topic}/LWT"; + payload_on= "ON"; + payload_off= "OFF"; + payload_available= "Online"; + payload_not_available= "Offline"; + retain = false; + qos = 1; + }; + am2301 = { name, host, topic?host }: + [ { platform = "mqtt"; + name = "${name} Temperatur"; + state_topic = "${prefix}/${topic}/tele/SENSOR"; + value_template = "{{ value_json.AM2301.Temperature }}"; + unit_of_measurement = "°C"; + } + { platform = "mqtt"; + name = "${name} Luftfeuchtigkeit"; + state_topic = "${prefix}/${topic}/tele/SENSOR"; + value_template = "{{ value_json.AM2301.Humidity }}"; + unit_of_measurement = "%"; + } + ]; + bme = { name, host, topic?host }: + [ { platform = "mqtt"; + name = "${name} Temperatur"; + state_topic = "${prefix}/${topic}/tele/SENSOR"; + value_template = "{{ value_json.BME280.Temperature }}"; + unit_of_measurement = "°C"; + } + { platform = "mqtt"; + name = "${name} Luftfeuchtigkeit"; + state_topic = "${prefix}/${topic}/tele/SENSOR"; + value_template = "{{ value_json.BME280.Humidity }}"; + unit_of_measurement = "%"; + } + { platform = "mqtt"; + name = "${name} Luftdruck"; + state_topic = "${prefix}/${topic}/tele/SENSOR"; + value_template = "{{ value_json.BME280.Pressure }}"; + unit_of_measurement = "hPa"; + } + ]; + rgb = { name, host, topic?host }: + { platform = "mqtt"; + inherit name; + retain = false; + qos = 1; + optimistic = false; + # state + # TODO: currently broken, will not use the custom state topic + #state_topic = "${prefix}/${topic}/stat/POWER"; + state_topic = "${prefix}/${topic}/stat/POWER"; + command_topic = "${prefix}/${topic}/cmnd/POWER"; + availability_topic = "${prefix}/${topic}/tele/LWT"; + payload_on= "ON"; + payload_off= "OFF"; + payload_available= "Online"; + payload_not_available= "Offline"; + # brightness + brightness_state_topic = "${prefix}/${topic}/stat/Dimmer"; + brightness_command_topic = "${prefix}/${topic}/cmnd/Dimmer"; + brightness_value_template = "{{ value_json.Dimmer }}"; + brightness_scale = 100; + # color + rgb_state_topic = "${prefix}/${topic}/stat/Color"; + rgb_command_topic = "${prefix}/${topic}/cmnd/MEM1"; # use enabled rule + rgb_command_mode = "hex"; + rgb_command_template = "{{ '%02x%02x%02x' | format(red, green, blue)}}"; + # effects + effect_state_topic = "${prefix}/${topic}/stat/Scheme"; + effect_command_topic = "${prefix}/${topic}/cmnd/Scheme"; + effect_value_template = "{{ value_json.Scheme }}"; + effect_list = [ 0 1 2 3 4 5 6 7 8 9 10 11 12 ]; +}; + motion = { name, host, topic?host }: + { platform = "mqtt"; + device_class = "motion"; + inherit name; + # TODO: currently broken, will not use the custom state topic + state_topic = "${prefix}/${topic}/stat/POWER"; + payload_on = "ON"; + payload_off = "OFF"; + availability_topic = "${prefix}/${topic}/tele/LWT"; + payload_available = "Online"; + payload_not_available = "Offline"; + }; + }; +} diff --git a/makefu/2configs/homeautomation/multi/timer.nix b/makefu/2configs/homeautomation/multi/timer.nix new file mode 100644 index 00000000..eafb7841 --- /dev/null +++ b/makefu/2configs/homeautomation/multi/timer.nix @@ -0,0 +1,123 @@ +# Provides: +# timer +# automation +# script + +# Needs: +# sensor.zigbee_btn1_click +# notify.telegrambot +let + button = "sensor.zigbee_btn1_click"; +in { + timer.kurzzeitwecker = + { + name = "Zigbee Kurzzeitwecker"; + duration = 300; + }; + script.add_5_minutes_to_kurzzeitwecker = + { + alias = "Add 5 minutes to kurzzeitwecker"; + sequence = [ + { service = "timer.pause"; + entity_id = "timer.kurzzeitwecker"; + } + { service = "timer.start"; + data_template = { + entity_id = "timer.kurzzeitwecker"; + duration = '' + {% set r = state_attr('timer.wecker', 'remaining') ~ '-0000' %} + {% set t = strptime(r, '%H:%M:%S.%f%z') %} + {{ (as_timestamp(t) + 300) | timestamp_custom('%H:%M:%S', false) }} + ''; + }; + } + ]; + }; + automation = + [ + { + alias = "Start Timer 5min"; + trigger = { + platform = "state"; + entity_id = button; + to = "single"; + }; + condition = + { condition = "state"; + entity_id = "timer.kurzzeitwecker"; + state = "idle"; + }; + + action = [ + { service = "timer.start"; + entity_id = "timer.kurzzeitwecker"; + duration = "00:05:00"; + } + { + service = "notify.telegrambot"; + data = { + title = "Timer gestartet"; + message = "Timer auf 5 minuten gestellt"; + }; + } + ]; + } + { + alias = "Start Timer 10min"; + trigger = { + platform = "state"; + entity_id = button; + to = "double"; + }; + condition = + { + condition = "state"; + entity_id = "timer.kurzzeitwecker"; + state = "idle"; + }; + action = + [ + { + service = "timer.start"; + entity_id = "timer.kurzzeitwecker"; + duration = "00:10:00"; + } + { + service = "notify.telegrambot"; + data = { + title = "Timer gestartet"; + message = "Timer auf 10 minuten gestellt"; + }; + } + ]; + } + { + alias = "Stop timer on triple click"; + trigger = + { + platform = "state"; + entity_id = button; + to = "triple"; + }; + condition = + { + condition = "state"; + entity_id = "timer.kurzzeitwecker"; + state = "active"; + }; + + action = [ + { + service = "timer.stop"; + entity_id = "timer.kurzzeitwecker"; + } + { + service = "notify.telegrambot"; + data = { + title = "Timer gestoppt"; + }; + } + ]; + } + ]; +} diff --git a/makefu/2configs/homeautomation/multi/zigbee2mqtt.nix b/makefu/2configs/homeautomation/multi/zigbee2mqtt.nix new file mode 100644 index 00000000..ba81b129 --- /dev/null +++ b/makefu/2configs/homeautomation/multi/zigbee2mqtt.nix @@ -0,0 +1,165 @@ +# provides: +# switch +# automation +# binary_sensor +# sensor +# input_select +# timer +let + inherit (import ../lib) zigbee; + prefix = zigbee.prefix; + xiaomi_btn = name: [ + (zigbee.battery name) + (zigbee.linkquality name) + (zigbee.click name) + ]; + xiaomi_temp = name: [ + (zigbee.battery name) + (zigbee.linkquality name) + (zigbee.temperature name) + (zigbee.humidity name) + (zigbee.pressure name) + ]; + xiaomi_contact = name: [ + (zigbee.battery name) + (zigbee.linkquality name) + (zigbee.contact name) + ]; + router_link = name: [ + (zigbee.linkquality name) + ]; + router_bin = name: [ + (zigbee.state name) + ]; +in { + sensor = + (xiaomi_btn "btn1") + ++ (xiaomi_btn "btn2") + ++ (xiaomi_btn "btn3") + + ++ (xiaomi_temp "temp1") + ++ (xiaomi_temp "temp2") + ++ (xiaomi_temp "temp3") + + ++ (router_link "router1") + ++ (router_link "router2") + + ++ [ + # Sensor for monitoring the bridge state + { + platform = "mqtt"; + name = "Zigbee2mqtt Bridge state"; + state_topic = "${prefix}/bridge/state"; + icon = "mdi:router-wireless"; + } + # Sensor for Showing the Zigbee2mqtt Version + { + platform = "mqtt"; + name = "Zigbee2mqtt Version"; + state_topic = "${prefix}/bridge/config"; + value_template = "{{ value_json.version }}"; + icon = "mdi:zigbee"; + } + # Sensor for Showing the Coordinator Version + { + platform = "mqtt"; + name = "Coordinator Version"; + state_topic = "${prefix}/bridge/config"; + value_template = "{{ value_json.coordinator }}"; + icon = "mdi:chip"; + } + ]; + binary_sensor = + (router_bin "router1") + ++ (router_bin "router2"); + switch = [ + { + platform = "mqtt"; + name = "Zigbee2mqtt Main join"; + state_topic = "${prefix}/bridge/config/permit_join"; + command_topic = "${prefix}/bridge/config/permit_join"; + payload_on = "true"; + payload_off = "false"; + } + ]; + automation = [ + { + alias = "Zigbee2mqtt Log Level"; + initial_state = "on"; + trigger = { + platform = "state"; + entity_id = "input_select.zigbee2mqtt_log_level"; + }; + action = [ + { + service = "mqtt.publish"; + data = { + payload_template = "{{ states('input_select.zigbee2mqtt_log_level') }}"; + topic = "${prefix}/bridge/config/log_level"; + }; + } + ]; + } +# Automation to start timer when enable join is turned on + { + id = "zigbee_join_enabled"; + alias = "Zigbee Join Enabled"; + hide_entity = "true"; + trigger = + { + platform = "state"; + entity_id = "switch.zigbee2mqtt_main_join"; + to = "on"; + }; + action = + { + service = "timer.start"; + entity_id = "timer.zigbee_permit_join"; + }; + } +# # Automation to stop timer when switch turned off and turn off switch when timer finished + { + id = "zigbee_join_disabled"; + alias = "Zigbee Join Disabled"; + hide_entity = "true"; + trigger = [ + { + platform = "event"; + event_type = "timer.finished"; + event_data.entity_id = "timer.zigbee_permit_join"; + } + { + platform = "state"; + entity_id = "switch.zigbee2mqtt_main_join"; + to = "off"; + } + ]; + action = [ + { service = "timer.cancel"; + data.entity_id = "timer.zigbee_permit_join"; + } + { service = "switch.turn_off"; + entity_id = "switch.zigbee2mqtt_main_join"; + } + ]; + } + ]; + input_select.zigbee2mqtt_log_level = + { + name = "Zigbee2mqtt Log Level"; + options = [ + "debug" + "info" + "warn" + "error" + ]; + initial = "info"; + icon = "mdi:format-list-bulleted"; + }; + + timer.zigbee_permit_join = + { + name = "Zigbee Time remaining"; + duration = 120; + }; +} diff --git a/makefu/2configs/homeautomation/sensor/outside.nix b/makefu/2configs/homeautomation/sensor/outside.nix new file mode 100644 index 00000000..8436b8de --- /dev/null +++ b/makefu/2configs/homeautomation/sensor/outside.nix @@ -0,0 +1,26 @@ +{lib,...}: [ + { platform = "darksky"; + api_key = lib.removeSuffix "\n" + (builtins.readFile ); + language = "de"; + monitored_conditions = [ + "summary" "icon" + "nearest_storm_distance" "precip_probability" + "precip_intensity" + "temperature" # "temperature_high" "temperature_low" + "apparent_temperature" + "hourly_summary" # next 24 hours text + "humidity" + "pressure" + "uv_index" + ]; + units = "si" ; + scan_interval = "00:30:00"; + } + { platform = "luftdaten"; + name = "Muehlhausen"; + show_on_map = true; + sensor_id = "679"; + sensors.monitored_conditions = [ "P1" "P2" ]; + } + ] -- cgit v1.2.3 From d31fbfe31ee26b70f13c93d910f5ce0d3ce1d8c2 Mon Sep 17 00:00:00 2001 From: makefu Date: Wed, 5 Feb 2020 17:34:44 +0100 Subject: ma 2/homeautomation -> 2/ham avoid overlapping autocomplete with home-manager --- makefu/1systems/omo/config.nix | 39 ++- makefu/2configs/ham/default.nix | 225 +++++++++++++++ makefu/2configs/ham/google-muell.nix | 45 +++ makefu/2configs/ham/lib/default.nix | 318 +++++++++++++++++++++ makefu/2configs/ham/mqtt.nix | 24 ++ makefu/2configs/ham/multi/timer.nix | 123 ++++++++ makefu/2configs/ham/multi/zigbee2mqtt.nix | 165 +++++++++++ makefu/2configs/ham/sensor/outside.nix | 26 ++ makefu/2configs/homeautomation/default.nix | 225 --------------- makefu/2configs/homeautomation/google-muell.nix | 45 --- makefu/2configs/homeautomation/lib/default.nix | 318 --------------------- makefu/2configs/homeautomation/mqtt.nix | 24 -- makefu/2configs/homeautomation/multi/timer.nix | 123 -------- .../2configs/homeautomation/multi/zigbee2mqtt.nix | 165 ----------- makefu/2configs/homeautomation/sensor/outside.nix | 26 -- 15 files changed, 943 insertions(+), 948 deletions(-) create mode 100644 makefu/2configs/ham/default.nix create mode 100644 makefu/2configs/ham/google-muell.nix create mode 100644 makefu/2configs/ham/lib/default.nix create mode 100644 makefu/2configs/ham/mqtt.nix create mode 100644 makefu/2configs/ham/multi/timer.nix create mode 100644 makefu/2configs/ham/multi/zigbee2mqtt.nix create mode 100644 makefu/2configs/ham/sensor/outside.nix delete mode 100644 makefu/2configs/homeautomation/default.nix delete mode 100644 makefu/2configs/homeautomation/google-muell.nix delete mode 100644 makefu/2configs/homeautomation/lib/default.nix delete mode 100644 makefu/2configs/homeautomation/mqtt.nix delete mode 100644 makefu/2configs/homeautomation/multi/timer.nix delete mode 100644 makefu/2configs/homeautomation/multi/zigbee2mqtt.nix delete mode 100644 makefu/2configs/homeautomation/sensor/outside.nix diff --git a/makefu/1systems/omo/config.nix b/makefu/1systems/omo/config.nix index 9b9b91a6..d00d61fd 100644 --- a/makefu/1systems/omo/config.nix +++ b/makefu/1systems/omo/config.nix @@ -57,7 +57,7 @@ in { # - + # # services { @@ -71,14 +71,9 @@ in { - { - # Risikoübernahme - nixpkgs.config.permittedInsecurePackages = [ - "homeassistant-0.77.2" - ]; - } - - + + + { makefu.ps3netsrv = { enable = true; @@ -120,7 +115,7 @@ in { gid = (import ).genid "share"; members = [ "makefu" "misa" ]; }; - networking.firewall.trustedInterfaces = [ primaryInterface ]; + networking.firewall.trustedInterfaces = [ primaryInterface "docker0" ]; @@ -141,18 +136,18 @@ in { sed-plugin random-emoji ]; }; - krebs.Reaktor.reaktor-bgt = { - nickname = "Reaktor|bgt"; - workdir = "/var/lib/Reaktor/bgt"; - channels = [ "#binaergewitter" ]; - plugins = with pkgs.ReaktorPlugins; - [ titlebot - # stockholm-issue - nixos-version - shack-correct - sed-plugin - random-emoji ]; - }; + #krebs.Reaktor.reaktor-bgt = { + # nickname = "Reaktor|bgt"; + # workdir = "/var/lib/Reaktor/bgt"; + # channels = [ "#binaergewitter" ]; + # plugins = with pkgs.ReaktorPlugins; + # [ titlebot + # # stockholm-issue + # nixos-version + # shack-correct + # sed-plugin + # random-emoji ]; + #}; krebs.build.host = config.krebs.hosts.omo; } diff --git a/makefu/2configs/ham/default.nix b/makefu/2configs/ham/default.nix new file mode 100644 index 00000000..56acc2d0 --- /dev/null +++ b/makefu/2configs/ham/default.nix @@ -0,0 +1,225 @@ +{ pkgs, lib, config, ... }: + +# Ideas: +## wake-on-lan server +## +let + hlib = (import ./lib); + prefix = hlib.prefix; + tasmota = hlib.tasmota; + firetv = "192.168.1.183"; + kodi-host = firetv; + hassdir = "/var/lib/hass"; + zigbee = import ./multi/zigbee2mqtt.nix; +# switch +# automation +# binary_sensor +# sensor +# input_select +# timer +in { + imports = [ + ./mqtt.nix + ]; + + services.home-assistant = { + config = { + input_select = zigbee.input_select; # dict + timer = zigbee.timer; # dict + homeassistant = { + name = "Home"; time_zone = "Europe/Berlin"; + latitude = "48.7687"; + longitude = "9.2478"; + elevation = 247; + }; + #discovery = {}; + conversation = {}; + history = {}; + logbook = {}; + tts = [ + { platform = "google_translate"; + language = "de"; + time_memory = 57600; + service_name = "google_say"; + } + ]; + + telegram_bot = [ + # secrets file: { + # "platform": "broadcast", + # "api_key": "", # talk to Botfather /newbot + # "allowed_chat_ids": [ ID ] # curl -X GET # https://api.telegram.org/bot/getUpdates + #} + (builtins.fromJSON + (builtins.readFile )) + ]; + notify = [ + { + platform = "kodi"; + name = "wohnzimmer"; + host = kodi-host; + } + { + platform = "telegram"; + name = "telegrambot"; + chat_id = builtins.elemAt + (builtins.fromJSON (builtins.readFile + )).allowed_chat_ids 0; + } + ]; + sun.elevation = 247; + recorder = {}; + media_player = [ + { platform = "kodi"; + host = firetv; + } + { platform = "firetv"; + name = "FireTV Stick"; + host = firetv; + adbkey = ; + } + ]; + mqtt = { + broker = "localhost"; + port = 1883; + client_id = "home-assistant"; + username = "hass"; + password = lib.removeSuffix "\n" (builtins.readFile ); + 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; + }; + }; + binary_sensor = [ + (tasmota.motion { name = "Flur Bewegung"; host = "flurlicht";}) + ] ++ zigbee.binary_sensor; + sensor = [ + # broken + #{ platform = "speedtest"; + # monitored_conditions = [ "ping" "download" "upload" ]; + #} + # https://www.home-assistant.io/cookbook/automation_for_rainy_days/ + ] + ++ ((import ./sensor/outside.nix) {inherit lib;}) + ++ zigbee.sensor + ++ (tasmota.bme { name = "Schlafzimmer"; host = "schlafzimmer";}) + ++ (tasmota.am2301 { name= "Arbeitszimmer" ; host = "arbeitszimmer"; }); + frontend = { }; + group = + { default_view = + { view = "yes"; + entities = [ + "group.flur" + "group.schlafzimmer" + "group.draussen" + "group.wohnzimmer" + "group.arbeitszimmer" + ]; + }; + flur = [ + "light.flurlicht" + "binary_sensor.flur_bewegung" + "automation.dunkel_bei_sonnenuntergang" + "automation.hell_bei_sonnenaufgang" + ]; + wohnzimmer = [ + "media_player.kodi" + "media_player.firetv_stick" + ]; + draussen = [ + "sensor.dark_sky_temperature" + "sensor.dark_sky_hourly_summary" + "sensor.dark_sky_humidity" + "sensor.dark_sky_pressure" + "sensor.muehlhausen_pm10" + "sensor.muehlhausen_pm25" + ]; + schlafzimmer = [ + "sensor.schlafzimmer_temperatur" + "sensor.schlafzimmer_luftdruck" + "sensor.schlafzimmer_luftfeuchtigkeit" + "switch.lichterkette_schlafzimmer" + ]; + arbeitszimmer = [ + "switch.strom_staubsauger" + "sensor.arbeitszimmer_temperatur" + "sensor.arbeitszimmer_luftfeuchtigkeit" + ]; + }; + http = { }; + switch = [ + (tasmota.plug { name = "Lichterkette Schlafzimmer"; host = "schlafzimmer";}) + (tasmota.plug { name = "Strom Staubsauger"; host = "arbeitszimmer"; } ) + ] ++ zigbee.switch; + light = [ (tasmota.rgb { name = "Flurlicht"; host = "flurlicht";} ) ]; + automation = [ + { alias = "Dunkel bei Sonnenuntergang"; + trigger = { + platform = "sun"; + event = "sunset"; + # offset: "-00:45:00" + }; + action = [ + { + service= "light.turn_on"; + data = { + entity_id= "light.flurlicht"; + # rgb_color = [ 0,0,0 ]; <-- TODO default color + brightness_pct = 15; + }; + } + { + service= "light.turn_off"; + entity_id= "light.flurlicht"; + } + ]; + } + { alias = "Hell bei Sonnenaufgang"; + trigger = { + platform = "sun"; + event = "sunrise"; + # offset: "-00:00:00" + }; + action = [ + { + service= "light.turn_on"; + data = { + entity_id= "light.flurlicht"; + brightness_pct = 85; + }; + } + { + service= "light.turn_off"; + entity_id= "light.flurlicht"; + } + ]; + } + #{ alias = "Staubsauger Strom aus nach 6h"; + # trigger = { + # platform = "state"; + # entity_id = "switch.strom_staubsauger"; + # to = "on"; + # for.hours = 6; + # }; + # action = { + # service= "homeassistant.turn_off"; + # entity_id= "switch.strom_staubsauger"; + # }; + #} + ] ++ zigbee.automation; + }; + enable = true; + configDir = hassdir; + }; + +} diff --git a/makefu/2configs/ham/google-muell.nix b/makefu/2configs/ham/google-muell.nix new file mode 100644 index 00000000..c81eae20 --- /dev/null +++ b/makefu/2configs/ham/google-muell.nix @@ -0,0 +1,45 @@ +{ config, lib, pkgs, buildPythonPackage, ... }: +with import ; +let + pkg = pkgs.ampel; + home = "/var/lib/ampel"; + sec = "${toString }/ampel/google-muell.json"; + ampelsec = "${home}/google-muell.json"; + cred = "${toString }/ampel/google-muell-creds.json"; + # TODO: generate this credential file locally + ampelcred = "${home}/google-muell-creds.json"; + sleepval = "1800"; + # default-color = "18,63,40"; + default-color = "255,127,0"; + config_json = toFile "config.json" (toJSON { + mq_hostname = "localhost"; + mq_port = 1883; + mq_username = "sensor"; + mq_topic = "/ham/flurlicht/cmnd/MEM1"; + mq_password = replaceChars ["\n"] [""] (readFile "${toString }/mqtt/sensor"); + }); +in { + users.users.ampel = { + uid = genid "ampel"; + createHome = true; + isSystemUser = true; + inherit home; + }; + systemd.services.google-muell-ampel = { + description = "Send led change to rgb cubes"; + after = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + User = "ampel"; + ExecStartPre = pkgs.writeDash "copy-ampel-secrets" '' + install -m600 -o ampel ${sec} ${ampelsec} + install -m600 -o ampel ${cred} ${ampelcred} + ''; + ExecStart = "${pkg}/bin/google-muell --config ${config_json} --default-color=${default-color} --client-secrets=${ampelsec} --credential-path=${ampelcred} --sleepval=${sleepval}"; + PermissionsStartOnly = true; + Restart = "always"; + RestartSec = 10; + PrivateTmp = true; + }; + }; +} diff --git a/makefu/2configs/ham/lib/default.nix b/makefu/2configs/ham/lib/default.nix new file mode 100644 index 00000000..8bc54431 --- /dev/null +++ b/makefu/2configs/ham/lib/default.nix @@ -0,0 +1,318 @@ +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 = let + prefix = "/ham/zigbee"; + in + { + inherit prefix; + state = name: { + platform = "mqtt"; + name = "zigbee ${name} connectivity"; + state_topic = "${prefix}/${name}"; + availability_topic = "${prefix}/bridge/state"; + payload_on = true; + payload_off = false; + value_template = "{{ value_json.state }}"; + device_class = "connectivity"; + }; + battery = name: { + platform = "mqtt"; + name = "zigbee ${name} battery"; + state_topic = "${prefix}/${name}"; + availability_topic = "${prefix}/bridge/state"; + unit_of_measurement = "%"; + device_class = "battery"; + value_template = "{{ value_json.battery }}"; + }; + linkquality = name: { + platform = "mqtt"; + name = "zigbee ${name} linkquality"; + state_topic = "${prefix}/${name}"; + availability_topic = "${prefix}/bridge/state"; + unit_of_measurement = "-"; + value_template = "{{ value_json.linkquality }}"; + }; + temperature = name: { + platform = "mqtt"; + name = "zigbee ${name} temperature"; + state_topic = "${prefix}/${name}"; + availability_topic = "${prefix}/bridge/state"; + unit_of_measurement = "°C"; + device_class = "temperature"; + value_template = "{{ value_json.temperature }}"; + }; + humidity = name: { + platform = "mqtt"; + name = "zigbee ${name} humidity"; + state_topic = "${prefix}/${name}"; + availability_topic = "${prefix}/bridge/state"; + unit_of_measurement = "%"; + device_class = "humidity"; + value_template = "{{ value_json.humidity }}"; + }; + pressure = name: { + platform = "mqtt"; + state_topic = "${prefix}/${name}"; + name = "zigbee ${name} pressure"; + availability_topic = "${prefix}/bridge/state"; + unit_of_measurement = "hPa"; + device_class = "pressure"; + value_template = "{{ value_json.pressure }}" ; + }; + click = name: + { + platform = "mqtt"; + name = "zigbee ${name} click"; + state_topic = "${prefix}/${name}"; + availability_topic = "${prefix}/bridge/state"; + icon = "mdi:toggle-switch"; + value_template = "{{ value_json.click }}"; + }; + contact = name: { + platform = "mqtt"; + name = "zigbee ${name} contact"; + state_topic = "${prefix}/${name}"; + availability_topic = "${prefix}/bridge/state"; + payload_on = false; + payload_off = true; + value_template = "{{ value_json.contact }}"; + device_class = "door"; + }; + }; + esphome = + { + temp = {host, topic ? "temperature" }: + { + platform = "mqtt"; + name = "${host} Temperature"; + device_class = "temperature"; + unit_of_measurement = "°C"; + icon = "mdi:thermometer"; + state_topic = "${prefix}/${host}/sensor/${topic}/state"; + availability_topic = "${prefix}/${host}/status"; + payload_available = "online"; + payload_not_available = "offline"; + }; + hum = {host, topic ? "humidity" }: + { + platform = "mqtt"; + unit_of_measurement = "%"; + icon = "mdi:water-percent"; + device_class = "humidity"; + name = "${host} Humidity"; + state_topic = "${prefix}/${host}/sensor/${topic}/state"; + availability_topic = "${prefix}/${host}/status"; + payload_available = "online"; + payload_not_available = "offline"; + }; + # copied from "homeassistant/light/fablab_led/led_ring/config" + led = {host, topic ? "led", name ? host}: + { # name: fablab_led + # topic: led_ring + platform = "mqtt"; + inherit name; + schema = "json"; + brightness = true; + rgb = true; + effect = true; + effect_list = [ # TODO: may be different + "Random" + "Strobe" + "Rainbow" + "Color Wipe" + "Scan" + "Twinkle" + "Fireworks" + "Addressable Flicker" + "None" + ]; + state_topic = "${prefix}/${host}/light/${topic}/state"; + command_topic = "${prefix}/${host}/light/${topic}/command"; + availability_topic = "${prefix}/${host}/status"; + payload_available = "online"; + payload_not_available = "offline"; + qos = 1; + }; + # Feinstaub + dust_25m = { host, name ? "${host} < 2.5µm", topic ? "particulate_matter_25m_concentration" }: + { + platform = "mqtt"; + unit_of_measurement = "µg/m³"; + icon = "mdi:chemical-weapon"; + inherit name; + state_topic = "${prefix}/${host}/sensor/${topic}/state"; + availability_topic = "${prefix}/${host}/status"; + }; + dust_100m = {host, name ? "${host} < 10µm", topic ? "particulate_matter_100m_concentration" }: + { + platform = "mqtt"; + unit_of_measurement = "µg/m³"; + icon = "mdi:chemical-weapon"; + inherit name; + state_topic = "${prefix}/${host}/sensor/${topic}/state"; + availability_topic = "${prefix}/${host}/status"; + }; + ip = {host, name ? "${host} IP", topic ? "ip_address" }: + { + platform = "mqtt"; + inherit name; + state_topic = "${prefix}/${host}/sensor/${topic}/state"; + availability_topic = "${prefix}/${host}/status"; + }; + wifi = {host, name ? "${host} Wifi Signal", topic ? "wifi_signal" }: + { + platform = "mqtt"; + unit_of_measurement = "dB"; + icon = "mdi:wifi"; + inherit name; + state_topic = "${prefix}/${host}/sensor/${topic}/state"; + availability_topic = "${prefix}/${host}/status"; + }; + switch = {host, name ? "${host} Button", topic ? "btn" }: + # host: ampel + # name: Button 1 + # topic: btn1 + { + inherit name; + platform = "mqtt"; + state_topic = "${prefix}/${host}/sensor/${topic}/state"; + command_topic = "${prefix}/${host}/switch/${topic}/state"; + availability_topic = "${prefix}/${host}/status"; + }; + }; + tasmota = + { + plug = {host, name ? host, topic ? host}: + { + platform = "mqtt"; + inherit name; + state_topic = "sonoff/stat/${topic}/POWER1"; + command_topic = "sonoff/cmnd/${topic}/POWER1"; + availability_topic = "sonoff/tele/${topic}/LWT"; + payload_on= "ON"; + payload_off= "OFF"; + payload_available= "Online"; + payload_not_available= "Offline"; + retain = false; + qos = 1; + }; + am2301 = { name, host, topic?host }: + [ { platform = "mqtt"; + name = "${name} Temperatur"; + state_topic = "${prefix}/${topic}/tele/SENSOR"; + value_template = "{{ value_json.AM2301.Temperature }}"; + unit_of_measurement = "°C"; + } + { platform = "mqtt"; + name = "${name} Luftfeuchtigkeit"; + state_topic = "${prefix}/${topic}/tele/SENSOR"; + value_template = "{{ value_json.AM2301.Humidity }}"; + unit_of_measurement = "%"; + } + ]; + bme = { name, host, topic?host }: + [ { platform = "mqtt"; + name = "${name} Temperatur"; + state_topic = "${prefix}/${topic}/tele/SENSOR"; + value_template = "{{ value_json.BME280.Temperature }}"; + unit_of_measurement = "°C"; + } + { platform = "mqtt"; + name = "${name} Luftfeuchtigkeit"; + state_topic = "${prefix}/${topic}/tele/SENSOR"; + value_template = "{{ value_json.BME280.Humidity }}"; + unit_of_measurement = "%"; + } + { platform = "mqtt"; + name = "${name} Luftdruck"; + state_topic = "${prefix}/${topic}/tele/SENSOR"; + value_template = "{{ value_json.BME280.Pressure }}"; + unit_of_measurement = "hPa"; + } + ]; + rgb = { name, host, topic?host }: + { platform = "mqtt"; + inherit name; + retain = false; + qos = 1; + optimistic = false; + # state + # TODO: currently broken, will not use the custom state topic + #state_topic = "${prefix}/${topic}/stat/POWER"; + state_topic = "${prefix}/${topic}/stat/POWER"; + command_topic = "${prefix}/${topic}/cmnd/POWER"; + availability_topic = "${prefix}/${topic}/tele/LWT"; + payload_on= "ON"; + payload_off= "OFF"; + payload_available= "Online"; + payload_not_available= "Offline"; + # brightness + brightness_state_topic = "${prefix}/${topic}/stat/Dimmer"; + brightness_command_topic = "${prefix}/${topic}/cmnd/Dimmer"; + brightness_value_template = "{{ value_json.Dimmer }}"; + brightness_scale = 100; + # color + rgb_state_topic = "${prefix}/${topic}/stat/Color"; + rgb_command_topic = "${prefix}/${topic}/cmnd/MEM1"; # use enabled rule + rgb_command_mode = "hex"; + rgb_command_template = "{{ '%02x%02x%02x' | format(red, green, blue)}}"; + # effects + effect_state_topic = "${prefix}/${topic}/stat/Scheme"; + effect_command_topic = "${prefix}/${topic}/cmnd/Scheme"; + effect_value_template = "{{ value_json.Scheme }}"; + effect_list = [ 0 1 2 3 4 5 6 7 8 9 10 11 12 ]; +}; + motion = { name, host, topic?host }: + { platform = "mqtt"; + device_class = "motion"; + inherit name; + # TODO: currently broken, will not use the custom state topic + state_topic = "${prefix}/${topic}/stat/POWER"; + payload_on = "ON"; + payload_off = "OFF"; + availability_topic = "${prefix}/${topic}/tele/LWT"; + payload_available = "Online"; + payload_not_available = "Offline"; + }; + }; +} diff --git a/makefu/2configs/ham/mqtt.nix b/makefu/2configs/ham/mqtt.nix new file mode 100644 index 00000000..cd1c328d --- /dev/null +++ b/makefu/2configs/ham/mqtt.nix @@ -0,0 +1,24 @@ +{ pkgs, config, ... }: +{ + services.mosquitto = { + enable = true; + host = "0.0.0.0"; + allowAnonymous = false; + checkPasswords = true; + # see /mosquitto + users.sensor = { + hashedPassword = "$6$2DXU7W1bvqXPqxkF$vtdz5KTd/T09hmoc9LjgEGFjvpwQbQth6vlVcr5hJNLgcBHv4U03YCKC8TKXbmQAa8xiJ76xJIg25kcL+KI3tg=="; + acl = [ "topic readwrite #" ]; + }; + users.hass = { + hashedPassword = "$6$SHuYGrE5kPSUc/hu$EomZ0KBy+vkxLt/6eJkrSBjYblCCeMjhDfUd2mwqXYJ4XsP8hGmZ59mMlmBCd3AvlFYQxb4DT/j3TYlrqo7cDA=="; + acl = [ "topic readwrite #" ]; + }; + users.stats = { + hashedPassword = "$6$j4H7KXD/YZgvgNmL$8e9sUKRXowDqJLOVgzCdDrvDE3+4dGgU6AngfAeN/rleGOgaMhee2Mbg2KS5TC1TOW3tYbk9NhjLYtjBgfRkoA=="; + acl = [ "topic read #" ]; + }; + }; + environment.systemPackages = [ pkgs.mosquitto ]; + # port open via trusted interface +} diff --git a/makefu/2configs/ham/multi/timer.nix b/makefu/2configs/ham/multi/timer.nix new file mode 100644 index 00000000..eafb7841 --- /dev/null +++ b/makefu/2configs/ham/multi/timer.nix @@ -0,0 +1,123 @@ +# Provides: +# timer +# automation +# script + +# Needs: +# sensor.zigbee_btn1_click +# notify.telegrambot +let + button = "sensor.zigbee_btn1_click"; +in { + timer.kurzzeitwecker = + { + name = "Zigbee Kurzzeitwecker"; + duration = 300; + }; + script.add_5_minutes_to_kurzzeitwecker = + { + alias = "Add 5 minutes to kurzzeitwecker"; + sequence = [ + { service = "timer.pause"; + entity_id = "timer.kurzzeitwecker"; + } + { service = "timer.start"; + data_template = { + entity_id = "timer.kurzzeitwecker"; + duration = '' + {% set r = state_attr('timer.wecker', '