From 2b42b384c1b1efa353ea43f9d641a60fdeb73b04 Mon Sep 17 00:00:00 2001 From: Joris Roovers Date: Thu, 24 Feb 2022 21:30:53 +0100 Subject: [PATCH] Various updates :-) --- automations/bathroom.yaml | 42 +++---- automations/bedroom_kids.yaml | 12 +- automations/house_mode.yaml | 30 +++-- automations/kitchen.yaml | 11 ++ automations/landing.yaml | 9 ++ automations/laundryroom.yaml | 6 + automations/livingroom.yaml | 54 +++++---- automations/master_bedroom.yaml | 32 +++--- automations/morning_routine.yaml | 48 ++++---- automations/office.yaml | 30 ++--- commandline/udmpro-temp.sh | 10 -- commandline/unifi-stats.sh | 26 +++++ configuration.yaml | 7 ++ esphome/.base.yaml | 23 ++++ esphome/bedroom_window.yaml | 23 +--- esphome/diaper-station.yaml | 49 ++++---- esphome/front-door-curtain.yaml | 19 +--- esphome/office-curtain-left.yaml | 19 +--- esphome/office-curtain-right.yaml | 19 +--- esphome/sauna.yaml | 22 +--- esphome/slimmelezer.yaml | 180 ++++++++++++++++++++++++++++++ scenes/house_mode.yaml | 6 + scenes/livingroom.yaml | 19 +++- scenes/scenes.yaml | 9 +- scripts/notifications.yaml | 33 ++++-- sensors/binary.yaml | 17 +-- sensors/sensor.yaml | 5 +- templates/sensor.yaml | 34 ++++++ 28 files changed, 503 insertions(+), 291 deletions(-) delete mode 100644 commandline/udmpro-temp.sh create mode 100644 commandline/unifi-stats.sh create mode 100644 esphome/.base.yaml create mode 100644 esphome/slimmelezer.yaml diff --git a/automations/bathroom.yaml b/automations/bathroom.yaml index 54f0e20..8f14bb0 100644 --- a/automations/bathroom.yaml +++ b/automations/bathroom.yaml @@ -26,11 +26,9 @@ to: "off" for: "00:03:00" condition: - - condition: and - conditions: - - condition: state - entity_id: binary_sensor.shower_water_present - state: "off" + - condition: state + entity_id: binary_sensor.shower_water_present + state: "off" action: - service: scene.turn_on data: @@ -49,11 +47,9 @@ condition: # Let's check whether bathroom light is on, so we don't get cases where we the leak sensor is # flapping while nobody's in the bathroom - - condition: and - conditions: - - condition: state - entity_id: light.bathroom - state: "on" + - condition: state + entity_id: light.bathroom + state: "on" action: - service: script.notify_joris data: @@ -119,20 +115,18 @@ entity_id: light.bathroom_group to: "on" condition: - - condition: and - conditions: - - condition: state - entity_id: binary_sensor.joris_working - state: "off" - - condition: time - after: "12:00:00" - before: "17:00:00" - weekday: - - mon - - tue - - wed - - thu - - fri + - condition: state + entity_id: binary_sensor.joris_working + state: "off" + - condition: time + after: "12:00:00" + before: "17:00:00" + weekday: + - mon + - tue + - wed + - thu + - fri action: - service: scene.turn_on data: diff --git a/automations/bedroom_kids.yaml b/automations/bedroom_kids.yaml index cc2e3e5..fa61bb7 100644 --- a/automations/bedroom_kids.yaml +++ b/automations/bedroom_kids.yaml @@ -59,21 +59,20 @@ variables: kid: "{{ 'mats' if (trigger.to_state.entity_id == 'climate.bedroom_mats') else 'hannah' }}" action: - - service: notify.notify + - service: script.notify_family data: message: > It's getting warm in {{kid}}'s room. Bedroom Hannah: {{ state_attr("climate.bedroom_hannah", "current_temperature") }}C Bedroom Mats: {{ state_attr("climate.bedroom_mats", "current_temperature") }}C Master Bedroom: {{ state_attr("climate.master_bedroom", "current_temperature") }}C - data: - tag: bedroom-kids-warm + expire: "00:30:00" - condition: template value_template: "{{ is_state('input_boolean.heat_bedroom_' + kid, 'on') }}" - service: script.notify_joris data: message: Seems like it's {{kid}} room which has the input boolean on. - expire: "00:05:00" + expire: "00:01:00" - service: input_boolean.turn_off data: entity_id: "{{ 'input_boolean.heat_bedroom_' + kid }}" @@ -107,7 +106,7 @@ to: "off" for: "48:00:00" action: - - service: notify.notify + - service: script.notify_family data: message: It's been more than 48hrs since the kids window were last opened. Suggestion to open them :-) @@ -134,11 +133,12 @@ variables: action_open: "{{ 'OPEN_' ~ context.id }}" action_close: "{{ 'CLOSE_' ~ context.id }}" - - service: notify.notify + - service: script.notify_family data: message: > Hannah went to bed, pre-heat bedroom Mats? Bedroom Hannah: {{ state_attr("climate.bedroom_hannah", "current_temperature") }}C Bedroom Mats: {{ state_attr("climate.bedroom_mats", "current_temperature") }}C + expire: "00:05:00" data: uri: "/lovelace-phone/upstairs" diff --git a/automations/house_mode.yaml b/automations/house_mode.yaml index 79dca7a..dfb7bab 100644 --- a/automations/house_mode.yaml +++ b/automations/house_mode.yaml @@ -60,14 +60,12 @@ entity_id: light.office to: "on" condition: - - condition: and - conditions: - - condition: state - entity_id: input_select.house_mode - state: "Sleeping" - - condition: time - after: "05:00:00" - before: "18:00:00" + - condition: state + entity_id: input_select.house_mode + state: "Sleeping" + - condition: time + after: "05:00:00" + before: "18:00:00" action: - service: input_select.select_option data: @@ -151,15 +149,13 @@ entity_id: binary_sensor.front_door_contact to: "on" condition: - - condition: and - conditions: - - condition: state - entity_id: input_select.house_mode - state: "Away" - for: "00:05:00" - - condition: state - entity_id: person.joris - state: "home" + - condition: state + entity_id: input_select.house_mode + state: "Away" + for: "00:05:00" + - condition: state + entity_id: person.joris + state: "home" action: - service: script.notify_joris data: diff --git a/automations/kitchen.yaml b/automations/kitchen.yaml index 7327243..983bf96 100644 --- a/automations/kitchen.yaml +++ b/automations/kitchen.yaml @@ -42,3 +42,14 @@ - service: input_boolean.turn_off data: entity_id: input_boolean.cooking + +- alias: Enable cooking boolean when starting cooking + id: cooking_alert_on_start + trigger: + - platform: state + entity_id: binary_sensor.cooking_started + to: "on" + action: + - service: input_boolean.turn_on + data: + entity_id: input_boolean.cooking diff --git a/automations/landing.yaml b/automations/landing.yaml index b4f9b02..45ced63 100644 --- a/automations/landing.yaml +++ b/automations/landing.yaml @@ -27,3 +27,12 @@ - service: scene.turn_on data: entity_id: "{{ scene_entity_id }}" + # When Joris is still in bed, but Ilse is awake (determined when phone is charging) + - condition: "{{ not is_state('input_select.house_mode', 'Sleeping') }}" + - condition: "{{ is_state('sensor.iphone_13_pro_max_battery_state', 'Not Charging') }}" + - condition: "{{ is_state('person.joris', 'Home') }}" + - service: script.notify_joris + data: + message: Joris still sleeping, landing light should be kept off! + + diff --git a/automations/laundryroom.yaml b/automations/laundryroom.yaml index 6447807..5619905 100644 --- a/automations/laundryroom.yaml +++ b/automations/laundryroom.yaml @@ -18,12 +18,18 @@ to: "off" for: "00:01:00" variables: + # This is what I use today, the benefit is that this is pythonic (i.e. "easy" to read if you're used to python) scene_entity_id: "{{ 'scene.LaundryRoomEnter' + states('input_select.house_mode') if (trigger.to_state.state == 'on') else 'scene.LaundryRoomExit' }}" + # # Same, using new iif jinja filter + # scene_entity_id: "{{ (trigger.to_state.state == 'on') || iif('scene.LaundryRoomEnter' + states('input_select.house_mode'), 'scene.LaundryRoomExit') }}" + # # Same, using new iif homeassistant template function (I like this one the least) + # scene_entity_id: "{{ iif(trigger.to_state.state == 'on', scene.LaundryRoomEnter' + states('input_select.house_mode'), 'scene.LaundryRoomExit') }}" action: - service: scene.turn_on data: entity_id: "{{ scene_entity_id }}" + ################################################################################ # Laundry Status Notifications # ################################################################################ diff --git a/automations/livingroom.yaml b/automations/livingroom.yaml index 769ff4e..eb5c3b3 100644 --- a/automations/livingroom.yaml +++ b/automations/livingroom.yaml @@ -232,26 +232,24 @@ entity_id: light.dining_table to: "on" condition: - - condition: and + - condition: state + entity_id: media_player.tv_livingroom + state: "off" + - condition: state + entity_id: + - media_player.living_room + - media_player.bathroom + state: + - paused + - idle + - condition: state + entity_id: binary_sensor.joris_working + state: "off" + - condition: not conditions: - condition: state - entity_id: media_player.tv_livingroom - state: "off" - - condition: state - entity_id: - - media_player.living_room - - media_player.bathroom - state: - - paused - - idle - - condition: state - entity_id: binary_sensor.joris_working - state: "off" - - condition: not - conditions: - - condition: state - entity_id: input_select.house_mode - state: "Sleeping" + entity_id: input_select.house_mode + state: "Sleeping" action: - service: scene.turn_on data: @@ -272,17 +270,15 @@ to: "off" for: "00:15:00" condition: - - condition: and - conditions: - - condition: state - entity_id: light.dining_table - state: "on" - - condition: state - entity_id: binary_sensor.joris_working - state: "on" - - condition: state - entity_id: person.ilse - state: "not_home" + - condition: state + entity_id: light.dining_table + state: "on" + - condition: state + entity_id: binary_sensor.joris_working + state: "on" + - condition: state + entity_id: person.ilse + state: "not_home" action: - service: script.notify_joris data: diff --git a/automations/master_bedroom.yaml b/automations/master_bedroom.yaml index 3addb4e..864c6da 100644 --- a/automations/master_bedroom.yaml +++ b/automations/master_bedroom.yaml @@ -179,13 +179,11 @@ below: 16 for: "00:30:00" condition: - - condition: and - conditions: - - condition: template - value_template: "{{ states('input_select.house_mode') in ['Morning', 'Day', 'Evening'] }}" - - condition: state - entity_id: binary_sensor.bedroom_window - state: "on" + - condition: template + value_template: "{{ states('input_select.house_mode') in ['Morning', 'Day', 'Evening'] }}" + - condition: state + entity_id: binary_sensor.bedroom_window + state: "on" action: - service: script.notify_joris data: @@ -202,19 +200,17 @@ - platform: time at: "12:00:00" condition: - - condition: and + - condition: state + entity_id: binary_sensor.bedroom_window + state: "off" + - condition: not conditions: - condition: state - entity_id: binary_sensor.bedroom_window - state: "off" - - condition: not - conditions: - - condition: state - entity_id: binary_sensor.outside_precipitation - state: "on" - - condition: state - entity_id: input_select.house_mode - state: "Away" + entity_id: binary_sensor.outside_precipitation + state: "on" + - condition: state + entity_id: input_select.house_mode + state: "Away" action: - service: cover.open_cover data: diff --git a/automations/morning_routine.yaml b/automations/morning_routine.yaml index 217489f..d63409d 100644 --- a/automations/morning_routine.yaml +++ b/automations/morning_routine.yaml @@ -9,14 +9,12 @@ entity_id: light.nightstand_joris to: "on" condition: - - condition: and - conditions: - - condition: time - after: "07:00:00" - before: "10:00:00" - - condition: state - entity_id: binary_sensor.workday_sensor - state: "on" + - condition: time + after: "07:00:00" + before: "10:00:00" + - condition: state + entity_id: binary_sensor.workday_sensor + state: "on" action: - service: scene.turn_on data: @@ -34,17 +32,15 @@ entity_id: light.bathroom to: "off" condition: - - condition: and - conditions: - - condition: time - after: "07:00:00" - before: "10:00:00" - - condition: state - entity_id: binary_sensor.workday_sensor - state: "on" - - condition: state # Only do this automation when the house is still sleeping. This prevents this automation from messing up someone else presets who's already downstairs - entity_id: input_select.house_mode - state: "Sleeping" + - condition: time + after: "07:00:00" + before: "10:00:00" + - condition: state + entity_id: binary_sensor.workday_sensor + state: "on" + - condition: state # Only do this automation when the house is still sleeping. This prevents this automation from messing up someone else presets who's already downstairs + entity_id: input_select.house_mode + state: "Sleeping" action: # - service: rest_command.start_morning_tv # - delay: 00:00:05 # Wait a bit, so TV can turn on fully before we attempt to play music @@ -60,14 +56,12 @@ from: "off" to: "on" condition: - - condition: and - conditions: - - condition: time - after: "07:00:00" - before: "10:30:00" - - condition: state - entity_id: binary_sensor.workday_sensor - state: "on" + - condition: time + after: "07:00:00" + before: "10:30:00" + - condition: state + entity_id: binary_sensor.workday_sensor + state: "on" action: - service: scene.turn_on data: diff --git a/automations/office.yaml b/automations/office.yaml index 4879264..9b4ba4b 100644 --- a/automations/office.yaml +++ b/automations/office.yaml @@ -13,11 +13,9 @@ to: "off" for: "00:03:00" condition: - - condition: and - conditions: - - condition: state - entity_id: binary_sensor.joris_at_computer - state: "off" + - condition: state + entity_id: binary_sensor.joris_at_computer + state: "off" action: - service: scene.turn_on data: @@ -34,11 +32,9 @@ to: "off" for: "00:03:00" condition: - - condition: and - conditions: - - condition: state - entity_id: input_select.house_mode - state: "Sleeping" + - condition: state + entity_id: input_select.house_mode + state: "Sleeping" variables: scene_entity_id: "{{ 'scene.OfficeSleeping' if (trigger.to_state.state == 'on') else 'scene.OfficeSleepingExit' }}" action: @@ -104,13 +100,11 @@ - platform: time at: "09:00:00" condition: - - condition: and - conditions: - - condition: time - after: "08:59:00" - - condition: state - entity_id: input_select.house_mode - state: "Morning" + - condition: time + after: "08:59:00" + - condition: state + entity_id: input_select.house_mode + state: "Morning" action: - service: cover.open_cover data: @@ -239,5 +233,5 @@ action: - service: script.notify_joris data: - message: Office CO2 concentration ({{sensor.office_waveplus_co2}}) getting high! + message: Office CO2 concentration ({{ states('sensor.office_waveplus_co2') }}) getting high! expire: "00:15:00" diff --git a/commandline/udmpro-temp.sh b/commandline/udmpro-temp.sh deleted file mode 100644 index 4bcee3a..0000000 --- a/commandline/udmpro-temp.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -UDM_HOST=$(cat secrets.yaml | awk '/udm_pro_host/{print $2}') -UDM_BASE_URL="https://$UDM_HOST:443" -UDM_USERNAME=$(cat secrets.yaml | awk '/udm_pro_username/{print $2}') -UDM_PASSWORD=$(cat secrets.yaml | awk '/udm_pro_password/{print $2}') - -curl -s -k -X POST --data '{"username":"'$UDM_USERNAME'", "password": "'$UDM_PASSWORD'"}' -H "Content-Type: application/json" -c /tmp/cookie.txt $UDM_BASE_URL/api/auth/login > /dev/null -DATA=$(curl -s -k -X GET -b /tmp/cookie.txt $UDM_BASE_URL/proxy/network/api/s/default/stat/device) -echo "$DATA" | jq '.data[] | select(.model == "UDMPRO").temperatures[] | select(.name == "CPU").value' \ No newline at end of file diff --git a/commandline/unifi-stats.sh b/commandline/unifi-stats.sh new file mode 100644 index 0000000..b8cb928 --- /dev/null +++ b/commandline/unifi-stats.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# config +UDM_HOST=$(cat secrets.yaml | awk '/udm_pro_host/{print $2}') +UDM_BASE_URL="https://$UDM_HOST:443" +UDM_USERNAME=$(cat secrets.yaml | awk '/udm_pro_username/{print $2}') +UDM_PASSWORD=$(cat secrets.yaml | awk '/udm_pro_password/{print $2}') + +# Authenticate and fetch data +curl -s -k -X POST --data '{"username":"'$UDM_USERNAME'", "password": "'$UDM_PASSWORD'"}' -H "Content-Type: application/json" -c /tmp/cookie.txt $UDM_BASE_URL/api/auth/login > /dev/null +DATA=$(curl -s -k -X GET -b /tmp/cookie.txt $UDM_BASE_URL/proxy/network/api/s/default/stat/device) + +# Extract data for UDM Pro +UDM_PRO_DATA=$(echo "$DATA" | jq '.data[] | select(.model == "UDMPRO")') +UDM_PRO_TEMP=$(echo "$UDM_PRO_DATA" | jq -j '.temperatures[] | select(.name == "CPU").value') +UDM_PRO_CPU=$(echo "$UDM_PRO_DATA" | jq -r -j '."system-stats".cpu') +UDM_PRO_MEM=$(echo "$UDM_PRO_DATA" | jq -r -j '."system-stats".mem') +UDM_PRO_UPTIME=$(echo "$UDM_PRO_DATA" | jq -r -j '."system-stats".uptime') + +# Extract data for USW-24-POE +USW_24_POE_DATA=$(echo "$DATA" | jq '.data[] | select(.model == "USL24P")') +USW_24_POE_CPU=$(echo "$USW_24_POE_DATA" | jq -r -j '."system-stats".cpu') +USW_24_POE_MEM=$(echo "$USW_24_POE_DATA" | jq -r -j '."system-stats".mem') +USW_24_POE_UPTIME=$(echo "$USW_24_POE_DATA" | jq -r -j '."system-stats".uptime') + +echo "$UDM_PRO_TEMP|$UDM_PRO_CPU|$UDM_PRO_MEM|$UDM_PRO_UPTIME|$USW_24_POE_CPU|$USW_24_POE_MEM|$USW_24_POE_UPTIME" \ No newline at end of file diff --git a/configuration.yaml b/configuration.yaml index 02148ec..f54c182 100644 --- a/configuration.yaml +++ b/configuration.yaml @@ -24,6 +24,13 @@ zone: radius: 75 icon: mdi:home +notify: + - name: family + platform: group + services: + - service: mobile_app_iphone_13_pro_max + - service: mobile_app_iphone_van_ilse + group: !include groups.yaml # By "labeling" the 'automation' key, we can use it multiple times and import from different locations # This allows us to enable both handwritten and UI-generated automations diff --git a/esphome/.base.yaml b/esphome/.base.yaml new file mode 100644 index 0000000..cdd1b4d --- /dev/null +++ b/esphome/.base.yaml @@ -0,0 +1,23 @@ +wifi: + ssid: !secret wifi_ssid + password: !secret wifi_password + # Required to connect to hidden SSIDs + fast_connect: true + + # Enable fallback hotspot (captive portal) in case wifi connection fails + ap: + ssid: ${dnsname}_fallback-AP + password: !secret wifi_fallback_ap_password + +# Enable Home Assistant API +api: + password: !secret api_password + encryption: + key: !secret api_encryption_key + +# Enable Over-The-Air updates +ota: + password: !secret ota_password + +logger: +# level: DEBUG # Required for the tracker to show the device \ No newline at end of file diff --git a/esphome/bedroom_window.yaml b/esphome/bedroom_window.yaml index 12226ba..2c3bdb8 100644 --- a/esphome/bedroom_window.yaml +++ b/esphome/bedroom_window.yaml @@ -16,28 +16,7 @@ esphome: - switch.turn_off: ${deviceid}_open_relay - switch.turn_off: ${deviceid}_close_relay -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: ${dnsname}_fallback-AP - password: !secret wifi_fallback_ap_password - -captive_portal: - -# Enable logging -logger: - -# Enable Home Assistant API -api: - password: !secret api_password - encryption: - key: !secret api_encryption_key - -ota: - password: !secret ota_password +<<: !include .base.yaml ######################################################################################################################## # I/O # diff --git a/esphome/diaper-station.yaml b/esphome/diaper-station.yaml index f8317aa..1cf2a79 100644 --- a/esphome/diaper-station.yaml +++ b/esphome/diaper-station.yaml @@ -8,40 +8,25 @@ esphome: platform: ESP32 board: wemos_d1_mini32 -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: ${dnsname}_fallback-AP - password: !secret wifi_fallback_ap_password - -# Enable Home Assistant API -api: - password: !secret api_password - encryption: - key: !secret api_encryption_key - -# Enable Over-The-Air updates -ota: - password: !secret ota_password - -logger: +<<: !include .base.yaml ################################################################################ # Airthings Wave Plus BLE sensor # ################################################################################ +# airthings_ble: # Required for the tracker to show the device + # Enable Bluetooth Low Energy esp32_ble_tracker: ble_client: - - mac_address: !secret airthings_wave_plus_ble_mac - id: airthings01 + - mac_address: !secret office_airthings_wave_plus_ble_mac + id: airthings_office + - mac_address: !secret bedroom_airthings_wave_plus_ble_mac + id: airthings_bedroom sensor: - platform: airthings_wave_plus - ble_client_id: airthings01 + ble_client_id: airthings_office update_interval: 5min temperature: name: "Office WavePlus Temperature" @@ -57,6 +42,24 @@ sensor: name: "Office WavePlus CO2" tvoc: name: "Office WavePlus VOC" + + - platform: airthings_wave_plus + ble_client_id: airthings_bedroom + update_interval: 5min + temperature: + name: "Bedroom WavePlus Temperature" + radon: + name: "Bedroom WavePlus Radon" + radon_long_term: + name: "Bedroom WavePlus Radon Long Term" + pressure: + name: "Bedroom WavePlus Pressure" + humidity: + name: "Bedroom WavePlus Humidity" + co2: + name: "Bedroom WavePlus CO2" + tvoc: + name: "Bedroom WavePlus VOC" ################################################################################ # Diaper Weight sensor # diff --git a/esphome/front-door-curtain.yaml b/esphome/front-door-curtain.yaml index a1bb3fd..2e95ea9 100644 --- a/esphome/front-door-curtain.yaml +++ b/esphome/front-door-curtain.yaml @@ -9,24 +9,7 @@ esphome: platform: ESP8266 board: esp01_1m -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: ${dnsname}_fallback-AP - password: !secret wifi_fallback_ap_password - -api: - password: !secret api_password - encryption: - key: !secret api_encryption_key - -logger: - -ota: - password: !secret ota_password +<<: !include .base.yaml switch: - platform: gpio diff --git a/esphome/office-curtain-left.yaml b/esphome/office-curtain-left.yaml index 52a90f3..1b8f08f 100644 --- a/esphome/office-curtain-left.yaml +++ b/esphome/office-curtain-left.yaml @@ -9,24 +9,7 @@ esphome: platform: ESP8266 board: esp01_1m -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: ${dnsname}_fallback-AP - password: !secret wifi_fallback_ap_password - -api: - password: !secret api_password - encryption: - key: !secret api_encryption_key - -logger: - -ota: - password: !secret ota_password +<<: !include .base.yaml switch: - platform: gpio diff --git a/esphome/office-curtain-right.yaml b/esphome/office-curtain-right.yaml index 315fe90..1a3638c 100644 --- a/esphome/office-curtain-right.yaml +++ b/esphome/office-curtain-right.yaml @@ -9,24 +9,7 @@ esphome: platform: ESP8266 board: esp01_1m -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: ${dnsname}_fallback-AP - password: !secret wifi_fallback_ap_password - -api: - password: !secret api_password - encryption: - key: !secret api_encryption_key - -logger: - -ota: - password: !secret ota_password +<<: !include .base.yaml switch: - platform: gpio diff --git a/esphome/sauna.yaml b/esphome/sauna.yaml index ba5d524..159a9cf 100644 --- a/esphome/sauna.yaml +++ b/esphome/sauna.yaml @@ -15,27 +15,7 @@ esphome: board_build.mcu: esp32 board_build.f_cpu: 240000000L -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: ${dnsname}_fallback-AP - password: !secret wifi_fallback_ap_password - - -# Enable Home Assistant API -api: - password: !secret api_password - encryption: - key: !secret api_encryption_key - -# Enable Over-The-Air updates -ota: - password: !secret ota_password - -logger: +<<: !include .base.yaml i2c: sda: 21 diff --git a/esphome/slimmelezer.yaml b/esphome/slimmelezer.yaml new file mode 100644 index 0000000..d0a6e6c --- /dev/null +++ b/esphome/slimmelezer.yaml @@ -0,0 +1,180 @@ +substitutions: + device_name: slimmelezer + device_description: "DIY P1 module to read your smart meter" + +esphome: + name: ${device_name} + comment: "${device_description}" + platform: ESP8266 + esp8266_restore_from_flash: true + board: d1_mini + name_add_mac_suffix: false + project: + name: zuidwijk.slimmelezer + version: "1.0" + on_boot: + then: + - if: + condition: + lambda: return id(has_key); + then: + - lambda: |- + std::string key(id(stored_decryption_key), 32); + id(dsmr_instance).set_decryption_key(key); + else: + - logger.log: + level: info + format: "Not using decryption key. If you need to set a key use Home Assistant service 'ESPHome: ${device_name}_set_dsmr_key'" + +wifi: + fast_connect: true + networks: + - ssid: !secret wifi_ssid + password: !secret wifi_password + + # Enable fallback hotspot (captive portal) in case wifi connection fails + ap: + ssid: ${device_name} + ap_timeout: 15s + +captive_portal: + +# Enable logging +logger: + baud_rate: 0 + +# Enable Home Assistant API +api: + services: + service: set_dsmr_key + variables: + private_key: string + then: + - logger.log: + format: Setting private key %s. Set to empty string to disable + args: [private_key.c_str()] + - globals.set: + id: has_key + value: !lambda "return private_key.length() == 32;" + - lambda: |- + if (private_key.length() == 32) + private_key.copy(id(stored_decryption_key), 32); + id(dsmr_instance).set_decryption_key(private_key); + +ota: + +web_server: + port: 80 + +uart: + baud_rate: 115200 + rx_pin: D7 + +globals: + - id: has_key + type: bool + restore_value: yes + initial_value: "false" + - id: stored_decryption_key + type: char[32] + restore_value: yes + +dsmr: + id: dsmr_instance + # For Luxembourg users set here your decryption key. + # Enable this when using decryption for Luxembourg; + # key looks like '00112233445566778899AABBCCDDEEFF' + #decryption_key: !secret decryption_key + +sensor: + - platform: dsmr + energy_delivered_lux: + name: "Energy Consumed Luxembourg" + state_class: total_increasing + energy_delivered_tariff1: + name: "Energy Consumed Tariff 1" + state_class: total_increasing + energy_delivered_tariff2: + name: "Energy Consumed Tariff 2" + state_class: total_increasing + energy_returned_lux: + name: "Energy Produced Luxembourg" + state_class: total_increasing + energy_returned_tariff1: + name: "Energy Produced Tariff 1" + state_class: total_increasing + energy_returned_tariff2: + name: "Energy Produced Tariff 2" + state_class: total_increasing + power_delivered: + name: "Power Consumed" + accuracy_decimals: 3 + power_returned: + name: "Power Produced" + accuracy_decimals: 3 + electricity_failures: + name: "Electricity Failures" + icon: mdi:alert + electricity_long_failures: + name: "Long Electricity Failures" + icon: mdi:alert + voltage_l1: + name: "Voltage Phase 1" + voltage_l2: + name: "Voltage Phase 2" + voltage_l3: + name: "Voltage Phase 3" + current_l1: + name: "Current Phase 1" + current_l2: + name: "Current Phase 2" + current_l3: + name: "Current Phase 3" + power_delivered_l1: + name: "Power Consumed Phase 1" + accuracy_decimals: 3 + power_delivered_l2: + name: "Power Consumed Phase 2" + accuracy_decimals: 3 + power_delivered_l3: + name: "Power Consumed Phase 3" + accuracy_decimals: 3 + power_returned_l1: + name: "Power Produced Phase 1" + accuracy_decimals: 3 + power_returned_l2: + name: "Power Produced Phase 2" + accuracy_decimals: 3 + power_returned_l3: + name: "Power Produced Phase 3" + accuracy_decimals: 3 + gas_delivered: + name: "Gas Consumed" + state_class: total_increasing + gas_delivered_be: + name: "Gas Consumed Belgium" + state_class: total_increasing + - platform: uptime + name: "SlimmeLezer Uptime" + - platform: wifi_signal + name: "SlimmeLezer Wi-Fi Signal" + update_interval: 60s + +text_sensor: + - platform: dsmr + identification: + name: "DSMR Identification" + p1_version: + name: "DSMR Version" + p1_version_be: + name: "DSMR Version Belgium" + - platform: wifi_info + ip_address: + name: "SlimmeLezer IP Address" + ssid: + name: "SlimmeLezer Wi-Fi SSID" + bssid: + name: "SlimmeLezer Wi-Fi BSSID" + - platform: version + name: "ESPHome Version" + hide_timestamp: true \ No newline at end of file diff --git a/scenes/house_mode.yaml b/scenes/house_mode.yaml index 167530b..21896f3 100644 --- a/scenes/house_mode.yaml +++ b/scenes/house_mode.yaml @@ -36,6 +36,12 @@ state: "off" light.landing: state: "off" + humidifier.pure_humidify_cool: + state: "on" + mode: auto + fan.pure_humidify_cool: + state: "on" + preset_mode: Auto icon: mdi:bed - name: Away diff --git a/scenes/livingroom.yaml b/scenes/livingroom.yaml index 4d2248c..2d3062b 100644 --- a/scenes/livingroom.yaml +++ b/scenes/livingroom.yaml @@ -114,7 +114,19 @@ state: "off" input_select.downstairs_music: NoMusic -- name: StopWatchingTVDay +- name: StopWatchingTVEarlyMorning + entities: + input_select.living_preset: NoPreset + +- name: StopWatchingTVMorning + entities: + light.tv: + state: "off" + light.tv_ambience: + state: "off" + input_select.living_preset: NoPreset + +- name: StopWatchingTVAfternoon entities: light.tv: state: "off" @@ -130,6 +142,11 @@ entities: input_select.living_preset: NoPreset +- name: StopWatchingTVAway + entities: + input_select.living_preset: NoPreset + + - name: Romance entities: light.tv: diff --git a/scenes/scenes.yaml b/scenes/scenes.yaml index e022ff7..1ab10cd 100644 --- a/scenes/scenes.yaml +++ b/scenes/scenes.yaml @@ -51,6 +51,9 @@ - name: TestBlinds entities: - cover.office_blinds: - state: "open" - current_tilt_position: 40 + humidifier.pure_humidify_cool: + state: "on" + mode: auto + fan.pure_humidify_cool: + state: "on" + preset_mode: Auto diff --git a/scripts/notifications.yaml b/scripts/notifications.yaml index 38cd09f..7c2e27f 100644 --- a/scripts/notifications.yaml +++ b/scripts/notifications.yaml @@ -3,7 +3,7 @@ ######################################################################################################################## # Notification script, provides syntactic sugar for expiring messages -notify_joris_sync: +notify_sync: mode: parallel fields: title: @@ -12,38 +12,55 @@ notify_joris_sync: description: "The message content" expire: description: "Delay after which the notification should disappear" + nofication_service: + description: "Which notification service to use" variables: default_tag: "notify-{{ now() }}" message_tag: "{{ tag if (tag is defined and tag != '') else default_tag }}" sequence: - - service: notify.mobile_app_iphone_13_pro_max + - service: "{{ notification_service }}" data: - title: "{{ title }}" + title: "{{title}}" message: "{{message}}" data: tag: "{{message_tag}}" - condition: template value_template: "{{ expire is defined }}" - delay: "{{ expire }}" - - service: notify.mobile_app_iphone_13_pro_max + - service: "{{ notification_service }}" data: message: clear_notification data: tag: "{{message_tag}}" -# This is an asynchronous wrapper around the 'notify_joris_sync' script. -# It allows for clean syntactic sugar, i.e. being able to use script.notify_joris +######################################################################################################################## +# Below are asynchronous wrappers around the 'notify_sync' script. +# These allow for clean syntactic sugar, i.e. being able to use script.notify_joris, script.notify_family, etc # instead of script.turn_on and setting an additional entity_id, while still asynchronously # deliverying messages. This is especially useful when there's an 'expire' set for -# a notification as the 'notify_joris_sync' script will be blocking until the message +# a notification as the 'notify_sync' script will be blocking until the message # has expired. notify_joris: mode: parallel sequence: - service: script.turn_on - entity_id: script.notify_joris_sync + entity_id: script.notify_sync + data: + variables: + notification_service: "notify.mobile_app_iphone_13_pro_max" + title: "{{title}}" + message: "{{message}}" + expire: "{{expire}}" + tag: "{{tag}}" + +notify_family: + mode: parallel + sequence: + - service: script.turn_on + entity_id: script.notify_sync data: variables: + notification_service: "notify.family" title: "{{title}}" message: "{{message}}" expire: "{{expire}}" diff --git a/sensors/binary.yaml b/sensors/binary.yaml index be01047..abcae01 100644 --- a/sensors/binary.yaml +++ b/sensors/binary.yaml @@ -34,10 +34,13 @@ name: Is Afternoon after: "12:00" before: "18:00" -# - platform: trend -# sensors: -# cooking_trend: -# entity_id: sensor.kitchen_hood_temperature -# sample_duration: 30 -# max_samples: 10 -# min_gradient: 0.05 + +- platform: trend + sensors: + cooking_started: + entity_id: sensor.kitchen_hood_temperature + sample_duration: 60 + max_samples: 10 + # The gradient is measured in sensor units per second + # We want to trigger if there's a 1.5C change in 60s, so gradient should be: 1.5/60 = 0.025 + min_gradient: 0.025 diff --git a/sensors/sensor.yaml b/sensors/sensor.yaml index 6094454..3316336 100644 --- a/sensors/sensor.yaml +++ b/sensors/sensor.yaml @@ -48,6 +48,5 @@ days: 30 - platform: command_line - name: UDMPRO CPU Temperature - command: "commandline/udmpro-temp.sh" - unit_of_measurement: "°C" + name: Unifi Stats + command: "commandline/unifi-stats.sh" diff --git a/templates/sensor.yaml b/templates/sensor.yaml index 6b8dff6..11550de 100644 --- a/templates/sensor.yaml +++ b/templates/sensor.yaml @@ -22,3 +22,37 @@ - name: "Sauna Session Duration Minutes" unit_of_measurement: "min" state: "{{ states('sensor.sauna_session_duration') | float * 60 | int }}" + + - name: "UDMPRO CPU Temperature" + unit_of_measurement: "°C" + state: "{{ states('sensor.unifi_stats').split('|')[0] }}" + + - name: "UDMPRO CPU Usage" + unit_of_measurement: "%" + state: "{{ states('sensor.unifi_stats').split('|')[1] }}" + + - name: "UDMPRO Memory Usage" + unit_of_measurement: "%" + state: "{{ states('sensor.unifi_stats').split('|')[2] }}" + + - name: "UDMPRO Uptime Secs" + unit_of_measurement: "sec" + state: "{{ states('sensor.unifi_stats').split('|')[3] }}" + + - name: "UDMPRO Uptime" + state: "{{ (now() - timedelta(seconds=states('sensor.unifi_stats').split('|')[3] | int)) | relative_time }}" + + - name: "USW24POE CPU Usage" + unit_of_measurement: "%" + state: "{{ states('sensor.unifi_stats').split('|')[4] }}" + + - name: "USW24POE Memory Usage" + unit_of_measurement: "%" + state: "{{ states('sensor.unifi_stats').split('|')[5] }}" + + - name: "USW24POE Uptime Secs" + unit_of_measurement: "sec" + state: "{{ states('sensor.unifi_stats').split('|')[6] }}" + + - name: "USW24POE Uptime" + state: "{{ (now() - timedelta(seconds=states('sensor.unifi_stats').split('|')[6] | int)) | relative_time }}" \ No newline at end of file