pepe: add stocks to home-assistant

This commit is contained in:
Ingolf Wagner 2020-04-17 20:59:12 +02:00
parent ddccee53cc
commit c1fe743fc4
No known key found for this signature in database
GPG key ID: 76BF5F1928B9618B
4 changed files with 237 additions and 21 deletions

View file

@ -3,12 +3,13 @@ let unstablePkgs = import <nixpkgs-unstable> { };
in { in {
imports = [ imports = [
#./home-assistant/chaospott.nix
#./home-assistant/mpd.nix #./home-assistant/mpd.nix
#./home-assistant/timer.nix #./home-assistant/timer.nix
./home-assistant/chaospott.nix
./home-assistant/kodi.nix ./home-assistant/kodi.nix
./home-assistant/mqtt.nix ./home-assistant/mqtt.nix
./home-assistant/sonoff.nix ./home-assistant/sonoff.nix
./home-assistant/stocks.nix
./home-assistant/weather.nix ./home-assistant/weather.nix
./home-assistant/workday.nix ./home-assistant/workday.nix
./home-assistant/zigbee2mqtt.nix ./home-assistant/zigbee2mqtt.nix
@ -37,7 +38,14 @@ in {
# ------------ # ------------
input_select.situation = { input_select.situation = {
icon = "mdi:brightness-auto"; 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.bed_room_buttons.icon = "mdi:toggle-switch";
input_boolean.situation_toggle.icon = "mdi:toggle-switch"; input_boolean.situation_toggle.icon = "mdi:toggle-switch";
@ -45,10 +53,19 @@ in {
automation = let automation = let
# todo : at night only turn trigger essential groups # todo : at night only turn trigger essential groups
roomPresents = { roomGroup, roomOffGroup ? roomGroup, presentsGroup roomPresents = {
, situation, brightness ? 255 }: [ # 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 = { trigger = {
platform = "state"; platform = "state";
entity_id = "group.${presentsGroup}"; entity_id = "group.${presentsGroup}";
@ -75,13 +92,19 @@ in {
]; ];
} }
{ {
alias = "absents -> turn off ${roomOffGroup} lights"; alias =
"absents -> turn off ${roomOffGroup} lights in ${situation}";
trigger = { trigger = {
platform = "state"; platform = "state";
entity_id = "group.${presentsGroup}"; entity_id = "group.${presentsGroup}";
from = "on"; from = "on";
to = "off"; to = "off";
}; };
condition = {
condition = "state";
entity_id = "input_select.situation";
state = situation;
};
action = [ action = [
{ {
service = "switch.turn_off"; service = "switch.turn_off";
@ -98,7 +121,7 @@ in {
{ {
roomGroup = "${name}_lights"; roomGroup = "${name}_lights";
presentsGroup = "${name}_present"; presentsGroup = "${name}_present";
situation = "on"; situation = "dark";
} }
{ {
roomGroup = "${name}_essential"; roomGroup = "${name}_essential";
@ -107,7 +130,10 @@ in {
situation = "essential"; situation = "essential";
brightness = 30; 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"; alias = "set essential";
trigger = { trigger = {
@ -136,7 +162,7 @@ in {
service = "input_select.select_option"; service = "input_select.select_option";
data = { data = {
entity_id = "input_select.situation"; entity_id = "input_select.situation";
option = "on"; option = "dark";
}; };
}; };
} }
@ -291,7 +317,9 @@ in {
# maintainers = with maintainers; [ mrVanDalo ]; # maintainers = with maintainers; [ mrVanDalo ];
# }; # };
#}) #})
]; ];
}; };
}; };

View file

@ -59,9 +59,8 @@ in {
Type = "oneshot"; Type = "oneshot";
}; };
description = "set ${name} for homeassistant"; description = "set ${name} for homeassistant";
script = # sh script = ''
'' ${pkgs.curl}/bin/curl --location --silent https://status.chaospott.de/api \
${pkgs.curl}/bin/curl -Ls https://status.chaospott.de/api \
| ${pkgs.jq}/bin/jq --compact-output \ | ${pkgs.jq}/bin/jq --compact-output \
'.sensors.door_locked | '.sensors.door_locked |
[.[] | { "\(.location)" : (if .value then "closed" else "open" end) }] | [.[] | { "\(.location)" : (if .value then "closed" else "open" end) }] |

View file

@ -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=<keywords>&apikey=<api_key>
# 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 <secrets/home-assistant/stocks>;
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 <secrets/home-assistant/alphavantage/apikey>
}
${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);
}

View file

@ -3,17 +3,26 @@ let
# https://www.zigbee2mqtt.io/devices/MCCGQ11LM.html # https://www.zigbee2mqtt.io/devices/MCCGQ11LM.html
allDevices = { allDevices = {
"door_sensor_1" = { id = "0x00158d000312dc52"; }; "door_sensor_1" = {
id = "0x00158d000312dc52";
groups = [ "living_room" ];
};
"door_sensor_2" = { "door_sensor_2" = {
id = "0x00158d000316d5bf"; id = "0x00158d000316d5bf";
groups = [ "floor_room" "floor_room_present" ]; groups = [ "floor_room" "floor_room_present" ];
}; };
"door_sensor_3" = { id = "0x00158d0002f9516f"; }; "door_sensor_3" = {
id = "0x00158d0002f9516f";
groups = [ "kitchen_room" ];
};
"door_sensor_4" = { "door_sensor_4" = {
id = "0x00158d00031383b9"; id = "0x00158d00031383b9";
groups = [ "floor_room" "floor_room_present" ]; groups = [ "floor_room" "floor_room_present" ];
}; };
"door_sensor_5" = { id = "0x00158d0003120d3e"; }; "door_sensor_5" = {
id = "0x00158d0003120d3e";
groups = [ "bath_room" ];
};
}; };
in { in {