Compare commits

...

3 Commits

Author SHA1 Message Date
Florian Brinker c1ecdac17e update skeleton 2019-10-13 11:25:14 +02:00
Florian Brinker fe5f9caca4 Add shinobi, wakeonlan workaround, optimized harmony switch code 2019-10-13 11:25:14 +02:00
Florian Brinker 2e501bc322 update 2019-10-13 11:25:04 +02:00
19 changed files with 571 additions and 217 deletions

3
.gitignore vendored
View File

@ -7,14 +7,17 @@
!*.png
!.gitignore
!*.md
!*.skel
!/automations/
!/lovelace-views/
!/sensors/
!/www/
!/scripts/
# "Force" Disallow
.storage/
android/
ssh-key/
ip_bans.yaml
secrets.yaml

View File

@ -8,6 +8,7 @@
- light.ambilight
- light.kuchen_theke
- light.esstisch
- light.office
- switch.livingroom_stimmungslicht
- switch.livingroom_music
- switch.livingroom_netflix
@ -32,7 +33,10 @@
description: Küche - Theken-Lichter
light.esstisch:
name: Esstisch
description: Küche - Esstisch-Lampen
description: Esstisch-Lichter
light.office:
name: Büro
description: Büro - Deckenlampe
light.stimmungslicht:
name: Stimmungslicht
description: Wohnzimmer - Stimmungslicht

View File

@ -0,0 +1,28 @@
# You can replace default by Light - Green, for example
- alias: 'Set theme at startup'
trigger:
- platform: homeassistant
event: start
action:
- service: frontend.set_theme
data:
name: default
- alias: 'Set HA theme for day and night'
trigger:
- platform: homeassistant
event: start
- platform: state
entity_id: sun.sun
to: above_horizon
- platform: state
entity_id: sun.sun
to: below_horizon
action:
- service_template: frontend.set_theme
data_template:
name: >
{% if states.sun.sun.state == "above_horizon" %}
default
{% else %}
default
{% endif %}

View File

@ -7,6 +7,7 @@ homeassistant:
time_zone: Europe/Berlin
customize: !include_dir_merge_named customizations/
auth_providers:
- type: homeassistant
- type: trusted_networks
trusted_networks:
- 127.0.0.1
@ -15,6 +16,7 @@ homeassistant:
- fd00::/8
frontend:
themes: !include_dir_merge_named themes/
http:
ip_ban_enabled: true
@ -28,11 +30,16 @@ lovelace:
mode: yaml
zone:
- name: !secret work1_name
latitude: !secret work1_lat
longitude: !secret work1_long
- name: !secret work_name_f
latitude: !secret work_lat_f
longitude: !secret work_long_f
radius: 250
icon: mdi:briefcase
- name: !secret work_name_j
latitude: !secret work_lat_j
longitude: !secret work_long_j
radius: 500
icon: mdi:briefcase
system_health:
@ -45,7 +52,8 @@ updater:
conversation:
tts:
- platform: google
- platform: google_translate
service_name: google_say
history:
@ -132,8 +140,8 @@ notify:
- name: telegram_fb
platform: telegram
chat_id: !secret telegram_chat_fb
- name: android
platform: fcm-android
# - name: android
# platform: fcm-android
device_tracker:
@ -174,25 +182,11 @@ binary_sensor:
name: Morning
after: '05:00'
before: '11:00'
- platform: mqtt
state_topic: /home/camera/yihome1/motion/state
name: YiHome1 Alarm
payload_on: 1
payload_off: 0
- platform: command_line
name: backup_error_occured
command: 'if [ `wc -l < /backuplogs/run.err.log` -eq 0 ]; then echo 0; else echo 1; fi'
payload_on: 1
payload_off: 0
scan_interval: 1800
device_class: 'problem'
- platform: command_line
name: backup_sync_error_occured
command: 'if [ `wc -l < /backuplogs/sync.err.log` -eq 0 ]; then echo 0; else echo 1; fi'
payload_on: 1
payload_off: 0
scan_interval: 1800
device_class: 'problem'
- platform: ping
name: desktop_ping
host: !secret desktop_ip
count: 2
scan_interval: 15
weather:
- platform: openweathermap
@ -204,25 +198,15 @@ weather:
# bed: true
# number_of_tools: 1
#ffmpeg:
# ffmpeg_bin: /usr/bin/ffmpeg
ffmpeg:
ffmpeg_bin: /usr/bin/ffmpeg
stream:
camera:
# - platform: yi
# name: YiHome1
# host: !secret yihome1
# password: !secret yihome1_password
# ffmpeg_arguments: '-pred 1 -vf scale=800:450'
# - platform: mqtt
# name: YiHome1-Mqtt
# topic: /home/camera/yihome1/motion/photo
# - platform: mjpeg
# name: octoprint_webcam
# mjpeg_url: !secret octoprint_cam_url
# - platform: local_file
#name: elisey_shocked
#friendly_name: Schlechtes Wetter
#file_path: /local/elisey_shocked.png
- platform: ffmpeg
name: office
input: !secret office_stream_url
input_datetime:
bedroom_alarm_clock_time:
@ -230,20 +214,35 @@ input_datetime:
has_date: false
has_time: true
shell_command:
ssh: 'ssh -o "StrictHostKeyChecking=no" -i {{ sshkey }} {{ host }} -l {{ user }} -p {{ port }} {{ command_or_param }}'
rest_command:
shinobi_monitorstates:
url: "https://{{ host }}/{{ apikey }}/monitorStates/{{ group }}/{{ preset_name }}"
panel_iframe:
deconz:
title: 'Deconz'
url: !secret url_deconz
icon: mdi:gate-and
cctv:
title: 'CCTV'
url: !secret url_cctv
icon: mdi:cctv
chronograf:
title: 'Chronograf'
url: !secret url_chronograf
icon: mdi:monitor-dashboard
deconz:
title: 'Deconz'
url: !secret url_deconz
icon: mdi:gate-and
esphome:
title: 'ESPHome'
url: !secret url_esphome
icon: mdi:chip
#alert: !include alerts.yaml
#alert: !include_dir_merge_list alerts/
alexa: !include alexa.yaml
automation: !include_dir_merge_list automations/
#scene: !include scenes.yaml
script: !include scripts.yaml
sensor: !include_dir_merge_list sensors/
switch: !include switches.yaml
switch: !include switches.yaml

View File

@ -1,10 +1,21 @@
icon: mdi:cctv
path: cctv
cards:
- type: picture-entity
name: Haustür
entity: camera.yihome1
- type: picture-entity
name: Haustür Alarm Image
entity: binary_sensor.yihome1_alarm
camera_image: camera.yihome1_alarm
- type: entities
show_header_toggle: false
entities:
- entity: switch.cctv_active
name: Kameras aktiviert
icon: mdi:power
- entity: switch.cctv_motion_detection
name: Aufnahmen bei Bewegung
icon: mdi:motion-sensor
- type: picture-glance
title: Büro
camera_image: camera.office
camera_view: live
entities:
- entity: switch.cctv_motion_detection
icon: mdi:motion-sensor
- entity: switch.cctv_active
icon: mdi:power

View File

@ -6,22 +6,30 @@ cards:
- entity: sensor.myip
name: Öffentliche IP
icon: mdi:earth
- type: horizontal-stack
cards:
- type: entities
title: Florian
show_header_toggle: false
entities:
- entity: device_tracker.mobile_fb
name: Standort
- entity: sensor.device_mobile_fb_battery
name: Handy-Akku
icon: mdi:battery
- type: entities
title: Jenny
show_header_toggle: false
entities:
- entity: device_tracker.mobile_fb
name: Standort
- entity: sensor.device_mobile_fb_battery
name: Handy-Akku
icon: mdi:battery
- type: entities
title: Florian
title: Wake On Lan
show_header_toggle: false
entities:
- entity: device_tracker.mobile_fb
name: Standort
- entity: sensor.device_mobile_fb_battery
name: Handy-Akku
icon: mdi:battery
- type: entities
title: Jenny
show_header_toggle: false
entities:
- entity: device_tracker.mobile_fb
name: Standort
- entity: sensor.device_mobile_fb_battery
name: Handy-Akku
icon: mdi:battery
- entity: switch.desktop_wol
name: Desktop-PC
icon: mdi:desktop-classic

View File

@ -1,21 +1,151 @@
icon: mdi:water-percent
path: humidity
cards:
- type: history-graph
title: 'Badezimmer'
refresh_interval: 30
entities:
- entity: sensor.bathroom_hygrometer_temperature
name: Temperatur
- entity: sensor.bathroom_hygrometer_humidity
name: Luftfeuchtigkeit
- type: history-graph
title: 'Dachboden'
refresh_interval: 30
entities:
- entity: sensor.attic_temperature
name: Temperatur
- entity: sensor.attic_heatIndex
name: Gefühlt
- entity: sensor.attic_humidity
name: Luftfeuchtigkeit
- type: vertical-stack
cards:
- type: markdown
content: "### Elternbad"
- type: horizontal-stack
cards:
- type: sensor
entity: sensor.parents_bathroom_hygrometer_humidity
name: Luftfeuchtigkeit
graph: line
unit: "%"
detail: 2
hours_to_show: 12
- type: sensor
entity: sensor.parents_bathroom_hygrometer_temperature
name: Temperatur
graph: line
unit: °C
detail: 2
hours_to_show: 12
- type: markdown
content: "### \"Kinderbad\""
- type: horizontal-stack
cards:
- type: sensor
entity: sensor.kids_bathroom_hygrometer_humidity
name: Luftfeuchtigkeit
graph: line
unit: "%"
detail: 2
hours_to_show: 12
- type: sensor
entity: sensor.kids_bathroom_hygrometer_temperature
name: Temperatur
graph: line
unit: °C
detail: 2
hours_to_show: 12
- type: markdown
content: "### Schlafzimmer"
- type: horizontal-stack
cards:
- type: sensor
entity: sensor.humidity_12
name: Luftfeuchtigkeit
graph: line
unit: "%"
detail: 2
hours_to_show: 12
- type: sensor
entity: sensor.temperature_11
name: Temperatur
graph: line
unit: °C
detail: 2
hours_to_show: 12
- type: markdown
content: "### Gästezimmer"
- type: horizontal-stack
cards:
- type: sensor
entity: sensor.humidity_18
name: Luftfeuchtigkeit
graph: line
unit: "%"
detail: 2
hours_to_show: 12
- type: sensor
entity: sensor.temperature_17
name: Temperatur
graph: line
unit: °C
detail: 2
hours_to_show: 12
- type: vertical-stack
cards:
- type: markdown
content: "### Wohnzimmer"
- type: horizontal-stack
cards:
- type: sensor
entity: sensor.humidity_4
name: Luftfeuchtigkeit
graph: line
unit: "%"
detail: 2
hours_to_show: 12
- type: sensor
entity: sensor.temperature_3
name: Temperatur
graph: line
unit: °C
detail: 2
hours_to_show: 12
- type: markdown
content: "### Hauswirtschaftsraum"
- type: horizontal-stack
cards:
- type: sensor
entity: sensor.hwr_hygrometer_humidity
name: Luftfeuchtigkeit
graph: line
unit: "%"
detail: 2
hours_to_show: 12
- type: sensor
entity: sensor.hwr_hygrometer_temperature
name: Temperatur
graph: line
unit: °C
detail: 2
hours_to_show: 12
- type: markdown
content: "### Büro"
- type: horizontal-stack
cards:
- type: sensor
entity: sensor.humidity_15
name: Luftfeuchtigkeit
graph: line
unit: "%"
detail: 2
hours_to_show: 12
- type: sensor
entity: sensor.temperature_14
name: Temperatur
graph: line
unit: °C
detail: 2
hours_to_show: 12
- type: markdown
content: "### Dachboden"
- type: horizontal-stack
cards:
- type: sensor
entity: sensor.attic_humidity_2
name: Luftfeuchtigkeit
graph: line
unit: "%"
detail: 2
hours_to_show: 12
- type: sensor
entity: sensor.attic_temperature_2
name: Temperatur
graph: line
unit: °C
detail: 2
hours_to_show: 12

View File

@ -1,10 +0,0 @@
title: Küche
path: kitchen
cards:
# Lights
- type: entities
entities:
- entity: light.kuchen_theke
name: Küchen-Theke
- entity: light.esstisch
name: Esstisch

View File

@ -0,0 +1,18 @@
title: Lichter
path: lights
cards:
- type: light
entity: light.kuchen_theke
name: Küchen-Theke
- type: light
entity: light.office
name: Büro
- type: light
entity: light.stimmungslicht
name: Stimmungslicht
- type: light
entity: light.ambilight
name: Ambilight
- type: light
entity: light.esstisch
name: Esstisch

View File

@ -3,14 +3,15 @@ path: overview
cards:
- type: vertical-stack
cards:
- type: weather-forecast
- type: custom:weather-card
entity: weather.openweathermap
# - type: iframe
# url: !secret iframe_windy
# aspect_ratio: 75%
name: Wetter
- type: iframe
url: !secret iframe_earth
url: !secret iframe_windy
aspect_ratio: 75%
# - type: iframe
# url: !secret iframe_earth
# aspect_ratio: 75%
- type: conditional
conditions:
- entity: binary_sensor.workday_sensor
@ -24,36 +25,6 @@ cards:
entities:
- entity: sensor.salzbergen_to_munster_hbf
name: Abfahrt
- type: vertical-stack
cards:
- type: glance
title: Temperatur
show_name: true
show_state: true
entities:
- entity: sensor.bathroom_hygrometer_temperature
name: Badezimmer
icon: mdi:thermometer
- entity: sensor.temperature_3
name: Wohnzimmer
icon: mdi:thermometer
- entity: sensor.attic_temperature
name: Dachboden
icon: mdi:thermometer
- type: glance
title: Luftfeuchtigkeit
show_name: true
show_state: true
entities:
- entity: sensor.bathroom_hygrometer_humidity
name: Badezimmer
icon: mdi:water-percent
- entity: sensor.humidity_4
name: Wohnzimmer
icon: mdi:water-percent
- entity: sensor.attic_humidity
name: Dachboden
icon: mdi:water-percent
- type: vertical-stack
cards:
- type: glance
@ -64,4 +35,4 @@ cards:
aspect_ratio: 75%
default_zoom: 15
entities:
- zone.home
- zone.home

View File

@ -1,3 +1,6 @@
dummy:
sequence:
ambilight_off:
alias: Ambilight schwarz schalten
sequence:
@ -76,4 +79,77 @@ livingroom_netflix_on:
command:
- Ok
device: 42849848 #FireTv
delay_secs: 0.6
delay_secs: 0.6
### Harmony Helper-Scripts
harmony_denon_power:
alias: Denon Power
sequence:
- service: remote.send_command
data:
entity_id: remote.livingroom_harmony
command:
- PowerToggle
device: 42849850 #Denon
harmony_denon_mute:
alias: Denon Stumm
sequence:
- service: remote.send_command
data:
entity_id: remote.livingroom_harmony
command:
- Mute
device: 42849850 #Denon
harmony_volume_up:
alias: Denon Lauter
sequence:
- service: remote.send_command
data:
entity_id: remote.livingroom_harmony
command:
- VolumeUp
device: 42849850 #Denon
num_repeats: 5
harmony_volume_down:
alias: Denon Leiser
sequence:
- service: remote.send_command
data:
entity_id: remote.livingroom_harmony
command:
- VolumeDown
device: 42849850 #Denon
num_repeats: 5
# CCTV
shinobi_idle:
sequence:
- service: rest_command.shinobi_monitorstates
data:
host: !secret shinobi_host
apikey: !secret shinobi_api_key
group: !secret shinobi_group
preset_name: Inactive (Idle)
shinobi_active:
sequence:
- service: rest_command.shinobi_monitorstates
data:
host: !secret shinobi_host
apikey: !secret shinobi_api_key
group: !secret shinobi_group
preset_name: Active + Motion Detection OFF
shinobi_active_with_motion:
sequence:
- service: rest_command.shinobi_monitorstates
data:
host: !secret shinobi_host
apikey: !secret shinobi_api_key
group: !secret shinobi_group
preset_name: Active + Motion Detection ON

23
scripts/create-secrets-skel.sh Executable file
View File

@ -0,0 +1,23 @@
#!/usr/bin/env bash
DIR=$(dirname "$(readlink -f "$0")")
SECRETS_FILE="$DIR/../secrets.yaml"
SKEL_FILE="$SECRETS_FILE.skel"
if [ ! -f $SECRETS_FILE ]; then
echo "File missing: \"$SECRETS_FILE\""
exit 1
fi
touch $SKEL_FILE
echo "" > $SKEL_FILE
while read LINE; do
# do nothing with empty lines
if [[ $LINE = *:* ]]; then
LINE="${LINE%%:*}: "
fi
echo "$LINE" >> $SKEL_FILE
done < $SECRETS_FILE

View File

@ -0,0 +1,22 @@
#!/usr/bin/env bash
DIR=$(dirname "$(readlink -f "$0")")
KEYFILE="$DIR/../ssh-key/homeassistant-wakeonlan-sshkey"
TARGET="$HOME/.ssh/authorized_keys"
if [ ! -f $KEYFILE ]; then
echo "You need to create the SSH-Key-File first: \"$KEYFILE\""
echo "Use: \"ssh-keygen -t ed25519 -C homeassistant-wakeonlan-sshkey -f $KEYFILE\""
exit 1
fi
if ! which wakeonlan > /dev/null; then
echo "You need to install \"wakeonlan\" first. Otherwise the ssh-key will be useless."
exit 1
fi
SSHKEY=$(<"$KEYFILE.pub")
echo "command=\"wakeonlan \$SSH_ORIGINAL_COMMAND\" $SSHKEY" >> $TARGET
echo "Installed the ssh key into \"$TARGET\"."

90
secrets.yaml.skel Normal file
View File

@ -0,0 +1,90 @@
# Misc
adbkey:
url_cctv:
url_chronograf:
url_deconz:
url_esphome:
# Zones
home_lat:
home_long:
home_elevation:
work_name_f:
work_lat_f:
work_long_f:
work_name_j:
work_lat_j:
work_long_j:
# Remote services
alexa_client_id:
alexa_client_secret:
deconz_ip:
deconz_port:
influxdb:
influxdb_user:
influxdb_password:
mqtt_broker_ip:
mqtt_username:
mqtt_password:
# Remote control
ambilight_ip:
firetv_ip:
harmonyhub_ip:
octoprint_ip:
octoprint_api_key:
octoprint_cam_url:
spotify_client_id:
spotify_client_secret:
shinobi_host:
shinobi_api_key:
shinobi_group:
office_stream_url:
office_details_url:
# Weather
openweathermap:
# Wake On Lan
nas_ip:
nas_ssh_user:
nas_ssh_port:
sshkey_wakeonlan:
desktop_ip:
desktop_mac:
desktop_wol_cmd:
iframe_earth:
#iframe_windy:
iframe_windy:
# Notifications
telegram_bot:
telegram_chat_fb:
telegram_chat_group:
# Social data
instagram_beauty:
instagram_franky:
instagram_fb:
instagram_mtb:
youtube_beauty:
youtube_mtb:
bitly_blog_bb:
bitly_instagram_bb:
bitly_impressum_bb:
bitly_youtube_bb:

8
sensors/cctv.yaml Normal file
View File

@ -0,0 +1,8 @@
- platform: rest
resource: !secret office_details_url
name: Camera Mode Office
value_template: '{{ value_json.mode }}'
- platform: rest
resource: !secret office_details_url
name: Camera Motion Office
value_template: '{{ value_json.details|string|regex_search("\"detector\":\"1\"", ignorecase=FALSE) }}'

View File

@ -9,20 +9,4 @@
name: "mobile_fb_callstate"
state_topic: "homeassistant/sensor/android_mobile_fb_callstate/state"
value_template: "{{ value_json.state }}"
json_attributes_topic: "homeassistant/sensor/android_mobile_fb_callstate/state"
- platform: mqtt
name: "Attic Humidity"
state_topic: "home/attic/homenodeTiny1/humidity"
force_update: true
unit_of_measurement: "%"
- platform: mqtt
name: "Attic Temperature"
state_topic: "home/attic/homenodeTiny1/temperature"
force_update: true
unit_of_measurement: "°C"
- platform: mqtt
name: "Attic HeatIndex"
state_topic: "home/attic/homenodeTiny1/heatIndex"
force_update: true
unit_of_measurement: "°C"
json_attributes_topic: "homeassistant/sensor/android_mobile_fb_callstate/state"

0
ssh-key/.gitkeep Normal file
View File

View File

@ -1,5 +1,18 @@
- platform: template
switches:
desktop_wol:
value_template: "{{ is_state('binary_sensor.desktop_ping', 'on') }}"
turn_on:
service: shell_command.ssh
data:
sshkey: !secret sshkey_wakeonlan
host: !secret nas_ip
user: !secret nas_ssh_user
port: !secret nas_ssh_port
command_or_param: !secret desktop_mac
turn_off:
service: script.dummy
harmony_music_bt:
value_template: "{{ is_state_attr('remote.livingroom_harmony', 'current_activity', 'Musik Bluetooth') }}"
turn_on:
@ -52,81 +65,34 @@
entity_id: remote.livingroom_harmony
activity: 'PowerOff'
harmony_denon_mute:
friendly_name: Denon Stumm
value_template: "{{ state_attr('remote.livingroom_harmony', 'current_activity') != 'PowerOff' }}"
turn_on:
service: remote.send_command
data:
entity_id: remote.livingroom_harmony
command:
- Mute
device: 42849850 #Denon
turn_off:
service: remote.send_command
data:
entity_id: remote.livingroom_harmony
command:
- Mute
device: 42849850 #Denon
harmony_denon_power:
friendly_name: Denon Power
value_template: "{{ state_attr('remote.livingroom_harmony', 'current_activity') != 'PowerOff' }}"
turn_on:
service: remote.send_command
data:
entity_id: remote.livingroom_harmony
command:
- PowerToggle
device: 42849850 #Denon
service: script.harmony_denon_power
turn_off:
service: remote.send_command
data:
entity_id: remote.livingroom_harmony
command:
- PowerToggle
device: 42849850 #Denon
service: script.harmony_denon_power
harmony_volume_down:
friendly_name: Denon Leiser
harmony_denon_mute:
friendly_name: Denon Stumm
value_template: "{{ state_attr('remote.livingroom_harmony', 'current_activity') != 'PowerOff' }}"
turn_on:
service: remote.send_command
data:
entity_id: remote.livingroom_harmony
command:
- VolumeDown
device: 42849850 #Denon
num_repeats: 5
turn_off:
service: remote.send_command
data:
entity_id: remote.livingroom_harmony
command:
- VolumeDown
device: 42849850 #Denon
num_repeats: 5
service: script.harmony_denon_mute
harmony_volume_up:
friendly_name: Denon Lauter
value_template: "{{ state_attr('remote.livingroom_harmony', 'current_activity') != 'PowerOff' }}"
turn_on:
service: remote.send_command
data:
entity_id: remote.livingroom_harmony
command:
- VolumeUp
device: 42849850 #Denon
num_repeats: 5
turn_off:
service: remote.send_command
data:
entity_id: remote.livingroom_harmony
command:
- VolumeUp
device: 42849850 #Denon
num_repeats: 5
service: script.harmony_volume_up
harmony_volume_down:
friendly_name: Denon Leiser
value_template: "{{ state_attr('remote.livingroom_harmony', 'current_activity') != 'PowerOff' }}"
turn_on:
turn_off:
service: script.harmony_volume_down
livingroom_music:
value_template: "{{ is_state_attr('remote.livingroom_harmony', 'current_activity', 'Musik Bluetooth') }}"
@ -143,4 +109,22 @@
service: remote.turn_on
data:
entity_id: remote.livingroom_harmony
activity: 'PowerOff'
activity: 'PowerOff'
### CCTV
cctv_motion_detection:
friendly_name: CCTV Motion Detection
value_template: "{{ (is_state('sensor.camera_mode_office', 'start') or is_state('sensor.camera_mode_office', 'recording')) and is_state('sensor.camera_motion_office', 'True') }}"
turn_on:
service: script.shinobi_active_with_motion
turn_off:
service: script.shinobi_active
cctv_active:
friendly_name: CCTV Active
value_template: "{{ is_state('sensor.camera_mode_office', 'start') or is_state('sensor.camera_mode_office', 'recording') }}"
turn_on:
service: script.shinobi_active
turn_off:
service: script.shinobi_idle

View File

@ -1,11 +1,16 @@
# Icons @ https://materialdesignicons.com/
title: Making Home Great Again
views:
- !include lovelace-views/overview.yaml
- !include lovelace-views/kitchen.yaml
- !include lovelace-views/lights.yaml
- !include lovelace-views/livingroom.yaml
- !include lovelace-views/humidity.yaml
- !include lovelace-views/spotify.yaml
- !include lovelace-views/instagram.yaml
- !include lovelace-views/devices.yaml
# - !include lovelace-views/cctv.yaml
- !include lovelace-views/cctv.yaml
resources:
- url: https://cdn.jsdelivr.net/gh/bramkragten/custom-ui@master/weather-card/weather-card.min.js
type: module