From c1fe743fc4e3ee3357b486a067e7da39008febc0 Mon Sep 17 00:00:00 2001 From: Ingolf Wagner Date: Fri, 17 Apr 2020 20:59:12 +0200 Subject: [PATCH] pepe: add stocks to home-assistant --- configs/pepe/home-assistant.nix | 46 ++++- configs/pepe/home-assistant/chaospott.nix | 17 +- configs/pepe/home-assistant/stocks.nix | 180 ++++++++++++++++++ .../pepe/home-assistant/zigbee2mqtt/doors.nix | 15 +- 4 files changed, 237 insertions(+), 21 deletions(-) create mode 100644 configs/pepe/home-assistant/stocks.nix diff --git a/configs/pepe/home-assistant.nix b/configs/pepe/home-assistant.nix index d7ebe49..c25bb10 100644 --- a/configs/pepe/home-assistant.nix +++ b/configs/pepe/home-assistant.nix @@ -3,12 +3,13 @@ let unstablePkgs = import { }; in { imports = [ - #./home-assistant/chaospott.nix #./home-assistant/mpd.nix #./home-assistant/timer.nix + ./home-assistant/chaospott.nix ./home-assistant/kodi.nix ./home-assistant/mqtt.nix ./home-assistant/sonoff.nix + ./home-assistant/stocks.nix ./home-assistant/weather.nix ./home-assistant/workday.nix ./home-assistant/zigbee2mqtt.nix @@ -37,7 +38,14 @@ in { # ------------ input_select.situation = { icon = "mdi:brightness-auto"; - options = [ "on" "off" "essential" ]; + options = [ + # it is dark outside and I want it to be bright inside + "dark" + # it is bright outside, so no need to be bright inside + "bright" + # it is dark ouside, but I don't want it bright inside + "essential" + ]; }; input_boolean.bed_room_buttons.icon = "mdi:toggle-switch"; input_boolean.situation_toggle.icon = "mdi:toggle-switch"; @@ -45,10 +53,19 @@ in { automation = let # todo : at night only turn trigger essential groups - roomPresents = { roomGroup, roomOffGroup ? roomGroup, presentsGroup - , situation, brightness ? 255 }: [ + roomPresents = { + # group of the room that should be turned on + roomGroup, + # group of the room that should be turned off + roomOffGroup ? roomGroup, + # group of the room that that indicates presents in the room + presentsGroup, + # global situation + situation, + # brightness for dimable lights + brightness ? 255 }: [ { - alias = "presents -> turn on ${roomGroup} lights"; + alias = "presents -> turn on ${roomGroup} lights in ${situation}"; trigger = { platform = "state"; entity_id = "group.${presentsGroup}"; @@ -75,13 +92,19 @@ in { ]; } { - alias = "absents -> turn off ${roomOffGroup} lights"; + alias = + "absents -> turn off ${roomOffGroup} lights in ${situation}"; trigger = { platform = "state"; entity_id = "group.${presentsGroup}"; from = "on"; to = "off"; }; + condition = { + condition = "state"; + entity_id = "input_select.situation"; + state = situation; + }; action = [ { service = "switch.turn_off"; @@ -98,7 +121,7 @@ in { { roomGroup = "${name}_lights"; presentsGroup = "${name}_present"; - situation = "on"; + situation = "dark"; } { roomGroup = "${name}_essential"; @@ -107,7 +130,10 @@ in { situation = "essential"; brightness = 30; } - ]) [ "living_room" "floor_room" "bath_room" "bed_room" "kitchen_room" ]))) ++ [ + ]) [ "living_room" "floor_room" "bath_room" "bed_room" "kitchen_room" ]))) + ++ [ + + # control situation with buttons { alias = "set essential"; trigger = { @@ -136,7 +162,7 @@ in { service = "input_select.select_option"; data = { entity_id = "input_select.situation"; - option = "on"; + option = "dark"; }; }; } @@ -291,7 +317,9 @@ in { # maintainers = with maintainers; [ mrVanDalo ]; # }; #}) + ]; + }; }; diff --git a/configs/pepe/home-assistant/chaospott.nix b/configs/pepe/home-assistant/chaospott.nix index 945d7cd..0099c7f 100644 --- a/configs/pepe/home-assistant/chaospott.nix +++ b/configs/pepe/home-assistant/chaospott.nix @@ -59,15 +59,14 @@ in { Type = "oneshot"; }; description = "set ${name} for homeassistant"; - script = # sh - '' - ${pkgs.curl}/bin/curl -Ls https://status.chaospott.de/api \ - | ${pkgs.jq}/bin/jq --compact-output \ - '.sensors.door_locked | - [.[] | { "\(.location)" : (if .value then "closed" else "open" end) }] | - reduce .[] as $item ({}; . + $item) ' \ - >> ${filePath} - ''; + script = '' + ${pkgs.curl}/bin/curl --location --silent https://status.chaospott.de/api \ + | ${pkgs.jq}/bin/jq --compact-output \ + '.sensors.door_locked | + [.[] | { "\(.location)" : (if .value then "closed" else "open" end) }] | + reduce .[] as $item ({}; . + $item) ' \ + >> ${filePath} + ''; }; systemd.timers."${name}" = { diff --git a/configs/pepe/home-assistant/stocks.nix b/configs/pepe/home-assistant/stocks.nix new file mode 100644 index 0000000..d2e9073 --- /dev/null +++ b/configs/pepe/home-assistant/stocks.nix @@ -0,0 +1,180 @@ +{ lib, config, pkgs, ... }: +let + + folderPath = config.services.home-assistant.configDir; + + # find symbols with + # https://www.alphavantage.co/query?function=SYMBOL_SEARCH&keywords=&apikey= + # as described here : https://www.alphavantage.co/documentation/#symbolsearch + # + # example: + # -------- + # stocks = [ + # { + # symbol = "GOOGL"; + # name = "google"; + # friendly_name = "Google"; + # currency = "$"; + # # I own 50 and bought at a price of 1000 + # own = { + # pieces = 50; + # price = 1000; + # }; + # } + # ]; + stocks = import ; + filePath = name: "${folderPath}/stock_${name}.json"; + + cleanup_list = list: lib.filter (entry: entry != { }) (lib.flatten list); + +in { + services.homeAssistantConfig = { + + sensor = cleanup_list (map ({ name, currency, own ? { }, ... }: [ + { + platform = "file"; + name = "stock_${name}"; + file_path = filePath name; + value_template = "{{ value_json.price}} ${currency}"; + + } + { + platform = "file"; + name = "stock_${name}_change"; + file_path = filePath name; + value_template = "{{ value_json.change}} ${currency}"; + + } + { + platform = "file"; + name = "stock_${name}_change_percent"; + file_path = filePath name; + value_template = "{{ value_json.change_percent}} %"; + } + (lib.optionalAttrs (own != { }) { + platform = "file"; + name = "stock_${name}_profit"; + file_path = filePath name; + value_template = '' + {{ "{:,.2f}".format( value_json.price * ${toString own.pieces} - ${ + toString (own.pieces * own.price) + } ) }} ${currency}''; + }) + ]) stocks); + + homeassistant = { + whitelist_external_dirs = [ folderPath ]; + customize = builtins.listToAttrs (cleanup_list (map + ({ name, own ? { }, ... }: [ + { + name = "sensor.stock_${name}"; + value = { + icon = "mdi:cash-usd-outline"; + friendly_name = "Price"; + }; + } + { + name = "sensor.stock_${name}_change"; + value = { + icon = "mdi:radar"; + friendly_name = "Difference"; + }; + } + { + name = "sensor.stock_${name}_change_percent"; + value = { + icon = "mdi:radar"; + friendly_name = "Percent"; + }; + } + (lib.optionalAttrs (own != { }) { + name = "sensor.stock_${name}_profit"; + value = { + icon = "mdi:radar"; + friendly_name = "Profit"; + }; + }) + ]) stocks)); + }; + + group = { + "stocks" = { + name = "Aktien"; + view = true; + control = "hidden"; + entities = map ({ name, ... }: "group.stock_${name}") stocks; + }; + } // (builtins.listToAttrs (map ({ name, friendly_name, own ? { }, ... }: { + name = "stock_${name}"; + value = { + name = friendly_name; + control = "hidden"; + entities = [ + "sensor.stock_${name}" + "sensor.stock_${name}_change" + "sensor.stock_${name}_change_percent" + ] ++ (lib.optional (own != { }) "sensor.stock_${name}_profit"); + }; + }) stocks)); + + }; + + systemd.services = let + pullService = { name, symbol, currency, ... }: { + name = "pull_stock_${name}"; + value = { + enable = true; + before = [ "home-assistant.service" ]; + wantedBy = [ "home-assistant.service" ]; + serviceConfig = { + User = "hass"; + Type = "oneshot"; + }; + description = "pull stock_${name} for homeassistant"; + script = '' + SYMBOL="${symbol}" + CURRENCY="${currency}" + APIKEY=${ + lib.fileContents + } + + ${pkgs.curl}/bin/curl --location --silent \ + "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=$SYMBOL&apikey=$APIKEY" \ + | ${pkgs.jq}/bin/jq --compact-output \ + '.["Global Quote"] | + { + price: .["05. price"] | tonumber, + currency: "'$CURRENCY'", + change_percent: .["10. change percent"] | .[0:-1] | tonumber, + change: .["09. change"] | tonumber, + last_date: .["07. latest trading day"], + }' \ + >> ${filePath name} + + # old and stupid + #${pkgs.curl}/bin/curl --location --silent \ + #"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=$SYMBOL&interval=5min&apikey=$APIKEY" \ + #| ${pkgs.jq}/bin/jq --compact-output \ + # '.["Time Series (5min)"] | to_entries | [ .[] + # | { date : .key , value : .value["4. close"], currency: "'$CURRENCY'" } ] + # | sort_by(.date) | reverse | .[0]' \ + ''; + }; + }; + in builtins.listToAttrs (map pullService stocks); + + systemd.timers = let + pullTimer = { name, ... }: { + name = "pull_stock_${name}"; + value = { + enable = true; + wantedBy = [ "multi-user.target" ]; + timerConfig = { + OnCalendar = "hourly"; + Persistent = "true"; + }; + }; + }; + in builtins.listToAttrs (map pullTimer stocks); + +} diff --git a/configs/pepe/home-assistant/zigbee2mqtt/doors.nix b/configs/pepe/home-assistant/zigbee2mqtt/doors.nix index 5926c84..ae02a13 100644 --- a/configs/pepe/home-assistant/zigbee2mqtt/doors.nix +++ b/configs/pepe/home-assistant/zigbee2mqtt/doors.nix @@ -3,17 +3,26 @@ let # https://www.zigbee2mqtt.io/devices/MCCGQ11LM.html allDevices = { - "door_sensor_1" = { id = "0x00158d000312dc52"; }; + "door_sensor_1" = { + id = "0x00158d000312dc52"; + groups = [ "living_room" ]; + }; "door_sensor_2" = { id = "0x00158d000316d5bf"; groups = [ "floor_room" "floor_room_present" ]; }; - "door_sensor_3" = { id = "0x00158d0002f9516f"; }; + "door_sensor_3" = { + id = "0x00158d0002f9516f"; + groups = [ "kitchen_room" ]; + }; "door_sensor_4" = { id = "0x00158d00031383b9"; groups = [ "floor_room" "floor_room_present" ]; }; - "door_sensor_5" = { id = "0x00158d0003120d3e"; }; + "door_sensor_5" = { + id = "0x00158d0003120d3e"; + groups = [ "bath_room" ]; + }; }; in {