Home Assistant Git Exporter
parent
fa8e399ee8
commit
715aefffd3
|
@ -1,44 +0,0 @@
|
|||
check:
|
||||
check_for_ips: false
|
||||
check_for_secrets: true
|
||||
enabled: true
|
||||
dry_run: false
|
||||
exclude:
|
||||
- '*.db'
|
||||
- '*.log*'
|
||||
- __pycache__
|
||||
- ._*
|
||||
- .DS_Store
|
||||
- deps/
|
||||
- known_devices.yaml
|
||||
- tts/
|
||||
- '*.tmp'
|
||||
- '*.swp'
|
||||
- '*.bak'
|
||||
- .nvimlog
|
||||
- build/
|
||||
- '*.fault'
|
||||
- secrets.yaml
|
||||
- esphome/common/secrets.yaml
|
||||
- .stversions
|
||||
- custom_components
|
||||
- .st*
|
||||
- ~*-*.yaml
|
||||
- log.text
|
||||
- /www/
|
||||
- .local/
|
||||
- .vscode/
|
||||
- .cache/
|
||||
- .bash_history
|
||||
export:
|
||||
addons: true
|
||||
esphome: true
|
||||
lovelace: true
|
||||
node_red: true
|
||||
repository:
|
||||
branch_name: main
|
||||
commit_message: Home Assistant Git Exporter
|
||||
password: '!secret git_export_token'
|
||||
pull_before_push: true
|
||||
url: '!secret git_export_url'
|
||||
username: '!secret git_export_token'
|
|
@ -1,6 +0,0 @@
|
|||
folders:
|
||||
- /config
|
||||
private_key_file: /ssl/rsync/id_rsa
|
||||
remote_folder: /home/user
|
||||
remote_host: ''
|
||||
username: user
|
|
@ -1 +0,0 @@
|
|||
{}
|
|
@ -1,9 +0,0 @@
|
|||
data_path: /config/zigbee2mqtt
|
||||
mqtt: {}
|
||||
serial: {}
|
||||
socat:
|
||||
enabled: false
|
||||
log: false
|
||||
master: pty,raw,echo=0,link=/tmp/ttyZ2M,mode=777
|
||||
options: -d -d
|
||||
slave: tcp-listen:8485,keepalive,nodelay,reuseaddr,keepidle=1,keepintvl=1,keepcnt=5
|
|
@ -1,11 +0,0 @@
|
|||
databases:
|
||||
- homeassistant
|
||||
init_commands: []
|
||||
max_connections: 20
|
||||
system_packages: []
|
||||
timescale_enabled:
|
||||
- homeassistant
|
||||
timescaledb:
|
||||
maxcpus: '4'
|
||||
maxmemory: 512MB
|
||||
telemetry: basic
|
|
@ -1 +0,0 @@
|
|||
db: '!secret recorder_db'
|
|
@ -1 +0,0 @@
|
|||
leave_front_door_open: true
|
|
@ -1,16 +0,0 @@
|
|||
certfile: fullchain.pem
|
||||
credential_secret: '!secret nodered_secret'
|
||||
dark_mode: false
|
||||
http_node:
|
||||
password: ''
|
||||
username: ''
|
||||
http_static:
|
||||
password: ''
|
||||
username: ''
|
||||
init_commands: []
|
||||
keyfile: privkey.pem
|
||||
npm_packages: []
|
||||
require_ssl: false
|
||||
ssl: false
|
||||
system_packages: []
|
||||
theme: default
|
|
@ -1,3 +0,0 @@
|
|||
api_auth_token: G5XtXp31iwh1Xl0yfaGaXc317Oo9JgVB
|
||||
networks:
|
||||
- 17d709436c21ca93
|
|
@ -1,4 +0,0 @@
|
|||
days_between_backups: 3
|
||||
max_backups_in_google_drive: 4
|
||||
max_backups_in_ha: 4
|
||||
send_error_reports: true
|
|
@ -1,9 +0,0 @@
|
|||
dirsfirst: false
|
||||
enforce_basepath: true
|
||||
git: true
|
||||
ignore_pattern:
|
||||
- __pycache__
|
||||
- .cloud
|
||||
- .storage
|
||||
- deps
|
||||
ssh_keys: []
|
|
@ -1,13 +0,0 @@
|
|||
certfile: fullchain.pem
|
||||
customize:
|
||||
active: false
|
||||
folder: mosquitto
|
||||
keyfile: privkey.pem
|
||||
logins:
|
||||
- password: '!secret mosquitto_espresense_password'
|
||||
username: espresense
|
||||
- password: '!secret mosquitto_esphome_password'
|
||||
username: esphome
|
||||
- password: '!secret mosquitto_zigbee2mqtt_password'
|
||||
username: zigbee2mqtt
|
||||
require_certificate: false
|
|
@ -1,13 +0,0 @@
|
|||
allow_hosts:
|
||||
- '!secret lan_subnet'
|
||||
- '!secret docker_subnet'
|
||||
compatibility_mode: false
|
||||
password: '!secret samba_password'
|
||||
username: '!secret samba_username'
|
||||
veto_files:
|
||||
- ._*
|
||||
- .DS_Store
|
||||
- Thumbs.db
|
||||
- icon?
|
||||
- .Trashes
|
||||
workgroup: WORKGROUP
|
|
@ -1,12 +0,0 @@
|
|||
apks:
|
||||
- neovim
|
||||
- postgresql-client
|
||||
- bat
|
||||
authorized_keys:
|
||||
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3TLYeC/VkgBdsabbhRDG5mdTgIsjvE2046Pir4DQFb
|
||||
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILIusX84DqZiOvTKgjD481KIF5gH5XZcC26AIo4y/E9M
|
||||
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCequm1RHBiWwfCRPcKc+I8ptsIwj5dW3O9ETbKbnkqkZv6Ent2nm5zVYK7YdmS2IEhcZtCZVmOOc+m0xH4/x5aRH7HnUtP1De72HTrR82yvOMa4uOsgF73Sb3Fo94UXT+9C3jdWiemiNVB87szi6RQxRTRxcEsX76r6ViMSigEPAviuNWiGMbmw+5hVJhVq4Vv8C6wN3C7F2GrKkSuorr5e7oXluaSEg5rgusuQn637dSK1kbJSeda4qsdaOj5zrOPYWxT/HkZLvAOnwz1XuLl+uLQVrkikFp3mXrYT8jarbt6q3e95JpA2SQJVZNpCL55akUUVEr7FocxOmGS7awprYI3PDryCbmTHp64mx/6XzhRDhYYnauKMu1nnU3pasCj2kCaFg1k9Ficq9o6yWpRGxvUb5ZPAE06YlTwXeEHFATIA/GXdi33G60Zjd0kmfEjbjOOihU+Oxvg7vCzFVHsg2qL5/8KpVHP7kpkYANgjjSvZE3zl2IKOMLvlBslpmcYX/GN/J5Ln0BSi1lw0e51PQePhVZC6Wqt1jQ2NMQ9BJRFWSNAraEeU2Df+GlJUF2yoDU0vVpSYETTpTZt6l2u/L3h+/YElWpZNAba1Y7EqvXgKF9C/DCZteAxXXcOmdNeUYrJnKD2er9vG5JqN0R5Fvws77R+fSc6ldrH1Ft7EQ==
|
||||
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJykg+5TulcwmeKFYSjZmnrL5/Fo4kWmOV1fAyt41Evh
|
||||
password: ''
|
||||
server:
|
||||
tcp_forwarding: false
|
|
@ -1,3 +1,23 @@
|
|||
Add-On Repository for Cloudflare:
|
||||
maintainer: Tobia Brenner <https://github.com/brenner-tobias/>
|
||||
slug: 9074a9fa
|
||||
source: https://github.com/brenner-tobias/ha-addons
|
||||
Alex's Add-ons Shack:
|
||||
maintainer: Alex van den Hoogen <homeassistant@alxx.nl>
|
||||
slug: 2ca71ec5
|
||||
source: https://github.com/alex3305/home-assistant-addons
|
||||
B Tasker HomeAssistant Addons:
|
||||
maintainer: B Tasker
|
||||
slug: 93f0ddc5
|
||||
source: https://github.com/bentasker/HomeAssistantAddons
|
||||
EMHASS Add-on Energy Management for Home Assistant:
|
||||
maintainer: David HERNANDEZ <davidusb@gmail.com>
|
||||
slug: 5b918bf2
|
||||
source: https://github.com/davidusb-geek/emhass-add-on
|
||||
ESPHome:
|
||||
maintainer: ESPHome <esphome@nabucasa.com>
|
||||
slug: 5c53de3b
|
||||
source: https://github.com/esphome/home-assistant-addon
|
||||
Expaso Home Assistant Add-Ons:
|
||||
maintainer: Hans van Essen <hans@expaso.nl>
|
||||
slug: 77b2833f
|
||||
|
@ -6,10 +26,6 @@ Frigate hass.io addons:
|
|||
maintainer: blakeblackshear
|
||||
slug: ccab4aaf
|
||||
source: https://github.com/blakeblackshear/frigate-hass-addons
|
||||
HA Add-ons by alexbelgium:
|
||||
maintainer: alexbelgium
|
||||
slug: db21ed7f
|
||||
source: https://github.com/alexbelgium/hassio-addons
|
||||
Hass.io add-ons by Nicolai:
|
||||
maintainer: Nicolai Bjerre Pedersen
|
||||
slug: 0844df1a
|
||||
|
@ -26,35 +42,23 @@ Home Assistant Google Drive Backup Repository:
|
|||
maintainer: Stephen Beechen <stephen@beechens.com>
|
||||
slug: cebe7a76
|
||||
source: https://github.com/sabeechen/hassio-google-drive-backup
|
||||
Local add-ons:
|
||||
maintainer: you
|
||||
slug: local
|
||||
source: local
|
||||
MickMake Hass.io Add-ons:
|
||||
maintainer: MickMake <embed@mickmake.com>
|
||||
slug: ba22da74
|
||||
source: https://github.com/MickMake/HomeAssistantAddons
|
||||
Official add-ons:
|
||||
maintainer: Home Assistant
|
||||
slug: core
|
||||
source: core
|
||||
Poeschl Home Assistant Add-ons:
|
||||
maintainer: Poeschl <Poeschl@users.noreply.github.com>
|
||||
slug: 243ffc37
|
||||
source: https://github.com/Poeschl/Hassio-Addons
|
||||
Sanderdw's add-on repository:
|
||||
maintainer: Sander de Wildt <sanderdw@gmail.com>
|
||||
slug: 0826754b
|
||||
source: https://github.com/sanderdw/hassio-addons
|
||||
Tom's Home Assistant Add-ons:
|
||||
maintainer: Thomas Mauerer
|
||||
slug: 15d21743
|
||||
source: https://github.com/thomasmauerer/hassio-addons
|
||||
Shortumations:
|
||||
maintainer: Ari Sosnovsky <ariel@sosnovsky.ca>
|
||||
slug: 04377e81
|
||||
source: https://github.com/asosnovsky/Shortumation
|
||||
TenySmart Hass.io Add-ons:
|
||||
maintainer: TTVTien <ttvtien@gmail.com>
|
||||
slug: 4ee6ccd4
|
||||
source: https://github.com/TenySmart/HassioAddon
|
||||
bjeanes Home Assistant add-on repository:
|
||||
maintainer: Bo Jeanes <hassio@bjeanes.com>
|
||||
slug: 9c51689a
|
||||
source: https://github.com/bjeanes/hassio-addons
|
||||
bjeanes' fork of Poeschl Home Assistant Add-ons:
|
||||
maintainer: bjeanes <bjeanes@users.noreply.github.com>
|
||||
slug: 61c150fb
|
||||
source: https://github.com/bjeanes/Poeschl-Hassio-Addons
|
||||
|
|
|
@ -1 +1 @@
|
|||
2022.7.5
|
||||
2022.8.5
|
|
@ -22,6 +22,7 @@ recorder:
|
|||
http:
|
||||
use_x_forwarded_for: true
|
||||
trusted_proxies:
|
||||
- !secret docker_subnet
|
||||
- !secret lan_subnet
|
||||
- !secret iot_subnet
|
||||
- !secret not_subnet
|
||||
|
@ -33,6 +34,7 @@ logger:
|
|||
default: warning
|
||||
logs:
|
||||
homeassistant.loader: error
|
||||
custom_components.magic_areas: debug
|
||||
|
||||
ffmpeg:
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
switch:
|
||||
- platform: command_line
|
||||
- platform: command_line # TODO: turn this into https://www.home-assistant.io/integrations/switch.rest/
|
||||
switches:
|
||||
3d_printer_connection:
|
||||
# 3d_printer_command_on: /usr/bin/curl -m 10 -d '{"command":"connect"}' -H 'Content-Type: application/json' -H 'X-Api-Key: REDACTED' http://REDACTED/api/connection
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
# This file just includes dummy entities for each integration which I use infrequently. It forces the integration to
|
||||
# load so that I can reload the YAML instead of having to restart HA in the case where I am adding/enabling the first
|
||||
# entity from that integration.
|
||||
|
||||
sensor:
|
||||
- platform: statistics # Force statistics integration to be loaded (even if no other sensors) so I can reload without restarting HA
|
||||
name: "dummy_statistics"
|
||||
unique_id: dummy
|
||||
entity_id: sensor.energy_production_tomorrow
|
||||
|
||||
- platform: filter # Force filter integration to be loaded (even if no other sensors) so I can reload without restarting HA
|
||||
name: "dummy_filter"
|
||||
unique_id: dummy
|
||||
entity_id: sensor.energy_production_tomorrow
|
||||
filters:
|
||||
- filter: lowpass
|
|
@ -1,8 +1,138 @@
|
|||
# See also sungrow.yaml
|
||||
|
||||
utility_meter:
|
||||
monthly_energy_import:
|
||||
source: sensor.eagle_200_total_meter_energy_delivered
|
||||
name: Energy imported
|
||||
cycle: monthly
|
||||
tariffs:
|
||||
- peak
|
||||
- offpeak
|
||||
|
||||
daily_energy_import:
|
||||
source: sensor.eagle_200_total_meter_energy_delivered
|
||||
name: Energy imported
|
||||
cycle: daily
|
||||
tariffs:
|
||||
- peak
|
||||
- offpeak
|
||||
|
||||
monthly_energy_export:
|
||||
source: sensor.eagle_200_total_meter_energy_received
|
||||
name: Energy exported
|
||||
cycle: monthly
|
||||
|
||||
daily_energy_export:
|
||||
source: sensor.eagle_200_total_meter_energy_received
|
||||
name: Energy exported
|
||||
cycle: daily
|
||||
|
||||
automation:
|
||||
- id: b508954f792ff8483254
|
||||
alias: Change electricity tariff
|
||||
mode: single
|
||||
trigger:
|
||||
- platform: time
|
||||
at: "15:00:00"
|
||||
variables:
|
||||
tariff: peak
|
||||
- platform: time
|
||||
at: "21:00:00"
|
||||
variables:
|
||||
tariff: offpeak
|
||||
action:
|
||||
- service: select.select_option
|
||||
target:
|
||||
entity_id:
|
||||
- select.monthly_energy_import
|
||||
- select.daily_energy_import
|
||||
data:
|
||||
option: "{{ tariff }}"
|
||||
|
||||
- id: 4f863af550147e9b3170
|
||||
alias: update pvoutput
|
||||
trigger:
|
||||
platform: time_pattern
|
||||
minutes: /5
|
||||
action:
|
||||
service: rest_command.update_pvoutput
|
||||
data: {}
|
||||
mode: single
|
||||
|
||||
rest_command:
|
||||
# https://pvoutput.org/help/api_specification.html#id1
|
||||
update_pvoutput:
|
||||
url: https://pvoutput.org/service/r2/addstatus.jsp
|
||||
method: post
|
||||
headers:
|
||||
Host: pvoutput.org
|
||||
User-Agent: HomeAssistant
|
||||
X-Pvoutput-Apikey: !secret pvoutput_api_key
|
||||
X-Pvoutput-SystemId: !secret pvoutput_system_id
|
||||
payload: >-
|
||||
d={{now().strftime("%Y%m%d")}} {#- date -#}
|
||||
&t={{now().strftime("%H:%M")}} {#- time -#}
|
||||
&c1=2 {#- cumulative mode -#}
|
||||
&v1={{(states('sensor.inverter_pv_generation_today')|float * 1000)|round(0) }}
|
||||
{#- energy generation (Wh) -#}
|
||||
&v2={{states('sensor.inverter_active_power')|float|round(0)}} {#- power generation (W) -#}
|
||||
&v3= {#- energy consumption (Wh) -#}
|
||||
&v4={{states('sensor.household_power_demand')|float|round(0)}} {#- power consumption (W) -#}
|
||||
{#- &v5={{states('sensor.home_weather_temperature')|float|round(1)}} {#- panel temperature? -#}
|
||||
&v6={{states('sensor.inverter_phase_a_voltage')|float|round(1)}} {#- voltage -#}
|
||||
content_type: "application/x-www-form-urlencoded"
|
||||
|
||||
sensor:
|
||||
# entity_id: sensor.inverter_grid_power_demand
|
||||
# state_characteristic: average_linear
|
||||
# max_age: "00:05"
|
||||
# - platform: statistics
|
||||
# name: "Eagle-200 meter power demand (smooth)"
|
||||
# unique_id: 5596672fba54c89c2131
|
||||
# entity_id: sensor.eagle_200_meter_power_demand_w
|
||||
# state_characteristic: average_linear
|
||||
# max_age: "00:05"
|
||||
|
||||
# - platform: filter
|
||||
# name: "Inverter grid power demand (smooth)"
|
||||
# unique_id: 88bfc3a211f1540c90cf
|
||||
# entity_id: sensor.inverter_grid_power_demand
|
||||
# filters:
|
||||
# - filter: lowpass
|
||||
# time_constant: 30
|
||||
# - filter: time_simple_moving_average
|
||||
# window_size: "00:02"
|
||||
|
||||
# - platform: filter
|
||||
# name: "Eagle-200 meter power demand (smooth)"
|
||||
# unique_id: 5596672fba54c89c2131
|
||||
# entity_id: sensor.eagle_200_meter_power_demand_w
|
||||
# filters:
|
||||
# - filter: lowpass
|
||||
# time_constant: 30
|
||||
# - filter: time_simple_moving_average
|
||||
# window_size: "00:02"
|
||||
|
||||
- platform: template
|
||||
sensors:
|
||||
# energy_import_price:
|
||||
# unique_id: 2b80f57455c84e873952
|
||||
# friendly_name: Energy import price
|
||||
# value_template: >-
|
||||
# {%- if is_state('select.daily_energy_import', 'peak') -%}
|
||||
# 0.23320
|
||||
# {%- else -%}
|
||||
# 0.15235
|
||||
# {%- endif -%}
|
||||
# unit_of_measurement: AUD
|
||||
# device_class: monetary
|
||||
# energy_export_price:
|
||||
# unique_id: a661839f99fbc85e23d9
|
||||
# friendly_name: Energy export price
|
||||
# value_template: "0.067"
|
||||
# unit_of_measurement: AUD
|
||||
# device_class: monetary
|
||||
|
||||
eagle_200_meter_power_demand_w:
|
||||
unique_id: 528a94ffdd069f6f5dcd
|
||||
friendly_name: Eagle-200 Meter Power Demand (W)
|
||||
|
@ -48,6 +178,20 @@ sensor:
|
|||
unit_of_measurement: W
|
||||
device_class: power
|
||||
|
||||
inverter_demand_gap_perc:
|
||||
unique_id: 12b4d474286fab17319d
|
||||
friendly_name: Inverter demand gap %
|
||||
value_template: >-
|
||||
{{ 100 * (-1 * states('sensor.inverter_export_power') | float) / (states('sensor.eagle_200_meter_power_demand_w') | float) }}
|
||||
unit_of_measurement: "%"
|
||||
|
||||
# inverter_demand_gap_perc_smooth:
|
||||
# unique_id: ad811b463d9a0a332c62
|
||||
# friendly_name: Inverter demand gap % (smooth)
|
||||
# value_template: >-
|
||||
# {{ 100 * states('sensor.inverter_grid_power_demand_smooth') | float / states('sensor.eagle_200_meter_power_demand_smooth') | float }}
|
||||
# unit_of_measurement: "%"
|
||||
|
||||
current_electricity_cost:
|
||||
unique_id: current_electricity_cost
|
||||
value_template: |
|
||||
|
|
|
@ -7,6 +7,8 @@ homeassistant:
|
|||
return 'mdi:bed';
|
||||
return 'mdi:bed-empty';
|
||||
|
||||
magic_areas:
|
||||
|
||||
proximity:
|
||||
bo_home:
|
||||
zone: home
|
||||
|
@ -38,6 +40,26 @@ group:
|
|||
- input_boolean.ri_in_bed
|
||||
|
||||
automation:
|
||||
- id: 29b7b074ebcbfa873522
|
||||
alias: turn off lights when everyone is in bed
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: binary_sensor.everyone_in_bed
|
||||
from: "off"
|
||||
to: "on"
|
||||
for:
|
||||
minutes: 1
|
||||
action:
|
||||
- service: light.turn_off
|
||||
target:
|
||||
entity_id: all
|
||||
- service: light.turn_on
|
||||
data:
|
||||
color_temp: 462
|
||||
brightness_pct: 10
|
||||
target:
|
||||
entity_id: light.sconce
|
||||
|
||||
- id: not_in_bed
|
||||
alias: No longer in bed when phone leaves room
|
||||
trigger:
|
||||
|
@ -143,6 +165,7 @@ homekit:
|
|||
- switch.bo_s_office_plug
|
||||
- switch.bos_office_heater
|
||||
- switch.ri_s_desk_plug
|
||||
|
||||
include_entity_globs:
|
||||
- binary_sensor.*_is_occupied
|
||||
- binary_sensor.*_motion
|
||||
|
@ -160,6 +183,7 @@ homekit:
|
|||
- "sensor.*freezer*"
|
||||
- "sensor.*cure*"
|
||||
- "sensor.*stash*"
|
||||
- light.shelly_*
|
||||
- sensor.*garden*
|
||||
- sensor.*battery_temperature*
|
||||
- sensor.*forecast*
|
||||
|
@ -171,3 +195,9 @@ homekit:
|
|||
vacuum.robot_vacuum:
|
||||
linked_battery_sensor: sensor.robot_vacuum_battery_level
|
||||
linked_battery_charging_sensor: binary_sensor.robot_vacuum_charging
|
||||
|
||||
- name: shelly
|
||||
port: 21225
|
||||
filter:
|
||||
include_entity_globs:
|
||||
- light.shelly_*
|
||||
|
|
|
@ -183,6 +183,16 @@ media_player:
|
|||
device_class: sensor.current_living_room_media|device_class
|
||||
|
||||
automation:
|
||||
- id: sign_into_heos
|
||||
trigger:
|
||||
- platform: time_pattern
|
||||
hours: "1"
|
||||
action:
|
||||
- service: heos.sign_in
|
||||
data:
|
||||
username: !secret heos_username
|
||||
password: !secret heos_password
|
||||
|
||||
- id: turn_on_apple_tv_on_source
|
||||
trigger:
|
||||
- platform: state
|
||||
|
@ -214,7 +224,7 @@ automation:
|
|||
- variables:
|
||||
current_volume_level: "{{ state_attr('media_player.denon_avr_x1600h', 'volume_level') }}"
|
||||
|
||||
# TODO model as a dictionary https://community.home-assistant.io/t/remember-volume-levels-of-each-source-for-a-media-player-to-automate-restoring/416749/6?u=bjeanes
|
||||
# TODO model as a dictionary https://community.home-assistant.io/t/remember-volume-levels-of-each-source-for-a-media-player-to-automate-restoring/416749/6?u=bjeanes #!notsecret!#
|
||||
new_volume_level: >-
|
||||
{% set volumes = state_attr('sensor.living_room_media_player_source_volumes', 'volumes') or [] %}
|
||||
{% set specific_source = state_attr('media_player.living_room_media_player', 'source') %}
|
||||
|
|
|
@ -32,6 +32,8 @@ anniversaries:
|
|||
date: "1987-02-17"
|
||||
- name: Jordon's Birthday
|
||||
date: "02-19"
|
||||
- name: Skye's Birthday
|
||||
date: "07-30"
|
||||
- name: Kate's Birthday
|
||||
date: "03-20"
|
||||
- name: Nick's Birthday
|
||||
|
@ -58,3 +60,5 @@ anniversaries:
|
|||
date: "05-05"
|
||||
- name: Alex Charry's Birthday
|
||||
date: "08-06"
|
||||
- name: Em Cheesman's Birthday
|
||||
date: "07-20"
|
||||
|
|
|
@ -21,3 +21,114 @@ switch:
|
|||
mac: !secret tumtum_mac
|
||||
host: !secret tumtum_ip
|
||||
broadcast_address: !secret lan_broadcast
|
||||
turn_off:
|
||||
- service: shell_command.shutdown_host
|
||||
data:
|
||||
host: !secret tumtum_ip
|
||||
|
||||
- platform: wake_on_lan
|
||||
name: NAS
|
||||
mac: !secret nas_mac
|
||||
host: !secret nas_ip
|
||||
broadcast_address: !secret lan_broadcast
|
||||
turn_off:
|
||||
service: button.press
|
||||
target:
|
||||
entity_id: button.nas_shutdown
|
||||
|
||||
automation:
|
||||
- id: 964db306d8b009f8f640
|
||||
alias: Power NAS/Tumtum according to sleep
|
||||
trigger:
|
||||
- platform: template
|
||||
value_template: |
|
||||
{{
|
||||
is_state('sensor.everyone_in_bed', 'on') and
|
||||
is_state('sensor.plex_tumtum_tree', '0')
|
||||
}}
|
||||
for:
|
||||
minutes: 15
|
||||
variables:
|
||||
service: switch.turn_off
|
||||
- platform: template
|
||||
value_template: |
|
||||
{{ is_state('sensor.everyone_in_bed', 'off') }}
|
||||
for:
|
||||
minutes: 15
|
||||
variables:
|
||||
service: switch.turn_on
|
||||
action:
|
||||
- service: "{{ service }}"
|
||||
target:
|
||||
entity_id:
|
||||
- switch.nas
|
||||
- switch.tumtum
|
||||
|
||||
- id: 8bec9ab03377b5202cad
|
||||
alias: Power NAS/Tumtum according to UPS
|
||||
mode: restart # so we only do latest
|
||||
trigger: # https://www.home-assistant.io/docs/automation/trigger/#event-trigger
|
||||
- platform: event
|
||||
event_type: nut.ups_event
|
||||
event_data:
|
||||
notify_type: ONBATT # on battery
|
||||
variables:
|
||||
direction: "off"
|
||||
seconds: 120
|
||||
- platform: event
|
||||
event_type: nut.ups_event
|
||||
event_data:
|
||||
notify_type: LOWBAT # low battery
|
||||
variables:
|
||||
direction: "off"
|
||||
seconds: 10
|
||||
- platform: event
|
||||
event_type: nut.ups_event
|
||||
event_data:
|
||||
notify_type: FSD # forced shutdown
|
||||
variables:
|
||||
direction: "off"
|
||||
seconds: 3
|
||||
- platform: event
|
||||
event_type: nut.ups_event
|
||||
event_data:
|
||||
notify_type: SHUTDOWN # system is shutting down
|
||||
variables:
|
||||
direction: "off"
|
||||
seconds: 0
|
||||
- platform: event
|
||||
event_type: nut.ups_event
|
||||
event_data:
|
||||
notify_type: ONLINE # system is (back) online
|
||||
variables:
|
||||
direction: "on"
|
||||
seconds: 120
|
||||
action:
|
||||
- delay: "{{ seconds }}"
|
||||
- service: "switch.turn_{{ direction }}"
|
||||
target:
|
||||
entity_id:
|
||||
- switch.nas
|
||||
- switch.tumtum
|
||||
|
||||
- id: 0300364ca8c814c4c325
|
||||
alias: "Notify on UPS state change"
|
||||
trigger:
|
||||
- platform: event
|
||||
event_type: nut.ups_event
|
||||
action:
|
||||
- service: notify.mobile_app_bos_iphone
|
||||
data_template:
|
||||
title: "UPS changed state"
|
||||
message: "{{ trigger.event.data.notify_msg }}"
|
||||
data:
|
||||
push:
|
||||
interruption-level: time-sensitive
|
||||
|
||||
shell_command:
|
||||
# NOTE: make sure connecting user can execute specified sudo command without password on remote host
|
||||
# See https://askubuntu.com/questions/168879/shutdown-from-terminal-without-entering-password, https://wiki.archlinux.org/title/allow_users_to_shutdown, https://toroid.org/sudoers-syntax
|
||||
reboot_host: >
|
||||
ssh -i /config/.ssh/id_rsa -o 'StrictHostKeyChecking=no' -l {% if user is defined %}{{user}}{%else%}homeassistant{% endif %} {{host}} -- 'sudo reboot'
|
||||
shutdown_host: >
|
||||
ssh -i /config/.ssh/id_rsa -o 'StrictHostKeyChecking=no' -l {% if user is defined %}{{user}}{%else%}homeassistant{% endif %} {{host}} -- 'sudo poweroff'
|
||||
|
|
|
@ -27,9 +27,142 @@
|
|||
# {% else %} 204 {% endif %}"
|
||||
# hub: SungrowSHx
|
||||
# mode: single
|
||||
|
||||
input_datetime:
|
||||
inverter_charging_schedule_start:
|
||||
has_time: true
|
||||
name: Inverter charging schedule start
|
||||
initial: "13:30:00"
|
||||
inverter_charging_schedule_end:
|
||||
has_time: true
|
||||
name: Inverter charging schedule end
|
||||
initial: "14:59:00"
|
||||
input_number:
|
||||
inverter_charging_schedule_target_soc:
|
||||
name: Inverter charging target state of charge
|
||||
min: 0
|
||||
max: 100
|
||||
unit_of_measurement: "%"
|
||||
mode: box
|
||||
inverter_battery_reserve:
|
||||
name: Inverter battery reserve
|
||||
min: 0
|
||||
max: 100
|
||||
initial: 5
|
||||
unit_of_measurement: "%"
|
||||
mode: box
|
||||
|
||||
automation:
|
||||
- id: e7df7dc23815acacdd8c
|
||||
alias: Inverter - apply charging schedule
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id:
|
||||
- input_datetime.inverter_charging_schedule_start
|
||||
- input_datetime.inverter_charging_schedule_end
|
||||
- input_number.inverter_charging_schedule_target_soc
|
||||
not_from:
|
||||
- unknown
|
||||
- unavailable
|
||||
not_to:
|
||||
- unknown
|
||||
- unavailable
|
||||
action:
|
||||
- service: script.apply_charging_schedule
|
||||
data_template:
|
||||
soc_1: "{{ states('input_number.inverter_charging_schedule_target_soc') | int }}"
|
||||
start_time_1: "{{ states('input_datetime.inverter_charging_schedule_start') }}"
|
||||
end_time_1: "{{ states('input_datetime.inverter_charging_schedule_end') }}"
|
||||
|
||||
- id: 7b93d325bfe632a4e890
|
||||
alias: Inverter - update battery reserve
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id:
|
||||
- input_number.inverter_battery_reserve
|
||||
not_from:
|
||||
- unknown
|
||||
- unavailable
|
||||
not_to:
|
||||
- unknown
|
||||
- unavailable
|
||||
action:
|
||||
- service: script.inverter_set_battery_reserve
|
||||
data_template:
|
||||
reserved_percentage: >-
|
||||
{{ states('input_number.inverter_battery_reserve') | int }}
|
||||
|
||||
script:
|
||||
inverter_set_battery_reserve:
|
||||
alias: "Set inverter battery reserve"
|
||||
mode: restart
|
||||
fields:
|
||||
reserved_percentage:
|
||||
name: "Percentage"
|
||||
description: "Percentage of battery reserved for emergency power supply"
|
||||
required: true
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
max: 100
|
||||
step: 1
|
||||
unit_of_measurement: "%"
|
||||
sequence:
|
||||
- service: modbus.write_register
|
||||
data_template:
|
||||
address: 13099 # 13100
|
||||
slave: 1
|
||||
value: "{{ [ reserved_percentage | int ] }}"
|
||||
hub: SungrowSHx
|
||||
|
||||
# inverter_set_battery_mode:
|
||||
# alias: Set inverter battery mode
|
||||
# fields:
|
||||
# battery_power:
|
||||
# name: "Charge/discharge power"
|
||||
# description: "Charge/discharge power"
|
||||
# required: false
|
||||
# selector:
|
||||
# number:
|
||||
# min: 0
|
||||
# max: 6600
|
||||
# step: 1
|
||||
# unit_of_measurement: "W"
|
||||
|
||||
# battery_mode:
|
||||
# name: "Battery mode"
|
||||
# description: "Battery mode"
|
||||
# required: true
|
||||
# selector:
|
||||
# select:
|
||||
# options:
|
||||
# - label: Self-consumption
|
||||
# value: [0, 0xCC]
|
||||
# - label: Force charge
|
||||
# value: [2, 0xAA]
|
||||
# - label: Force discharge
|
||||
# value: [2, 0xBB]
|
||||
# - label: Stop
|
||||
# value: [2, 0xCC]
|
||||
# sequence:
|
||||
# - service: modbus.write_register
|
||||
# data_template:
|
||||
# address: 13049 # 13050-13051
|
||||
# slave: 1
|
||||
# # value: "{{ battery_mode }}"
|
||||
# value: |
|
||||
# {% if battery_power %}
|
||||
# {{ battery_mode + [battery_power|int] }}
|
||||
# {% else %}
|
||||
# {{ battery_mode }}
|
||||
# {% endif %}
|
||||
# hub: SungrowSHx
|
||||
|
||||
inverter_force_battery_charge:
|
||||
alias: "Inverter - force battery charge"
|
||||
mode: restart
|
||||
sequence:
|
||||
- service: modbus.write_register
|
||||
data_template:
|
||||
|
@ -39,6 +172,7 @@ script:
|
|||
hub: SungrowSHx
|
||||
inverter_force_battery_discharge:
|
||||
alias: "Inverter - force battery discharge"
|
||||
mode: restart
|
||||
sequence:
|
||||
- service: modbus.write_register
|
||||
data_template:
|
||||
|
@ -48,6 +182,7 @@ script:
|
|||
hub: SungrowSHx
|
||||
inverter_force_battery_stop:
|
||||
alias: "Inverter - force battery stop"
|
||||
mode: restart
|
||||
sequence:
|
||||
- service: modbus.write_register
|
||||
data_template:
|
||||
|
@ -57,6 +192,7 @@ script:
|
|||
hub: SungrowSHx
|
||||
inverter_self_consumption:
|
||||
alias: "Inverter - self consumption"
|
||||
mode: restart
|
||||
sequence:
|
||||
- service: modbus.write_register
|
||||
data_template:
|
||||
|
@ -65,6 +201,93 @@ script:
|
|||
value: [0, 0xCC]
|
||||
hub: SungrowSHx
|
||||
|
||||
# https://github.com/bohdan-s/SunGather/pull/63#issuecomment-1195049341
|
||||
apply_charging_schedule:
|
||||
alias: "Inverter - apply charging schedule"
|
||||
|
||||
# Q: is this evaluated _after_ field values are captured or before?
|
||||
variables:
|
||||
enable_value: 0xAA
|
||||
disable_value: 0x55
|
||||
every_day_value: 1
|
||||
is_enabled: "{{ (soc_1 is defined and soc_1 | int > 0) or (soc_2 is defined and soc_2 | int > 0) }}"
|
||||
sched_1: >
|
||||
{% if soc_1 is defined and soc_1 | int > 0 %}
|
||||
{{ [
|
||||
today_at(start_time_1).hour,
|
||||
today_at(start_time_1).minute,
|
||||
today_at(end_time_1).hour,
|
||||
today_at(end_time_1).minute,
|
||||
soc_1
|
||||
] }}
|
||||
{% else %}
|
||||
{{ [0, 0, 0, 0, 0] }}
|
||||
{% endif %}
|
||||
sched_2: >
|
||||
{% if soc_2 is defined and soc_2 | int > 0 %}
|
||||
{{ [
|
||||
today_at(start_time_2).hour,
|
||||
today_at(start_time_2).minute,
|
||||
today_at(end_time_2).hour,
|
||||
today_at(end_time_2).minute,
|
||||
soc_2
|
||||
] }}
|
||||
{% else %}
|
||||
{{ [0, 0, 0, 0, 0] }}
|
||||
{% endif %}
|
||||
bytes: >
|
||||
{% if is_enabled %}
|
||||
{{ [enable_value, every_day_value] + sched_1 + sched_2 }}
|
||||
{% else %}
|
||||
{{ [disable_value] }}
|
||||
{% endif %}
|
||||
|
||||
fields:
|
||||
start_time_1:
|
||||
name: Schedule 1 Start Time
|
||||
default: "13:30:00"
|
||||
selector:
|
||||
time:
|
||||
end_time_1:
|
||||
name: Schedule 1 End Time
|
||||
default: "14:59:00" # 3PM is on-peak charging
|
||||
selector:
|
||||
time:
|
||||
soc_1:
|
||||
name: Schedule 1 Target State-of-Charge
|
||||
default: 85
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
max: 100
|
||||
unit_of_measurement: "%"
|
||||
start_time_2:
|
||||
name: Schedule 2 Start Time
|
||||
default: "0:00:00"
|
||||
selector:
|
||||
time:
|
||||
end_time_2:
|
||||
name: Schedule 2 End Time
|
||||
default: "00:00:00"
|
||||
selector:
|
||||
time:
|
||||
soc_2:
|
||||
name: Schedule 2 Target State-of-Charge
|
||||
default: 0
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
max: 100
|
||||
unit_of_measurement: "%"
|
||||
|
||||
sequence:
|
||||
- service: modbus.write_register
|
||||
data_template:
|
||||
address: 33207 # 33208 - ...
|
||||
slave: 1
|
||||
value: "{{ bytes | list }}"
|
||||
hub: SungrowSHx
|
||||
|
||||
modbus:
|
||||
- name: SungrowSHx
|
||||
type: tcp
|
||||
|
|
|
@ -3,7 +3,7 @@ calendar:
|
|||
calendars:
|
||||
- name: "On-call"
|
||||
url: !secret oncall_schedule_url
|
||||
includeAllDay: true
|
||||
include_all_day: true
|
||||
days: 30
|
||||
|
||||
automation:
|
||||
|
@ -12,16 +12,14 @@ automation:
|
|||
- platform: state
|
||||
entity_id: cover.front_gate
|
||||
from: "closed"
|
||||
to: "open"
|
||||
- platform: state
|
||||
entity_id: cover.front_gate
|
||||
from: "closed"
|
||||
to: "opening"
|
||||
- platform: event
|
||||
event_type: homekit_state_change
|
||||
event_data:
|
||||
entity_id: cover.front_gate
|
||||
service: open_cover
|
||||
to:
|
||||
- open
|
||||
- opening
|
||||
# - platform: event
|
||||
# event_type: homekit_state_change
|
||||
# event_data:
|
||||
# entity_id: cover.front_gate
|
||||
# service: open_cover
|
||||
condition: >-
|
||||
{{ is_state('calendar.on_call', 'on') or is_state('calendar.ical_on_call', 'on') }}
|
||||
action:
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1 +1,39 @@
|
|||
homeassistant: true
|
||||
frontend:
|
||||
port: 8099
|
||||
permit_join: false
|
||||
mqtt:
|
||||
base_topic: zigbee2mqtt
|
||||
server: mqtt://core-mosquitto
|
||||
keepalive: 60
|
||||
reject_unauthorized: true
|
||||
version: 4
|
||||
serial:
|
||||
port: /dev/ttyACM0
|
||||
adapter: deconz
|
||||
devices:
|
||||
'0x804b50fffe100ed4':
|
||||
friendly_name: IKEA Remote
|
||||
'0x00158d0008091c32':
|
||||
friendly_name: Bo's Office Door
|
||||
debounce: 1
|
||||
filtered_attributes: []
|
||||
optimistic: true
|
||||
'0x00158d00080915bd':
|
||||
friendly_name: Ri's Office Door
|
||||
'0x00158d0007e7725b':
|
||||
friendly_name: Back Door
|
||||
'0x00158d0008091b58':
|
||||
friendly_name: Front Door
|
||||
'0x00158d0007e4c4f2':
|
||||
friendly_name: Fridge Door
|
||||
debounce: 1
|
||||
optimistic: true
|
||||
'0x5c0272fffee93bae':
|
||||
friendly_name: Bo's Office Motion Sensor
|
||||
'0x00124b002359ed4c':
|
||||
friendly_name: Ri's Office
|
||||
'0xa4c138fda4db2c5e':
|
||||
friendly_name: Bo's Office PIR 2
|
||||
'0x84b4dbfffe850fda':
|
||||
friendly_name: Unused presence sensor
|
||||
|
|
|
@ -1 +1,90 @@
|
|||
{}
|
||||
{
|
||||
"0x804b50fffe100ed4": {
|
||||
"battery": 100,
|
||||
"update": {
|
||||
"state": "available"
|
||||
},
|
||||
"update_available": true,
|
||||
"linkquality": 215
|
||||
},
|
||||
"0x00158d0008091c32": {
|
||||
"contact": false,
|
||||
"voltage": 2995,
|
||||
"battery": 41,
|
||||
"temperature": 19,
|
||||
"linkquality": 255,
|
||||
"device_temperature": 21,
|
||||
"power_outage_count": 8
|
||||
},
|
||||
"0x00158d00080915bd": {
|
||||
"contact": true,
|
||||
"voltage": 3005,
|
||||
"battery": 44,
|
||||
"temperature": 17,
|
||||
"linkquality": 255,
|
||||
"device_temperature": 16,
|
||||
"power_outage_count": 7
|
||||
},
|
||||
"0x00158d0007e7725b": {
|
||||
"contact": true,
|
||||
"voltage": 2975,
|
||||
"battery": 36,
|
||||
"temperature": 18,
|
||||
"linkquality": 255,
|
||||
"device_temperature": 18,
|
||||
"power_outage_count": 8
|
||||
},
|
||||
"0x00158d0008091b58": {
|
||||
"contact": false,
|
||||
"voltage": 3025,
|
||||
"battery": 50,
|
||||
"temperature": 12,
|
||||
"linkquality": 255,
|
||||
"device_temperature": 15,
|
||||
"power_outage_count": 13
|
||||
},
|
||||
"0x00158d0007e4c4f2": {
|
||||
"contact": true,
|
||||
"voltage": 2975,
|
||||
"battery": 36,
|
||||
"temperature": 21,
|
||||
"linkquality": 255,
|
||||
"device_temperature": 21,
|
||||
"power_outage_count": 41
|
||||
},
|
||||
"0x5c0272fffee93bae": {
|
||||
"occupancy": false,
|
||||
"tamper": false,
|
||||
"battery_low": false,
|
||||
"linkquality": 255
|
||||
},
|
||||
"0x00124b002359ed4c": {
|
||||
"voltage": 3000,
|
||||
"battery": 100,
|
||||
"occupancy": false,
|
||||
"tamper": false,
|
||||
"battery_low": false,
|
||||
"linkquality": 191
|
||||
},
|
||||
"0xa4c138fda4db2c5e": {
|
||||
"occupancy": true,
|
||||
"battery": 50,
|
||||
"sensitivity": "high",
|
||||
"keep_time": "120",
|
||||
"illuminance": 898,
|
||||
"linkquality": 127
|
||||
},
|
||||
"0x84b4dbfffe850fda": {
|
||||
"target_distance": 0,
|
||||
"presence": false,
|
||||
"maximum_range": 3,
|
||||
"radar_sensitivity": 2,
|
||||
"minimum_range": 0,
|
||||
"self_test": "check_success",
|
||||
"detection_delay": 0.1,
|
||||
"fading_time": 5,
|
||||
"cli": " ",
|
||||
"illuminance_lux": 0,
|
||||
"linkquality": 255
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
substitutions:
|
||||
device_name: athom-smart-plug-v2-3ff494
|
||||
name: athom-smart-plug-v2-3ff494
|
||||
friendly_name: Bo's Desk Plug
|
||||
friendly_name: Bo's Office Heater
|
||||
packages:
|
||||
athom.smart-plug-v2: github://athom-tech/athom-configs/athom-smart-plug-v2.yaml
|
||||
esphome:
|
||||
|
|
|
@ -10,6 +10,10 @@ packages:
|
|||
base: !include common/base.yaml
|
||||
ble: !include common/ble-gateway.yaml
|
||||
|
||||
web_server:
|
||||
version: 2
|
||||
include_internal: true
|
||||
|
||||
wifi:
|
||||
use_address: 10.10.30.82
|
||||
|
||||
|
|
|
@ -12,3 +12,7 @@ packages:
|
|||
|
||||
wifi:
|
||||
use_address: 10.10.30.120
|
||||
|
||||
web_server:
|
||||
version: 2
|
||||
include_internal: true
|
||||
|
|
|
@ -26,31 +26,31 @@ binary_sensor:
|
|||
number: GPIO4
|
||||
inverted: false
|
||||
mode: INPUT_PULLUP
|
||||
filters:
|
||||
# Takes advantage of the fact that gate movement causes this GPIO pin to
|
||||
# flicker (probably due to wire moving). We can use that initial change
|
||||
# in state as a signal to set the cover operation. Later, when the final
|
||||
# value settles (after debounces) we can set it back to idle.
|
||||
- lambda: |-
|
||||
if(id(gate).current_operation == CoverOperation::COVER_OPERATION_IDLE) {
|
||||
id(gate).current_operation = (x ? COVER_OPERATION_CLOSING : COVER_OPERATION_OPENING);
|
||||
id(gate).publish_state();
|
||||
}
|
||||
return x;
|
||||
# filters:
|
||||
# # Takes advantage of the fact that gate movement causes this GPIO pin to
|
||||
# # flicker (probably due to wire moving). We can use that initial change
|
||||
# # in state as a signal to set the cover operation. Later, when the final
|
||||
# # value settles (after debounces) we can set it back to idle.
|
||||
# - lambda: |-
|
||||
# if(id(gate).current_operation == CoverOperation::COVER_OPERATION_IDLE) {
|
||||
# id(gate).current_operation = (x ? COVER_OPERATION_CLOSING : COVER_OPERATION_OPENING);
|
||||
# id(gate).publish_state();
|
||||
# }
|
||||
# return x;
|
||||
|
||||
# during gate movement, the wire movement seems to cause the state to rapidly flicker
|
||||
- delayed_on_off: 5000ms
|
||||
# # during gate movement, the wire movement seems to cause the state to rapidly flicker
|
||||
# - delayed_on_off: 5000ms
|
||||
|
||||
- lambda: |-
|
||||
id(gate).current_operation = COVER_OPERATION_IDLE;
|
||||
id(gate).publish_state();
|
||||
return x;
|
||||
# - lambda: |-
|
||||
# id(gate).current_operation = COVER_OPERATION_IDLE;
|
||||
# id(gate).publish_state();
|
||||
# return x;
|
||||
|
||||
on_state:
|
||||
then:
|
||||
- cover.template.publish:
|
||||
id: gate
|
||||
current_operation: IDLE
|
||||
# on_state:
|
||||
# then:
|
||||
# - cover.template.publish:
|
||||
# id: gate
|
||||
# current_operation: IDLE
|
||||
|
||||
- platform: gpio
|
||||
pin:
|
||||
|
|
|
@ -57,6 +57,10 @@ config:
|
|||
max: 100
|
||||
min: 0
|
||||
opposite: true
|
||||
- entities:
|
||||
- entity: switch.nas
|
||||
- entity: switch.tumtum
|
||||
type: entities
|
||||
icon: mdi:wardrobe-outline
|
||||
path: server-closet
|
||||
theme: Backend-selected
|
||||
|
|
|
@ -2,143 +2,98 @@ config:
|
|||
views:
|
||||
- badges: []
|
||||
cards:
|
||||
- cards:
|
||||
- content: "{%- set household_usage =\n states('sensor.inverter_active_power')\
|
||||
\ | float +\n states('sensor.eagle_200_meter_power_demand_w') | float\n\
|
||||
-%}\n**Household usage:** {{ household_usage }} W\n**PV+Bat:** {{ states('sensor.inverter_battery_power')\
|
||||
\ | float + states('sensor.inverter_pv_power') | float }} W\n**Active (AC?):**\
|
||||
\ {{ states('sensor.inverter_active_power') | float }} W\n**AC from PV:**\
|
||||
\ {{ states('sensor.inverter_active_power') | float - states('sensor.inverter_battery_power')\
|
||||
\ | float }} W\n**Inverter Load (claimed):** {{ states('sensor.inverter_load_power')\
|
||||
\ | float }} W\n**Inverter Load (gap):** {{ states('sensor.inverter_load_power')\
|
||||
\ | float - household_usage }} W\n**{Im,Ex}port:** {{ states('sensor.eagle_200_meter_power_demand_w')\
|
||||
\ | float }} W\n"
|
||||
type: markdown
|
||||
title: Scratch
|
||||
type: custom:stack-in-card
|
||||
- cards:
|
||||
- entities:
|
||||
battery: sensor.inverter_battery_power
|
||||
battery_charge: sensor.inverter_battery_level
|
||||
grid: sensor.eagle_200_meter_power_demand
|
||||
grid: sensor.inverter_grid_power_demand
|
||||
solar: sensor.inverter_pv_power
|
||||
kw_decimals: 2
|
||||
type: custom:power-flow-card
|
||||
w_decimals: 0
|
||||
watt_threshold: 900
|
||||
- link_dashboard: true
|
||||
type: energy-distribution
|
||||
- entities:
|
||||
- entity: sensor.inverter_active_power
|
||||
name: Active (AC) power
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.inverter_reactive_power
|
||||
name: Reactive power
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.inverter_power_factor
|
||||
name: Power factor
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.inverter_pv_power
|
||||
name: PV Power
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.inverter_load_power
|
||||
name: Load power (inverter claimed)
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.household_power_demand
|
||||
name: Actual load
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.inverter_battery_power
|
||||
name: Battery power
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.inverter_grid_power_demand
|
||||
name: Grid demand (inverter)
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.eagle_200_meter_power_demand_w
|
||||
name: Grid demand (meter)
|
||||
secondary_info: last-updated
|
||||
type: entities
|
||||
- entities:
|
||||
- entity: sensor.inverter_grid_power_demand
|
||||
name: Grid demand (inverter)
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.eagle_200_meter_power_demand_w
|
||||
name: Grid demand (meter)
|
||||
secondary_info: last-updated
|
||||
hours_to_show: 6
|
||||
type: history-graph
|
||||
- entities:
|
||||
- entity: sensor.inverter_load_power
|
||||
name: Inverter's claimed load power
|
||||
- entity: sensor.household_power_demand
|
||||
name: Actual household power demand
|
||||
hours_to_show: 6
|
||||
type: history-graph
|
||||
- entities:
|
||||
- entity: sensor.inverter_load_gap
|
||||
name: Load gap
|
||||
- entity: sensor.inverter_demand_gap
|
||||
name: Demand gap
|
||||
hours_to_show: 6
|
||||
type: history-graph
|
||||
title: Power
|
||||
type: custom:stack-in-card
|
||||
- cards:
|
||||
- link_dashboard: false
|
||||
type: energy-distribution
|
||||
title: Energy (today)
|
||||
type: custom:stack-in-card
|
||||
- entities:
|
||||
- entity: sensor.inverter_pv_power
|
||||
name: PV Power
|
||||
- entity: sensor.inverter_active_power
|
||||
name: Active Power
|
||||
- entity: sensor.inverter_load_power
|
||||
name: Load power
|
||||
name: Active power
|
||||
secondary_info: last-updated
|
||||
hours_to_show: 6
|
||||
type: history-graph
|
||||
type: custom:stack-in-card
|
||||
- entities:
|
||||
- label: Today
|
||||
type: section
|
||||
- entity: sensor.solcast_forecast_today
|
||||
name: Total
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.solcast_forecast_remaining_today
|
||||
name: Remaining
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.solcast_forecast_this_hour
|
||||
format: kilo
|
||||
name: Current hour
|
||||
secondary_info: last-updated
|
||||
type: custom:multiple-entity-row
|
||||
unit: kWh
|
||||
- entity: sensor.solcast_forecast_next_hour
|
||||
format: kilo
|
||||
name: Next hour
|
||||
secondary_info: last-updated
|
||||
type: custom:multiple-entity-row
|
||||
unit: kWh
|
||||
- label: Tomorrow
|
||||
type: section
|
||||
- entity: sensor.solcast_forecast_tomorrow
|
||||
name: Total
|
||||
secondary_info: last-updated
|
||||
- label: Peak hour
|
||||
type: section
|
||||
- entities:
|
||||
- entity: sensor.solcast_peak_time_today
|
||||
format: time
|
||||
name: ' '
|
||||
entity: sensor.solcast_peak_forecast_today
|
||||
format: kilo
|
||||
name: Today
|
||||
type: custom:multiple-entity-row
|
||||
unit: kWh
|
||||
- entities:
|
||||
- entity: sensor.solcast_peak_time_tomorrow
|
||||
format: time
|
||||
name: ' '
|
||||
entity: sensor.solcast_peak_forecast_tomorrow
|
||||
format: kilo
|
||||
name: Tomorrow
|
||||
type: custom:multiple-entity-row
|
||||
unit: kWh
|
||||
title: Forecast
|
||||
type: entities
|
||||
- cards:
|
||||
- entities:
|
||||
- entity: sensor.inverter_battery_level
|
||||
name: Charge
|
||||
- entity: sensor.inverter_battery_power
|
||||
name: Power
|
||||
type: history-graph
|
||||
- entities:
|
||||
- entity: sensor.inverter_battery_power
|
||||
name: Power
|
||||
- entity: sensor.inverter_battery_level
|
||||
name: Level
|
||||
- entity: sensor.inverter_battery_health
|
||||
name: Health
|
||||
- entity: sensor.inverter_battery_charge_today
|
||||
name: Total daily charge
|
||||
- entity: sensor.inverter_battery_discharge_today
|
||||
name: Total daily discharge
|
||||
type: entities
|
||||
title: Battery
|
||||
type: history-graph
|
||||
- card:
|
||||
type: entities
|
||||
filter:
|
||||
exclude:
|
||||
- state: unavailable
|
||||
include:
|
||||
- entity_id: sensor.eagle_200_meter_power_demand
|
||||
- entity_id: /sensor.inverter_/
|
||||
type: custom:auto-entities
|
||||
- card:
|
||||
title: Actions
|
||||
type: entities
|
||||
filter:
|
||||
exclude: []
|
||||
include:
|
||||
- domain: /script|automation/
|
||||
entity_id: /\.inverter_/
|
||||
type: custom:auto-entities
|
||||
- cards:
|
||||
- entities:
|
||||
- entity: sensor.inverter_grid_frequency
|
||||
name: Frequency
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.inverter_phase_a_voltage
|
||||
name: Voltage
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.inverter_phase_a_current
|
||||
name: Current
|
||||
secondary_info: last-updated
|
||||
type: entities
|
||||
- entities:
|
||||
- entity: sensor.inverter_grid_frequency
|
||||
name: Frequency
|
||||
- entity: sensor.inverter_phase_a_voltage
|
||||
name: Voltage
|
||||
- entity: sensor.inverter_phase_a_current
|
||||
name: Current
|
||||
type: history-graph
|
||||
title: Grid
|
||||
type: custom:stack-in-card
|
||||
icon: mdi:solar-power-variant
|
||||
theme: Backend-selected
|
||||
|
@ -374,3 +329,176 @@ config:
|
|||
icon: hass:lightning-bolt
|
||||
path: power
|
||||
title: Electricity
|
||||
- badges: []
|
||||
cards:
|
||||
- entities:
|
||||
- label: Charge schedule
|
||||
type: section
|
||||
- entity: input_datetime.inverter_charging_schedule_start
|
||||
name: Start charging at
|
||||
- entity: input_datetime.inverter_charging_schedule_end
|
||||
name: Finish charging at
|
||||
- entity: input_number.inverter_charging_schedule_target_soc
|
||||
name: Charge until
|
||||
- label: Misc
|
||||
type: section
|
||||
- entity: input_number.inverter_battery_reserve
|
||||
icon: mdi:battery-lock
|
||||
name: Reserve battery
|
||||
secondary_info: last-changed
|
||||
title: Settings
|
||||
type: entities
|
||||
- entities:
|
||||
- action_name: Set
|
||||
entity: script.inverter_self_consumption
|
||||
icon: mdi:recycle-variant
|
||||
name: Self-consumption
|
||||
- action_name: Set
|
||||
entity: script.inverter_force_battery_charge
|
||||
icon: mdi:import
|
||||
name: Force charge
|
||||
- action_name: Set
|
||||
entity: script.inverter_force_battery_discharge
|
||||
icon: mdi:export
|
||||
name: Force discharge
|
||||
- action_name: Set
|
||||
entity: script.inverter_force_battery_stop
|
||||
icon: mdi:stop
|
||||
name: Stop
|
||||
title: Battery mode
|
||||
type: entities
|
||||
- entities:
|
||||
- entity: automation.inverter_apply_charging_schedule
|
||||
icon: mdi:calendar-import
|
||||
name: Apply charging schedule
|
||||
secondary_info: last-triggered
|
||||
toggle: true
|
||||
type: custom:multiple-entity-row
|
||||
- entity: automation.inverter_update_battery_reserve
|
||||
icon: mdi:battery-sync-outline
|
||||
name: Apply battery reserve
|
||||
secondary_info: last-triggered
|
||||
toggle: true
|
||||
type: custom:multiple-entity-row
|
||||
- entity: automation.update_pvoutput
|
||||
icon: mdi:solar-power-variant-outline
|
||||
name: Send to PVOutput
|
||||
secondary_info: last-triggered
|
||||
title: Automations
|
||||
type: entities
|
||||
- card:
|
||||
hours_to_show: 1
|
||||
type: logbook
|
||||
filter:
|
||||
exclude: []
|
||||
include:
|
||||
- domain: automation
|
||||
name: /[Ii]nverter/
|
||||
- domain: script
|
||||
name: /[Ii]nverter/
|
||||
type: custom:auto-entities
|
||||
icon: mdi:wrench
|
||||
path: configure
|
||||
theme: Backend-selected
|
||||
title: Configure
|
||||
- badges: []
|
||||
cards:
|
||||
- cards:
|
||||
- entities:
|
||||
- entity: sensor.inverter_active_power
|
||||
name: Active (AC) power
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.inverter_pv_power
|
||||
name: PV Power
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.inverter_load_power
|
||||
name: Load power (inverter claimed)
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.household_power_demand
|
||||
name: Actual load
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.inverter_battery_power
|
||||
name: Battery power
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.inverter_grid_power_demand
|
||||
name: Grid demand (inverter)
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.eagle_200_meter_power_demand_w
|
||||
name: Grid demand (meter)
|
||||
secondary_info: last-updated
|
||||
type: entities
|
||||
- entities:
|
||||
- entity: sensor.inverter_grid_power_demand
|
||||
name: Grid demand (inverter)
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.eagle_200_meter_power_demand_w
|
||||
name: Grid demand (meter)
|
||||
secondary_info: last-updated
|
||||
hours_to_show: 6
|
||||
type: history-graph
|
||||
title: Power
|
||||
type: custom:stack-in-card
|
||||
- cards:
|
||||
- entities:
|
||||
- entity: sensor.inverter_battery_level
|
||||
name: Charge
|
||||
- entity: sensor.inverter_battery_power
|
||||
name: Power
|
||||
type: history-graph
|
||||
- entities:
|
||||
- sensor.inverter_battery_power
|
||||
- sensor.inverter_battery_level
|
||||
- sensor.inverter_battery_current
|
||||
- sensor.inverter_battery_voltage
|
||||
- sensor.inverter_battery_temperature
|
||||
- sensor.inverter_battery_health
|
||||
- sensor.inverter_battery_charge_today
|
||||
- sensor.inverter_battery_discharge_today
|
||||
type: entities
|
||||
title: Battery
|
||||
type: custom:stack-in-card
|
||||
- entities:
|
||||
- entity: sensor.inverter_output_energy_today
|
||||
name: Output energy (5003)
|
||||
- entity: sensor.inverter_pv_generation_today
|
||||
name: PV generation (13002)
|
||||
- entity: sensor.inverter_battery_charge_today
|
||||
name: Battery charge (13040)
|
||||
- entity: sensor.inverter_battery_charge_from_pv_today
|
||||
name: Battery charge from PV (13012)
|
||||
- entity: sensor.inverter_battery_discharge_today
|
||||
name: Battery discharge (13026)
|
||||
- entity: sensor.inverter_imported_energy_today
|
||||
name: Imported (13036)
|
||||
- entity: sensor.inverter_exported_energy_today
|
||||
name: Exported (13045)
|
||||
- entity: sensor.inverter_exported_energy_from_pv_today
|
||||
name: Exported from PV (13005)
|
||||
- entity: sensor.inverter_direct_energy_consumption_today
|
||||
name: Direct consumption (13017)
|
||||
title: Energy
|
||||
type: entities
|
||||
- cards:
|
||||
- entities:
|
||||
- entity: sensor.inverter_grid_frequency
|
||||
name: Frequency (5036)
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.inverter_phase_a_voltage
|
||||
name: Voltage (5019)
|
||||
secondary_info: last-updated
|
||||
- entity: sensor.inverter_phase_a_current
|
||||
name: Current (13031)
|
||||
secondary_info: last-updated
|
||||
type: entities
|
||||
- entities:
|
||||
- entity: sensor.inverter_export_power
|
||||
name: Export power (Inverter - 13010)
|
||||
- entity: sensor.eagle_200_meter_power_demand_w
|
||||
name: Import power (Eagle-200)
|
||||
type: history-graph
|
||||
title: Grid
|
||||
type: custom:stack-in-card
|
||||
icon: mdi:bug-outline
|
||||
path: debug
|
||||
theme: Backend-selected
|
||||
title: Debug
|
||||
|
|
|
@ -3,74 +3,6 @@ config:
|
|||
views:
|
||||
- badges: []
|
||||
cards:
|
||||
- cards:
|
||||
- cards:
|
||||
- entity: person.bo_jeanes
|
||||
fill_container: false
|
||||
hide_name: false
|
||||
hide_state: false
|
||||
type: custom:mushroom-person-card
|
||||
use_entity_picture: true
|
||||
- double_tap_action:
|
||||
action: none
|
||||
entity: sensor.template_room_bo_phone
|
||||
icon: "{% if is_state(entity, 'not_home') and is_state('person.bo_jeanes',\
|
||||
\ 'home') %}\n mdi:cellphone-off\n{% else %}\n mdi:cellphone-marker\n\
|
||||
{% endif %}"
|
||||
secondary: "{% if is_state('person.bo_jeanes', 'not_home') %}\n ~{{ states('proximity.bo_home')\
|
||||
\ }}m from home\n{% elif is_state(entity, 'not_home') %}\n Unknown\n\
|
||||
{% else %}\n {{ states(entity) | replace(\"_s_\",\"'s \") | replace(\"\
|
||||
_\",\" \") | title }}\n ~{{ state_attr(entity, 'distance') }}m\n{% endif\
|
||||
\ %}"
|
||||
tap_action:
|
||||
action: more-info
|
||||
type: custom:mushroom-template-card
|
||||
type: vertical-stack
|
||||
- cards:
|
||||
- entity: person.ri_liu
|
||||
fill_container: false
|
||||
hide_name: false
|
||||
hide_state: false
|
||||
layout: horizontal
|
||||
type: custom:mushroom-person-card
|
||||
use_entity_picture: true
|
||||
- double_tap_action:
|
||||
action: none
|
||||
entity: sensor.template_room_ri_phone
|
||||
icon: "{% if is_state(entity, 'not_home') and is_state('person.ri_liu',\
|
||||
\ 'home') %}\n mdi:cellphone-off\n{% else %}\n mdi:cellphone-marker\n\
|
||||
{% endif %}"
|
||||
secondary: "{% if is_state('person.ri_liu', 'not_home') %}\n ~{{ states('proximity.ri_home')\
|
||||
\ }}m from home\n{% elif is_state(entity, 'not_home') %}\n Unknown\n\
|
||||
{% else %}\n {{ states(entity) | replace(\"_s_\",\"'s \") | replace(\"\
|
||||
_\",\" \") | title }}\n ~{{ state_attr(entity, 'distance') }}m\n{% endif\
|
||||
\ %}"
|
||||
tap_action:
|
||||
action: more-info
|
||||
type: custom:mushroom-template-card
|
||||
type: vertical-stack
|
||||
type: horizontal-stack
|
||||
- card:
|
||||
type: custom:mushroom-chips-card
|
||||
card_param: chips
|
||||
filter:
|
||||
exclude: []
|
||||
include:
|
||||
- attributes:
|
||||
device_class: door
|
||||
domain: binary_sensor
|
||||
options:
|
||||
content: "{{ state_attr('this.entity_id', 'friendly_name') \n | replace('\
|
||||
\ contact','') \n | replace(' Door','') }}"
|
||||
icon: "{% if is_state('this.entity_id', 'on') %}\n mdi:door-open\n{%\
|
||||
\ else %}\n mdi:door-closed\n{% endif %}"
|
||||
tap_action:
|
||||
action: more-info
|
||||
type: template
|
||||
use_light_color: true
|
||||
state: 'on'
|
||||
show_empty: false
|
||||
type: custom:auto-entities
|
||||
- card:
|
||||
type: custom:mushroom-chips-card
|
||||
card_param: chips
|
||||
|
@ -91,17 +23,6 @@ config:
|
|||
sort:
|
||||
method: friendly_name
|
||||
type: custom:auto-entities
|
||||
- entity: cover.front_gate
|
||||
layout: horizontal
|
||||
show_buttons_control: true
|
||||
show_position_control: false
|
||||
tap_action:
|
||||
action: call-service
|
||||
service: button.press
|
||||
service_data: {}
|
||||
target:
|
||||
entity_id: button.front_gate_button
|
||||
type: custom:mushroom-cover-card
|
||||
- cards:
|
||||
- card:
|
||||
chips:
|
||||
|
@ -300,6 +221,9 @@ config:
|
|||
- entity_id: /fire_danger/
|
||||
not:
|
||||
state: /Low|^High/
|
||||
- entity_id: sensor.ups_status
|
||||
not:
|
||||
state: Online
|
||||
- entity_id: /octoprint_printing/
|
||||
state: 'on'
|
||||
- attributes:
|
||||
|
@ -353,7 +277,7 @@ config:
|
|||
- entities:
|
||||
battery: sensor.inverter_battery_power
|
||||
battery_charge: sensor.inverter_battery_level
|
||||
grid: sensor.eagle_200_meter_power_demand
|
||||
grid: sensor.inverter_grid_power_demand
|
||||
solar: sensor.inverter_pv_power
|
||||
kw_decimals: 2
|
||||
type: custom:power-flow-card
|
||||
|
@ -579,6 +503,59 @@ config:
|
|||
panel: false
|
||||
path: default_view
|
||||
title: Home
|
||||
- badges: []
|
||||
cards:
|
||||
- cards:
|
||||
- cards:
|
||||
- entity: person.bo_jeanes
|
||||
fill_container: false
|
||||
hide_name: false
|
||||
hide_state: false
|
||||
type: custom:mushroom-person-card
|
||||
use_entity_picture: true
|
||||
- double_tap_action:
|
||||
action: none
|
||||
entity: sensor.template_room_bo_phone
|
||||
icon: "{% if is_state(entity, 'not_home') and is_state('person.bo_jeanes',\
|
||||
\ 'home') %}\n mdi:cellphone-off\n{% else %}\n mdi:cellphone-marker\n\
|
||||
{% endif %}"
|
||||
secondary: "{% if is_state('person.bo_jeanes', 'not_home') %}\n ~{{ states('proximity.bo_home')\
|
||||
\ }}m from home\n{% elif is_state(entity, 'not_home') %}\n Unknown\n\
|
||||
{% else %}\n {{ states(entity) | replace(\"_s_\",\"'s \") | replace(\"\
|
||||
_\",\" \") | title }}\n ~{{ state_attr(entity, 'distance') }}m\n{% endif\
|
||||
\ %}"
|
||||
tap_action:
|
||||
action: more-info
|
||||
type: custom:mushroom-template-card
|
||||
type: vertical-stack
|
||||
- cards:
|
||||
- entity: person.ri_liu
|
||||
fill_container: false
|
||||
hide_name: false
|
||||
hide_state: false
|
||||
layout: horizontal
|
||||
type: custom:mushroom-person-card
|
||||
use_entity_picture: true
|
||||
- double_tap_action:
|
||||
action: none
|
||||
entity: sensor.template_room_ri_phone
|
||||
icon: "{% if is_state(entity, 'not_home') and is_state('person.ri_liu',\
|
||||
\ 'home') %}\n mdi:cellphone-off\n{% else %}\n mdi:cellphone-marker\n\
|
||||
{% endif %}"
|
||||
secondary: "{% if is_state('person.ri_liu', 'not_home') %}\n ~{{ states('proximity.ri_home')\
|
||||
\ }}m from home\n{% elif is_state(entity, 'not_home') %}\n Unknown\n\
|
||||
{% else %}\n {{ states(entity) | replace(\"_s_\",\"'s \") | replace(\"\
|
||||
_\",\" \") | title }}\n ~{{ state_attr(entity, 'distance') }}m\n{% endif\
|
||||
\ %}"
|
||||
tap_action:
|
||||
action: more-info
|
||||
type: custom:mushroom-template-card
|
||||
type: vertical-stack
|
||||
type: horizontal-stack
|
||||
icon: mdi:account-supervisor-circle
|
||||
path: people
|
||||
theme: Backend-selected
|
||||
title: People
|
||||
- badges: []
|
||||
cards:
|
||||
- entities:
|
||||
|
|
|
@ -61,7 +61,7 @@ items:
|
|||
url: /hacsfiles/lovelace-layout-card/layout-card.js?hacstag=156434866242
|
||||
- id: b573b075ef40439ea3961ecd46ea285a
|
||||
type: module
|
||||
url: /hacsfiles/scheduler-card/scheduler-card.js?hacstag=286270157234
|
||||
url: /hacsfiles/scheduler-card/scheduler-card.js?hacstag=286270157235
|
||||
- id: 618ee66f432c46edbbf612f2c10faa28
|
||||
type: module
|
||||
url: /hacsfiles/lovelace-multiple-entity-row/multiple-entity-row.js?hacstag=178921037441
|
||||
|
@ -118,7 +118,7 @@ items:
|
|||
url: /hacsfiles/power-flow-card/power-flow-card.js?hacstag=484538222251
|
||||
- id: 8217392f44e24fe98b652c7f36ab302e
|
||||
type: module
|
||||
url: /hacsfiles/ha-sankey-chart/ha-sankey-chart.js?hacstag=455846088070
|
||||
url: /hacsfiles/ha-sankey-chart/ha-sankey-chart.js?hacstag=4558460880110
|
||||
- id: 84ed6341c9b245aba7e66cbdc51e2ccb
|
||||
type: module
|
||||
url: /hacsfiles/state-attribute-element/state-attribute-element.js?hacstag=142038085040
|
||||
|
@ -136,7 +136,7 @@ items:
|
|||
url: /hacsfiles/last-changed-element/last-changed-element.js?hacstag=4203650621598
|
||||
- id: 713c44b772b54d5ebdb0061a188e2f7b
|
||||
type: module
|
||||
url: /hacsfiles/custom-icons/custom-icons.js?hacstag=491465538021
|
||||
url: /hacsfiles/custom-icons/custom-icons.js?hacstag=491465538035
|
||||
- id: c6b759faf93a4e22ab9faa3ebcaa218b
|
||||
type: module
|
||||
url: /hacsfiles/button-card/button-card.js?hacstag=146194325342
|
||||
|
|
Loading…
Reference in New Issue