catching up #52
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
airconnect_dir: "/var/lib/airconnect"
|
||||||
|
airconnect_user:
|
||||||
|
name: airconnect
|
||||||
|
uid: 1337
|
||||||
|
airconnect_group:
|
||||||
|
name: airconnect
|
||||||
|
gid: 1337
|
||||||
|
|
||||||
|
airconnect_upnp: []
|
||||||
|
airconnect_containers:
|
||||||
|
# UPnP/Sonos
|
||||||
|
- prog: airupnp
|
||||||
|
state: started
|
||||||
|
# Chromecast
|
||||||
|
- prog: aircast
|
||||||
|
state: started
|
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: restart airconnect containers
|
||||||
|
docker_container:
|
||||||
|
name: airconnect-{{ item }}
|
||||||
|
state: "{{ item.state }}"
|
||||||
|
restart: item.state == 'started'
|
||||||
|
with_items: "{{ airconnect_containers }}"
|
||||||
|
when:
|
||||||
|
- airconnect_containers is not defined or not airconnect_containers.changed
|
||||||
|
- item.state == 'started'
|
|
@ -0,0 +1,87 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: create airconnect dir
|
||||||
|
file:
|
||||||
|
path: "{{ airconnect_dir }}"
|
||||||
|
state: directory
|
||||||
|
mode: "0755"
|
||||||
|
owner: hass
|
||||||
|
group: hass
|
||||||
|
tags:
|
||||||
|
- airconnect-dirs
|
||||||
|
|
||||||
|
- name: airconnect config files
|
||||||
|
template:
|
||||||
|
src: "{{ item.name }}.j2"
|
||||||
|
dest: "{{ airconnect_dir }}/{{ item.name }}"
|
||||||
|
owner: "{{ item.owner | default(systemuserlist.hass.uid) }}"
|
||||||
|
group: "{{ item.group | default(systemuserlist.hass.gid) }}"
|
||||||
|
mode: "{{ item.mode }}"
|
||||||
|
notify: restart airconnect container
|
||||||
|
with_items:
|
||||||
|
- name: airupnp.xml
|
||||||
|
mode: "0644"
|
||||||
|
- name: run
|
||||||
|
mode: "0755"
|
||||||
|
- name: supervisord.conf
|
||||||
|
mode: "0644"
|
||||||
|
owner: "root"
|
||||||
|
group: "root"
|
||||||
|
# needed to nuke the script that would otherwise
|
||||||
|
# overwrite our sane supervisord.conf file
|
||||||
|
- name: 30-install
|
||||||
|
mode: "0755"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }}"
|
||||||
|
tags:
|
||||||
|
- airconnect-config
|
||||||
|
- airconnect
|
||||||
|
|
||||||
|
- name: start airconnect container
|
||||||
|
docker_container:
|
||||||
|
name: airconnect
|
||||||
|
hostname: airconnect
|
||||||
|
image: 1activegeek/airconnect
|
||||||
|
#user: "{{ systemuserlist.hass.uid }}:{{ systemuserlist.hass.gid }}"
|
||||||
|
detach: true
|
||||||
|
pull: true
|
||||||
|
auto_remove: false
|
||||||
|
restart_policy: "unless-stopped"
|
||||||
|
state: "{{ airconnect_container_state | default('started') }}"
|
||||||
|
network_mode: host
|
||||||
|
env:
|
||||||
|
# docker image uses the linuxserver base image and supervisor,
|
||||||
|
# setting 'user:' doesnt work because of all of the custom shit
|
||||||
|
# that the base image does: https://github.com/linuxserver/docker-baseimage-ubuntu/blob/bionic/root/etc/cont-init.d/10-adduser
|
||||||
|
# but this image doesnt follow that properly, and supervisor starts
|
||||||
|
# the airconnect processes as root, so we need to mount a custom
|
||||||
|
# supervisord.conf file instead
|
||||||
|
PUID: "{{ systemuserlist.hass.uid }}"
|
||||||
|
PGID: "{{ systemuserlist.hass.gid }}"
|
||||||
|
|
||||||
|
# the image runs a script
|
||||||
|
# AIRUPNP_VAR: "-x /etc/airconnect/airupnp.xml"
|
||||||
|
# will create a reference config file for chromecast when found,
|
||||||
|
# but the defaults are fine, so no need to maintain a custom file
|
||||||
|
#AIRCAST_VAR: "-i /etc/airconnect/aircast.xml"
|
||||||
|
mounts:
|
||||||
|
# generate the reference config files by setting AIRUPNP_VAR and
|
||||||
|
# AIRCAST_VAR env to '-i $PATH'
|
||||||
|
- type: bind
|
||||||
|
source: "{{ airconnect_dir }}/airupnp.xml"
|
||||||
|
target: /etc/airupnp.xml
|
||||||
|
read_only: true
|
||||||
|
# need this to set uid/gid properly
|
||||||
|
- type: bind
|
||||||
|
source: "{{ airconnect_dir }}/supervisord.conf"
|
||||||
|
target: /etc/supervisord.conf
|
||||||
|
# needed to nuke the script that would otherwise overwrite our sane
|
||||||
|
# version of the supervisord.conf file when the container starts
|
||||||
|
- type: bind
|
||||||
|
source: "{{ airconnect_dir }}/30-install"
|
||||||
|
target: /etc/cont-init.d/30-install
|
||||||
|
tags:
|
||||||
|
- airconnect
|
||||||
|
- airconnect-container
|
||||||
|
- docker-containers
|
||||||
|
register: airconnect_container
|
|
@ -0,0 +1,56 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: create airconnect dir
|
||||||
|
file:
|
||||||
|
path: "{{ airconnect_dir }}"
|
||||||
|
state: directory
|
||||||
|
mode: "0755"
|
||||||
|
owner: "{{ owntone_user.uid }}"
|
||||||
|
group: "{{ owntone_group.gid }}"
|
||||||
|
tags:
|
||||||
|
- airconnect-dirs
|
||||||
|
|
||||||
|
- name: airconnect config files
|
||||||
|
template:
|
||||||
|
src: "{{ item.name }}.j2"
|
||||||
|
dest: "{{ airconnect_dir }}/{{ item.name }}"
|
||||||
|
owner: "{{ owntone_user.uid }}"
|
||||||
|
group: "{{ owntone_group.gid }}"
|
||||||
|
mode: "{{ item.mode | default('0644') }}"
|
||||||
|
notify: restart airconnect containers
|
||||||
|
with_items:
|
||||||
|
- name: airupnp.xml
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }}"
|
||||||
|
tags:
|
||||||
|
- airconnect-config
|
||||||
|
- airconnect
|
||||||
|
|
||||||
|
- name: "set up the airconnect containers"
|
||||||
|
docker_container:
|
||||||
|
name: airconnect-{{ item.prog }}
|
||||||
|
hostname: airconnect-{{ item.prog }}
|
||||||
|
image: git.sudo.is/ben/airconnect
|
||||||
|
detach: true
|
||||||
|
pull: true
|
||||||
|
auto_remove: false
|
||||||
|
restart_policy: "unless-stopped"
|
||||||
|
state: "{{ item.state | default('started') }}"
|
||||||
|
network_mode: host
|
||||||
|
user: "{{ owntone_user.uid }}:{{ owntone_group.gid }}"
|
||||||
|
env:
|
||||||
|
AIRCONNECT_PROG: "{{ item.prog }}"
|
||||||
|
AIRCONNECT_ARGS: "{{ item.args|default() }}"
|
||||||
|
mounts:
|
||||||
|
- type: bind
|
||||||
|
source: "{{ airconnect_dir }}/airupnp.xml"
|
||||||
|
target: /etc/airupnp.xml
|
||||||
|
read_only: true
|
||||||
|
tags:
|
||||||
|
- airconnect
|
||||||
|
- airconnect-container
|
||||||
|
- docker-containers
|
||||||
|
register: airconnect_containers
|
||||||
|
loop_control:
|
||||||
|
label: airconnect-{{ item.prog }}
|
||||||
|
with_items: "{{ airconnect_containers }}"
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
- import_tasks: airconnect.yml
|
||||||
|
tags: airconnect
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<airupnp>
|
||||||
|
<common>
|
||||||
|
<protocolInfo>
|
||||||
|
<pcm>http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=00;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=0d500000000000000000000000000000</pcm>
|
||||||
|
<wav>http-get:*:audio/wav:DLNA.ORG_OP=00;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=0d500000000000000000000000000000</wav>
|
||||||
|
<flac>http-get:*:audio/flac:DLNA.ORG_OP=00;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=0d500000000000000000000000000000</flac>
|
||||||
|
<mp3>http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=00;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=0d500000000000000000000000000000</mp3>
|
||||||
|
</protocolInfo>
|
||||||
|
<enabled>1</enabled>
|
||||||
|
<max_volume>100</max_volume>
|
||||||
|
<http_length>-1</http_length>
|
||||||
|
<upnp_max>1</upnp_max>
|
||||||
|
<codec>mp3:320</codec>
|
||||||
|
<metadata>1</metadata>
|
||||||
|
<flush>1</flush>
|
||||||
|
<artwork></artwork>
|
||||||
|
<latency>0:1000</latency>
|
||||||
|
<drift>0</drift>
|
||||||
|
</common>
|
||||||
|
<main_log>info</main_log>
|
||||||
|
<upnp_log>info</upnp_log>
|
||||||
|
<util_log>warn</util_log>
|
||||||
|
<raop_log>info</raop_log>
|
||||||
|
<log_limit>-1</log_limit>
|
||||||
|
<max_players>32</max_players>
|
||||||
|
<binding>?</binding>
|
||||||
|
<ports>0:0</ports>
|
||||||
|
{% for item in airconnect_upnp -%}
|
||||||
|
<device>
|
||||||
|
<udn>uuid:{{ item.local_uid }}</udn>
|
||||||
|
<name>{{ item.name }}</name>
|
||||||
|
<mac>{{ item.mac }}</mac>
|
||||||
|
<enabled>{% if item.enabled|default(true) %}1{% else %}0{% endif %}</enabled>
|
||||||
|
</device>
|
||||||
|
{% endfor %}
|
||||||
|
</airupnp>
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/usr/bin/with-contenv bash
|
||||||
|
|
||||||
|
echo "this file has been nuked, so our sane supervisord.conf file is not overwritten"
|
||||||
|
|
||||||
|
exit 0
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/usr/bin/with-contenv bash
|
||||||
|
|
||||||
|
supervisord --configuration /etc/supervisord.conf
|
|
@ -0,0 +1,25 @@
|
||||||
|
[supervisord]
|
||||||
|
nodaemon=true
|
||||||
|
|
||||||
|
# the base image of the airconnect image uses the env vars $PUID and $PGID
|
||||||
|
# to create a user, and those are set in the ansible role
|
||||||
|
#
|
||||||
|
# supervisord doesnt have an argument for group, uses the default
|
||||||
|
# group of the user instead.
|
||||||
|
#
|
||||||
|
# but supervisor itself needs to run as root because of
|
||||||
|
# asinine stuff that the linuxserver base image wants to do
|
||||||
|
|
||||||
|
[program:airupnp]
|
||||||
|
user={{ systemuserlist.hass.uid }}
|
||||||
|
redirect_stderr=true
|
||||||
|
# the config file maintained in this ansible role, mounted in
|
||||||
|
# the docker_container task
|
||||||
|
command=/bin/airupnp-linux-x86_64 -x /etc/airupnp.xml
|
||||||
|
process_name = airupnp-linux-x86_64
|
||||||
|
|
||||||
|
[program:aircast]
|
||||||
|
user={{ systemuserlist.hass.uid }}
|
||||||
|
redirect_stderr=true
|
||||||
|
command=/bin/aircast-linux-x86_64
|
||||||
|
process_name = aircast-linux-x86_64
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: reload nginx
|
||||||
|
service:
|
||||||
|
name: nginx
|
||||||
|
state: reloaded
|
|
@ -0,0 +1,82 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: create dir structure
|
||||||
|
file:
|
||||||
|
path: "{{ audiobookshelf_path }}/{{ item.name }}"
|
||||||
|
mode: "{{ item.mode | default('0750') }}"
|
||||||
|
owner: "{{ audiobookshelf_user.uid }}"
|
||||||
|
group: "{{ audiobookshelf_group.gid }}"
|
||||||
|
tags:
|
||||||
|
- audiobookshelf-dirs
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }}"
|
||||||
|
with_items:
|
||||||
|
- name: ''
|
||||||
|
- name: audiobooks
|
||||||
|
- name: config
|
||||||
|
mode: "0755"
|
||||||
|
- name: metadata
|
||||||
|
- name: podcasts
|
||||||
|
|
||||||
|
- name: install certs
|
||||||
|
copy:
|
||||||
|
src: "/usr/local/etc/letsencrypt/live/{{ item }}"
|
||||||
|
dest: "/usr/local/etc/certs/"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0755
|
||||||
|
tags:
|
||||||
|
- letsencrypt-certs
|
||||||
|
notify: reload nginx
|
||||||
|
vars:
|
||||||
|
prediff_cmd: echo
|
||||||
|
with_items:
|
||||||
|
- "{{ audiobookshelf_url }}"
|
||||||
|
|
||||||
|
- name: template nginx vhost
|
||||||
|
template:
|
||||||
|
src: 02-audiobookshelf.conf.j2
|
||||||
|
dest: /etc/nginx/sites-enabled/02-audiobookshelf.conf
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0644
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- audiobookshelf-nginx
|
||||||
|
notify: reload nginx
|
||||||
|
|
||||||
|
- name: start audiobookshelf container
|
||||||
|
docker_container:
|
||||||
|
name: audiobookshelf
|
||||||
|
auto_remove: false
|
||||||
|
image: ghcr.io/advplyr/audiobookshelf:latest
|
||||||
|
detach: true
|
||||||
|
pull: true
|
||||||
|
restart_policy: "no"
|
||||||
|
state: started
|
||||||
|
container_default_behavior: compatibility
|
||||||
|
networks_cli_compatible: false
|
||||||
|
network_mode: bridgewithdns
|
||||||
|
networks:
|
||||||
|
- name: bridgewithdns
|
||||||
|
ipv4_address: "{{ bridgewithdns.audiobookshelf }}"
|
||||||
ben marked this conversation as resolved
|
|||||||
|
env:
|
||||||
|
AUDIOBOOKSHELF_UID: "{{ audiobookshelf_user.uid }}"
|
||||||
|
AUDIOBOOKSHELF_GID: "{{ audiobookshelf_group.gid }}"
|
||||||
|
user: "{{ audiobookshelf_user.uid }}:{{ audiobookshelf_group.gid }}"
|
||||||
|
mounts:
|
||||||
|
- type: bind
|
||||||
|
source: "{{ audiobookshelf_path }}/audiobooks"
|
||||||
|
target: /audiobooks
|
||||||
|
- type: bind
|
||||||
|
source: "{{ audiobookshelf_path }}/podcasts"
|
||||||
|
target: /podcasts
|
||||||
|
- type: bind
|
||||||
|
source: "{{ audiobookshelf_path }}/config"
|
||||||
|
target: /config
|
||||||
|
- type: bind
|
||||||
|
source: "{{ audiobookshelf_path }}/metadata"
|
||||||
|
target: /metadata
|
||||||
|
tags:
|
||||||
|
- audiobookshelf-container
|
||||||
|
- docker-containers
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
- import_tasks: audiobookshelf.yml
|
||||||
|
tags: audiobookshelf
|
|
@ -0,0 +1,50 @@
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
include listen-proxy-protocol.conf;
|
||||||
|
|
||||||
|
{% if inventory_hostname in wg_clients -%}
|
||||||
|
listen {{ wg_clients[inventory_hostname].ip }}:443 ssl http2;
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
server_name {{ audiobookshelf_url }};
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access_{{ audiobookshelf_url }}.log main;
|
||||||
|
error_log /var/log/nginx/error_{{ audiobookshelf_url }}.log warn;
|
||||||
|
|
||||||
|
ssl_certificate /usr/local/etc/certs/{{ audiobookshelf_url }}/fullchain.pem;
|
||||||
|
ssl_certificate_key /usr/local/etc/certs/{{ audiobookshelf_url }}/privkey.pem;
|
||||||
|
|
||||||
|
include /etc/nginx/authelia_internal.conf;
|
||||||
|
|
||||||
|
location /feed/ {
|
||||||
|
include /etc/nginx/require_auth.conf;
|
||||||
|
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
|
proxy_pass http://{{ bridgewithdns.audiobookshelf }}:80;
|
||||||
|
proxy_redirect http:// https://;
|
||||||
|
|
||||||
|
proxy_hide_header "Content-Type";
|
||||||
|
add_header "Content-Type" "application/rss+xml";
|
||||||
|
|
||||||
|
}
|
||||||
|
location / {
|
||||||
|
include /etc/nginx/require_auth.conf;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
|
proxy_pass http://{{ bridgewithdns.audiobookshelf }}:80;
|
||||||
|
proxy_redirect http:// https://;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +1,2 @@
|
||||||
---
|
---
|
||||||
|
blink1_enabled: false
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
-----BEGIN PGP ARMORED FILE-----
|
||||||
|
Comment: Use "gpg --dearmor" for unpacking
|
||||||
|
|
||||||
|
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
|
||||||
|
=P2ir
|
||||||
|
-----END PGP ARMORED FILE-----
|
|
@ -0,0 +1,52 @@
|
||||||
|
-----BEGIN PGP ARMORED FILE-----
|
||||||
|
Comment: Use "gpg --dearmor" for unpacking
|
||||||
|
|
||||||
|
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
|
||||||
|
=P2ir
|
||||||
|
-----END PGP ARMORED FILE-----
|
|
@ -1,6 +0,0 @@
|
||||||
|
|
||||||
- sensor:
|
|
||||||
- name: "chance_of_rain"
|
|
||||||
unit_of_measurement: "%"
|
|
||||||
icon: "mdi:weather-pouring"
|
|
||||||
state: "{{ state_attr('weather.hourly', 'forecast')[:2] | map(attribute='precipitation_probability') | list | max | float }}"
|
|
|
@ -15,4 +15,18 @@
|
||||||
name: hass
|
name: hass
|
||||||
state: started
|
state: started
|
||||||
restart: true
|
restart: true
|
||||||
when: hass_container is not defined or not hass_container.changed
|
when:
|
||||||
|
- hass_container is not defined or not hass_container.changed
|
||||||
|
- hass_container_state|default("stopped") == "started"
|
||||||
|
|
||||||
|
- name: restart zwavejs container
|
||||||
|
docker_container:
|
||||||
|
name: zwavejs
|
||||||
|
state: started
|
||||||
|
restart: true
|
||||||
|
when:
|
||||||
|
- zwavejs_container is not defined or not zwavejs_container.changed
|
||||||
|
- hass_container_state|default("stopped") == "started"
|
||||||
|
|
||||||
|
- name: udevadm reload rules
|
||||||
|
command: udevadm control --reload-rules
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: nmcli conn reload
|
||||||
|
command: nmcli conn reload
|
||||||
|
|
||||||
|
- name: nmcli device wifi hotspot
|
||||||
|
command: nmcli device wifi hotspot
|
|
@ -1,53 +1,5 @@
|
||||||
---
|
---
|
||||||
|
|
||||||
- name: allow ssh
|
|
||||||
ufw:
|
|
||||||
rule: allow
|
|
||||||
to_port: "22"
|
|
||||||
direction: in
|
|
||||||
state: enabled
|
|
||||||
tags:
|
|
||||||
- ufw
|
|
||||||
|
|
||||||
- name: allow loopback
|
|
||||||
ufw:
|
|
||||||
rule: allow
|
|
||||||
interface: lo
|
|
||||||
direction: in
|
|
||||||
state: enabled
|
|
||||||
tags:
|
|
||||||
- ufw
|
|
||||||
|
|
||||||
- name: default policy
|
|
||||||
ufw:
|
|
||||||
policy: allow
|
|
||||||
state: enabled
|
|
||||||
tags:
|
|
||||||
- ufw
|
|
||||||
|
|
||||||
- name: deny hass cloud port stuff
|
|
||||||
ufw:
|
|
||||||
# drops packets
|
|
||||||
rule: deny
|
|
||||||
to_port: '42161'
|
|
||||||
direction: in
|
|
||||||
state: enabled
|
|
||||||
tags:
|
|
||||||
- ufw
|
|
||||||
|
|
||||||
- name: reject zwavejs ws and hass ports (loopback only)
|
|
||||||
ufw:
|
|
||||||
# connection refused
|
|
||||||
rule: reject
|
|
||||||
to_port: "{{ item }}"
|
|
||||||
direction: in
|
|
||||||
state: enabled
|
|
||||||
with_items:
|
|
||||||
- "8091"
|
|
||||||
- "8123"
|
|
||||||
tags:
|
|
||||||
- ufw
|
|
||||||
|
|
||||||
- name: copy ssh keys for {{ hass_config_repo_name }}
|
- name: copy ssh keys for {{ hass_config_repo_name }}
|
||||||
template:
|
template:
|
||||||
src: "private/sshkeys/{{ item }}"
|
src: "private/sshkeys/{{ item }}"
|
||||||
|
@ -66,22 +18,30 @@
|
||||||
|
|
||||||
- name: create dir structure
|
- name: create dir structure
|
||||||
file:
|
file:
|
||||||
path: "{{ systemuserlist.hass.home }}/{{ item }}"
|
path: "{{ systemuserlist.hass.home }}/{{ item.name }}"
|
||||||
state: directory
|
state: directory
|
||||||
mode: 0755
|
mode: "{{ item.mode | default('0755') }}"
|
||||||
owner: hass
|
owner: hass
|
||||||
group: hass
|
group: hass
|
||||||
tags:
|
tags:
|
||||||
- hass-dirs
|
- hass-dirs
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }}"
|
||||||
with_items:
|
with_items:
|
||||||
- home-assistant
|
- name: .local
|
||||||
- home-assistant/config
|
mode: "0775"
|
||||||
- home-assistant/.config
|
- name: home-assistant
|
||||||
- home-assistant/media
|
- name: home-assistant/config
|
||||||
- zwavejs
|
- name: home-assistant/config/python_scripts
|
||||||
- zwavejs/app
|
- name: home-assistant/config/bvg
|
||||||
- zwavejs/app/store
|
- name: home-assistant/.config # might not be needed, misread 'cache' as 'config'
|
||||||
- git
|
- name: home-assistant/.cache
|
||||||
|
- name: home-assistant/media
|
||||||
|
mode: "0775"
|
||||||
|
- name: zwavejs
|
||||||
|
- name: zwavejs/app
|
||||||
|
- name: zwavejs/app/store
|
||||||
|
- name: git
|
||||||
|
|
||||||
- name: template gitconfig
|
- name: template gitconfig
|
||||||
template:
|
template:
|
||||||
|
@ -108,36 +68,38 @@
|
||||||
- hass-git
|
- hass-git
|
||||||
- hass-git-clone
|
- hass-git-clone
|
||||||
|
|
||||||
- name: home assistant main configuration.yaml
|
|
||||||
|
- name: home assistant config files
|
||||||
template:
|
template:
|
||||||
src: configuration.yaml.j2
|
src: "{{ item }}.j2"
|
||||||
dest: "{{ systemuserlist.hass.home }}/home-assistant/config/configuration.yaml"
|
dest: "{{ systemuserlist.hass.home }}/home-assistant/config/{{ item }}"
|
||||||
owner: "{{ systemuserlist.hass.uid }}"
|
owner: "{{ systemuserlist.hass.uid }}"
|
||||||
group: "{{ systemuserlist.hass.gid }}"
|
group: "{{ systemuserlist.hass.gid }}"
|
||||||
mode: 0644
|
mode: 0644
|
||||||
notify: restart hass container
|
notify: restart hass container
|
||||||
|
with_items:
|
||||||
|
- secrets.yaml
|
||||||
|
- configuration.yaml
|
||||||
|
- templates.yaml
|
||||||
|
- climate.yaml
|
||||||
|
- automations-ansible-managed.yaml
|
||||||
|
- scripts-ansible-managed.yaml
|
||||||
|
- blink1.yaml
|
||||||
tags:
|
tags:
|
||||||
- hass-config
|
- hass-config
|
||||||
|
|
||||||
- name: home assistant secrets file
|
- name: copy dashboards
|
||||||
template:
|
|
||||||
src: secrets.yaml.j2
|
|
||||||
dest: "{{ systemuserlist.hass.home }}/home-assistant/config/secrets.yaml"
|
|
||||||
owner: "{{ systemuserlist.hass.uid }}"
|
|
||||||
group: "{{ systemuserlist.hass.gid }}"
|
|
||||||
mode: 0644
|
|
||||||
notify: restart hass container
|
|
||||||
tags:
|
|
||||||
- hass-config
|
|
||||||
|
|
||||||
- name: copy home assistant templates file
|
|
||||||
copy:
|
copy:
|
||||||
src: templates.yaml
|
src: "private/hass/{{ item }}"
|
||||||
dest: "{{ systemuserlist.hass.home }}/home-assistant/config/templates.yaml"
|
dest: "{{ systemuserlist.hass.home }}/home-assistant/config/{{ item }}"
|
||||||
owner: "{{ systemuserlist.hass.uid }}"
|
mode: 0755
|
||||||
group: "{{ systemuserlist.hass.gid }}"
|
owner: hass
|
||||||
mode: 0644
|
group: hass
|
||||||
notify: restart hass container
|
notify: restart hass container
|
||||||
|
with_items:
|
||||||
|
- mini.yaml
|
||||||
|
- ui-test.yaml
|
||||||
|
- card_room.yaml
|
||||||
tags:
|
tags:
|
||||||
- hass-config
|
- hass-config
|
||||||
|
|
||||||
|
@ -163,15 +125,106 @@
|
||||||
- hass-cron
|
- hass-cron
|
||||||
- hass-git
|
- hass-git
|
||||||
|
|
||||||
|
- name: udev rules
|
||||||
|
template:
|
||||||
|
src: "{{ item }}.j2"
|
||||||
|
dest: /etc/udev/rules.d/{{ item }}
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0644
|
||||||
|
notify: udevadm reload rules
|
||||||
|
with_items:
|
||||||
|
- 20-sdr.rules
|
||||||
|
tags:
|
||||||
|
- hass-udev
|
||||||
|
|
||||||
|
# key source:
|
||||||
|
# - http://download.ag-projects.com/agp-debian-gpg.key
|
||||||
|
# - http://download.ag-projects.com/agp-debian-key.key
|
||||||
|
# gpg --enarmor roles/hass/files/agp-debian-gpg.key
|
||||||
|
# binary keys: .gpg
|
||||||
|
# ascii armor: .asc (or .key?)
|
||||||
|
- name: add apt key for sip tools
|
||||||
|
copy:
|
||||||
|
src: "{{ item }}"
|
||||||
|
dest: /etc/apt/trusted.gpg.d/{{ item }}
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0644"
|
||||||
|
with_items:
|
||||||
|
- agp-debian-gpg.asc
|
||||||
|
- agp-debian-key.asc
|
||||||
|
tags:
|
||||||
|
- packages
|
||||||
|
- hass-sip
|
||||||
|
- sip
|
||||||
|
|
||||||
|
# - debug:
|
||||||
|
# msg: "deb [signed-by=/usr/share/keyrings/agp-debian-gpg.key] http://ag-projects.com/{{ ansible_lsb.id | lower }} {{ ansible_lsb.codename }} main"
|
||||||
|
# tags: hass-sip
|
||||||
|
|
||||||
|
# [signed-by=/usr/share/keyrings/agp-debian-gpg.gpg]
|
||||||
|
# [signed-by=/etc/apt/trusted.gpg.d/agp-debian-gpg.asc]
|
||||||
|
- name: add repo for sip tools
|
||||||
|
apt_repository:
|
||||||
|
#repo: "{{ item }} [signed-by=/etc/apt/trusted.gpg.d/agp-debian-key.asc] http://ag-projects.com/{{ ansible_lsb.id | lower }} {{ ansible_lsb.codename }} main"
|
||||||
|
repo: "{{ item }} [signed-by=/etc/apt/trusted.gpg.d/agp-debian-key.asc] http://ag-projects.com/{{ ansible_lsb.id | lower }} sid main"
|
||||||
|
state: present
|
||||||
|
update_cache: false
|
||||||
|
with_items:
|
||||||
|
- "deb"
|
||||||
|
- "deb-src"
|
||||||
|
register: sip_repo
|
||||||
|
tags:
|
||||||
|
- packages
|
||||||
|
- hass-sip
|
||||||
|
- sip
|
||||||
|
when: false
|
||||||
|
|
||||||
|
- name: update apt if new repo was added
|
||||||
|
apt:
|
||||||
|
update_cache: true
|
||||||
|
tags:
|
||||||
|
- packages
|
||||||
|
- hass-sip
|
||||||
|
- sip
|
||||||
|
when:
|
||||||
|
- sip_repo.changed
|
||||||
|
- false
|
||||||
|
|
||||||
# the host needs to have bluez installed for the container to use bluetooth
|
# the host needs to have bluez installed for the container to use bluetooth
|
||||||
- name: install bluetooth packages
|
- name: install packages
|
||||||
apt:
|
apt:
|
||||||
name:
|
name:
|
||||||
|
- vlc
|
||||||
|
- mplayer
|
||||||
- bluez
|
- bluez
|
||||||
- bluetooth
|
- bluetooth
|
||||||
|
- fapg
|
||||||
|
- podget
|
||||||
|
- sqlite3
|
||||||
|
- rtl-433
|
||||||
|
- mosquitto
|
||||||
|
- python3-paho-mqtt
|
||||||
|
- blink1 # git.sudo.is/ben/build-blink1
|
||||||
|
# # sip tools
|
||||||
|
# - python3-sipsimple
|
||||||
|
# - sipclients3
|
||||||
state: latest
|
state: latest
|
||||||
tags:
|
tags:
|
||||||
- packages
|
- packages
|
||||||
|
- hass-bluetooth
|
||||||
|
- hass-packages
|
||||||
|
- hass-sip
|
||||||
|
- sip
|
||||||
|
|
||||||
|
- name: ensure bluetooth service is started and enabled
|
||||||
|
service:
|
||||||
|
name: bluetooth
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
tags:
|
||||||
|
- hass-bluetooth
|
||||||
|
|
||||||
# docker run --run -it -p 8091:8091 -p 3000:3000 --network
|
# docker run --run -it -p 8091:8091 -p 3000:3000 --network
|
||||||
#bridgewithdns --device /dev/ttyACM0:/dev/zwave -v
|
#bridgewithdns --device /dev/ttyACM0:/dev/zwave -v
|
||||||
|
@ -186,7 +239,7 @@
|
||||||
detach: true
|
detach: true
|
||||||
pull: true
|
pull: true
|
||||||
restart_policy: "unless-stopped"
|
restart_policy: "unless-stopped"
|
||||||
state: "{{ container_state | default('started') }}"
|
state: "{{ hass_container_state | default('stopped') }}"
|
||||||
container_default_behavior: compatibility
|
container_default_behavior: compatibility
|
||||||
user: "{{ systemuserlist.hass.uid }}:dialout"
|
user: "{{ systemuserlist.hass.uid }}:dialout"
|
||||||
networks_cli_compatible: false
|
networks_cli_compatible: false
|
||||||
|
@ -200,18 +253,21 @@
|
||||||
# ws for hass<->zwavejs
|
# ws for hass<->zwavejs
|
||||||
# hass is configured to use localhost:3000 to talk to zwavejs, but can
|
# hass is configured to use localhost:3000 to talk to zwavejs, but can
|
||||||
# also use {{ bridgewithdns.zwavejs }}, but hass is very fragile and
|
# also use {{ bridgewithdns.zwavejs }}, but hass is very fragile and
|
||||||
# you have to manually work around it if it cant access zwaevjs because the
|
# you have to manually work around it if it cant access zwaevjs because
|
||||||
# ip/dns changed or the container moved networks. it is not configured in a
|
# the ip/dns changed or the container moved networks. it is not
|
||||||
# config file either. so using localhost is the least fragile strategy.
|
# configured in a config file either. so using localhost is the least
|
||||||
|
# fragile strategy.
|
||||||
- "127.0.0.1:3000:3000"
|
- "127.0.0.1:3000:3000"
|
||||||
env:
|
env:
|
||||||
#BASE_URL: "/zwavejs/"
|
#BASE_URL: "/zwavejs/"
|
||||||
SESSION_SECRET: "{{ zwavejs_session_secret }}"
|
SESSION_SECRET: "{{ zwavejs_session_secret }}"
|
||||||
ZWAVEJS_EXTERNAL_CONFIG: /usr/src/app/store/.config-db
|
ZWAVEJS_EXTERNAL_CONFIG: /usr/src/app/store/.config-db
|
||||||
|
SERVER_SSL: "true"
|
||||||
mounts:
|
mounts:
|
||||||
- type: bind
|
- type: bind
|
||||||
source: "{{ systemuserlist.hass.home }}/zwavejs/app/store"
|
source: "{{ systemuserlist.hass.home }}/zwavejs/app/store"
|
||||||
target: /usr/src/app/store
|
target: /usr/src/app/store
|
||||||
|
register: zwavejs_container
|
||||||
tags:
|
tags:
|
||||||
- zwavejs
|
- zwavejs
|
||||||
- zwavejs-container
|
- zwavejs-container
|
||||||
|
@ -219,20 +275,25 @@
|
||||||
- docker-containers
|
- docker-containers
|
||||||
|
|
||||||
# docker run --rm it --name hass -p 8123:8123 -e TZ=Etc/UTC -v
|
# docker run --rm it --name hass -p 8123:8123 -e TZ=Etc/UTC -v
|
||||||
# /home/ben/hass:/config --network-bridgewithdns
|
# /home/ben/hass:/config --network=bridgewithdns
|
||||||
# ghcr.io/home-assistant/home-assistant:stable
|
# ghcr.io/home-assistant/home-assistant:stable
|
||||||
|
|
||||||
- name: start home-assistant container
|
- name: start home-assistant container
|
||||||
docker_container:
|
docker_container:
|
||||||
name: hass
|
name: hass
|
||||||
image: ghcr.io/home-assistant/home-assistant:stable
|
image: ghcr.io/home-assistant/home-assistant:stable
|
||||||
|
#image: git.sudo.is/ben/hass:latest
|
||||||
detach: true
|
detach: true
|
||||||
pull: true
|
pull: true
|
||||||
restart_policy: "unless-stopped"
|
restart_policy: "unless-stopped"
|
||||||
state: "{{ container_state | default('started') }}"
|
state: "{{ hass_container_state | default('stopped') }}"
|
||||||
container_default_behavior: compatibility
|
container_default_behavior: compatibility
|
||||||
user: "{{ systemuserlist.hass.uid }}:{{ systemuserlist.hass.gid }}"
|
user: "{{ systemuserlist.hass.uid }}:{{ systemuserlist.hass.gid }}"
|
||||||
network_mode: host
|
network_mode: host
|
||||||
|
privileged: true
|
||||||
|
capabilities:
|
||||||
|
- SYS_ADMIN
|
||||||
|
- NET_ADMIN
|
||||||
env:
|
env:
|
||||||
TZ: "Etc/UTC"
|
TZ: "Etc/UTC"
|
||||||
mounts:
|
mounts:
|
||||||
|
@ -242,19 +303,27 @@
|
||||||
- type: bind
|
- type: bind
|
||||||
source: "{{ systemuserlist.hass.home }}/home-assistant/.config"
|
source: "{{ systemuserlist.hass.home }}/home-assistant/.config"
|
||||||
target: /.config
|
target: /.config
|
||||||
|
- type: bind
|
||||||
|
source: "{{ systemuserlist.hass.home }}/home-assistant/.cache"
|
||||||
|
target: /.cache
|
||||||
|
- type: bind
|
||||||
|
source: "{{ systemuserlist.hass.home }}/.local"
|
||||||
|
target: /.local
|
||||||
- type: bind
|
- type: bind
|
||||||
source: "{{ systemuserlist.hass.home }}/home-assistant/media"
|
source: "{{ systemuserlist.hass.home }}/home-assistant/media"
|
||||||
target: /usr/var/media
|
target: /usr/var/media
|
||||||
# for bluetooth, container needs access to the dbus socket
|
|
||||||
# https://www.home-assistant.io/integrations/bluetooth/
|
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /run/dbus/
|
|
||||||
target: /run/dbus/
|
|
||||||
read_only: true
|
read_only: true
|
||||||
|
source: "{{ systemuserlist.archives.home }}/podgrab/data"
|
||||||
|
target: /usr/var/media/podcasts
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /etc/bluetooth/main.conf
|
read_only: false
|
||||||
target: /etc/bluetooth/main.conf
|
source: /run/dbus
|
||||||
read_only: true
|
target: /run/dbus
|
||||||
|
# - type: bind
|
||||||
|
# source: /etc/bluetooth/main.conf
|
||||||
|
# target: /etc/bluetooth/main.conf
|
||||||
|
# read_only: true
|
||||||
# scripts from role: common
|
# scripts from role: common
|
||||||
# only depends on requests, which hass image has
|
# only depends on requests, which hass image has
|
||||||
- type: bind
|
- type: bind
|
||||||
|
@ -283,20 +352,23 @@
|
||||||
vars:
|
vars:
|
||||||
prediff_cmd: echo
|
prediff_cmd: echo
|
||||||
with_items:
|
with_items:
|
||||||
- "{{ hass_url }}"
|
- "{{ domain }}"
|
||||||
|
|
||||||
- name: template nginx vhost for hass
|
- name: template nginx vhosts for hass and friends
|
||||||
template:
|
template:
|
||||||
src: 01-hass.j2
|
src: "01-{{ item }}.conf.j2"
|
||||||
dest: /etc/nginx/sites-enabled/01-hass
|
dest: /etc/nginx/sites-enabled/{{ item }}.conf
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: 0644
|
mode: 0644
|
||||||
|
with_items:
|
||||||
|
- hass
|
||||||
|
- zwavejs
|
||||||
tags:
|
tags:
|
||||||
- nginx
|
- nginx
|
||||||
- hass-nginx
|
- hass-nginx
|
||||||
- zwave-nginx
|
- zwave-nginx
|
||||||
notify: restart nginx
|
notify: reload nginx
|
||||||
|
|
||||||
# different task because its better for the hass config to restart nginx
|
# different task because its better for the hass config to restart nginx
|
||||||
- name: template nginx vhost for grafana-proxy
|
- name: template nginx vhost for grafana-proxy
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
|
||||||
|
- name: allow ssh
|
||||||
|
ufw:
|
||||||
|
rule: allow
|
||||||
|
to_port: "22"
|
||||||
|
direction: in
|
||||||
|
state: enabled
|
||||||
|
tags:
|
||||||
|
- ufw
|
||||||
|
|
||||||
|
- name: allow loopback
|
||||||
|
ufw:
|
||||||
|
rule: allow
|
||||||
|
interface: lo
|
||||||
|
direction: in
|
||||||
|
state: enabled
|
||||||
|
tags:
|
||||||
|
- ufw
|
||||||
|
|
||||||
|
- name: default policy
|
||||||
|
ufw:
|
||||||
|
policy: allow
|
||||||
|
state: enabled
|
||||||
|
tags:
|
||||||
|
- ufw
|
||||||
|
|
||||||
|
- name: deny hass cloud port stuff
|
||||||
|
ufw:
|
||||||
|
# drops packets
|
||||||
|
rule: deny
|
||||||
|
to_port: '42161'
|
||||||
|
direction: in
|
||||||
|
state: enabled
|
||||||
|
tags:
|
||||||
|
- ufw
|
||||||
|
|
||||||
|
- name: reject zwavejs ws and hass ports (loopback only)
|
||||||
|
ufw:
|
||||||
|
# connection refused
|
||||||
|
rule: reject
|
||||||
|
to_port: "{{ item }}"
|
||||||
|
direction: in
|
||||||
|
state: enabled
|
||||||
|
with_items:
|
||||||
|
- "8091"
|
||||||
|
- "8123"
|
||||||
|
tags:
|
||||||
|
- ufw
|
||||||
|
|
||||||
|
- name: get current timestamp line
|
||||||
|
command: grep "timestamp=" /etc/NetworkManager/system-connections/blackbox.connection
|
||||||
|
check_mode: false
|
||||||
|
ignore_errors: true
|
||||||
|
changed_when: false
|
||||||
|
register: timestamp
|
||||||
|
tags:
|
||||||
|
- hass-wifi
|
||||||
|
- hass-blackbox
|
||||||
|
|
||||||
|
|
||||||
|
# nmcli device wifi blackbox ifname wlo1 ssid {{ hass_wifi_blackbox.ssid }} password {{ hass_wifi_blackbox.pass }}
|
||||||
|
- name: config for blackbox wifi ap with NetworkManager
|
||||||
|
template:
|
||||||
|
src: blackbox.connection.j2
|
||||||
|
dest: /etc/NetworkManager/system-connections/blackbox.connection
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0600
|
||||||
|
tags:
|
||||||
|
- hass-wifi
|
||||||
|
- hass-blackbox
|
||||||
|
notify:
|
||||||
|
- nmcli conn reload
|
||||||
|
- nmcli device wifi hotspot
|
||||||
|
|
||||||
|
# routing/forwarding should not be enabled, but block it to be sure
|
||||||
|
- name: allow local traffic on blackbox wifi
|
||||||
|
ufw:
|
||||||
|
rule: allow
|
||||||
|
interface: "{{ hass_wifi_blackbox.iface }}"
|
||||||
|
direction: out
|
||||||
|
dest: "{{ hass_wifi_blackbox.ip }}/{{ hass_wifi_blackbox.cidr_prefix }}"
|
||||||
|
state: enabled
|
||||||
|
tags:
|
||||||
|
- hass-wifi
|
||||||
|
- hass-blackbox
|
||||||
|
- ufw
|
||||||
|
|
||||||
|
- name: reject everything else on the blackbox wifi
|
||||||
|
ufw:
|
||||||
|
# connection refused
|
||||||
|
rule: reject
|
||||||
|
interface: "{{ hass_wifi_blackbox.iface }}"
|
||||||
|
direction: out
|
||||||
|
dest: any
|
||||||
|
state: enabled
|
||||||
|
tags:
|
||||||
|
- hass-wifi
|
||||||
|
- hass-blackbox
|
||||||
|
- ufw
|
|
@ -0,0 +1,144 @@
|
||||||
|
map $http_upgrade $connection_upgrade {
|
||||||
|
default upgrade;
|
||||||
|
#default $http_connection;
|
||||||
|
'' close;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
{% if inventory_hostname in wg_clients -%}
|
||||||
|
listen {{ wg_clients[inventory_hostname].ip }}:443 ssl http2;
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
include /etc/nginx/authelia_internal.conf;
|
||||||
|
include listen-proxy-protocol.conf;
|
||||||
|
include /etc/nginx/sudo-known.conf;
|
||||||
|
|
||||||
|
server_name {{ hass_url }};
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
|
||||||
|
proxy_pass http://127.0.0.1:8123;
|
||||||
|
}
|
||||||
|
|
||||||
|
# location /media {
|
||||||
|
# root {{ systemuserlist.hass.home }}/home-assistant/media;
|
||||||
|
# autoindex on;
|
||||||
|
# autoindex_exact_size off;
|
||||||
|
# }
|
||||||
|
|
||||||
|
{% if blink1_enabled -%}
|
||||||
|
location /blink1/ {
|
||||||
|
{% for cidr in my_local_cidrs -%}
|
||||||
|
allow {{ cidr }};
|
||||||
|
{% endfor -%}
|
||||||
|
allow {{ my_public_ips[ansible_control_host] }}/32;
|
||||||
|
allow 127.0.0.1;
|
||||||
|
deny all;
|
||||||
|
|
||||||
|
{% if blink1_tiny_html|default(false) -%}
|
||||||
|
rewrite '^/blink1(/.*)$' $1 break;
|
||||||
|
sub_filter_once off;
|
||||||
|
sub_filter '"/' '"./';
|
||||||
|
{% else -%}
|
||||||
|
add_header Content-Type 'application/json' always;
|
||||||
|
{% endif -%}
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_pass http://localhost:{{ blink1_server_port }};
|
||||||
|
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
location = {{ nginx_zwavejs_path }} {
|
||||||
|
# zwavejs needs to be accessed with a trailing / to respond.
|
||||||
|
#
|
||||||
|
# temporary redirects dont get remembered by the browser
|
||||||
|
# and redirect issues are no fun
|
||||||
|
return 302 https://{{ hass_url }}{{ nginx_zwavejs_path }}/;
|
||||||
|
}
|
||||||
|
location {{ nginx_zwavejs_path }} {
|
||||||
|
#add_header Access-Control-Allow-Origin "*" always;
|
||||||
|
# kill cache
|
||||||
|
add_header Last-Modified $date_gmt always;
|
||||||
|
add_header Cache-Control 'no-store' always;
|
||||||
|
if_modified_since off;
|
||||||
|
expires off;
|
||||||
|
etag off;
|
||||||
|
|
||||||
|
# nuke the service worker cache
|
||||||
|
# sub_filter '.js' '.js?id=$request_id';
|
||||||
|
|
||||||
|
include /etc/nginx/require_auth.conf;
|
||||||
|
|
||||||
|
rewrite ^ $request_uri;
|
||||||
|
rewrite '^{{ nginx_zwavejs_path }}(/.*)$' $1 break;
|
||||||
|
|
||||||
|
proxy_set_header X-External-Path {{ nginx_zwavejs_path }};
|
||||||
|
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
#proxy_socket_keepalive on;
|
||||||
|
|
||||||
|
## for the special dashboard
|
||||||
|
## https://zwave-js.github.io/zwave-js-ui/#/usage/reverse-proxy?id=using-an-http-header
|
||||||
|
## proxy_set_header X-External-Path $http_x_ingress_path;
|
||||||
|
|
||||||
|
proxy_pass http://{{ bridgewithdns.zwavejs }}:8091$uri;
|
||||||
|
#proxy_pass http://{{ bridgewithdns.zwavejs }}:8091/;
|
||||||
|
}
|
||||||
ben marked this conversation as resolved
ben
commented
remove remove
ben
commented
more or less fixed, not in this pr. more or less fixed, not in this pr.
|
|||||||
|
|
||||||
|
location = {{ nginx_podgrab_path }} {
|
||||||
|
return 302 https://{{ hass_url }}{{ nginx_podgrab_path }};
|
||||||
|
}
|
||||||
|
location {{ nginx_podgrab_path }} {
|
||||||
|
#include /etc/nginx/require_auth.conf;
|
||||||
|
|
||||||
|
# json for a tag:
|
||||||
|
# https://hass.sudo.is/podcasts/tags/${tag}
|
||||||
|
|
||||||
|
# add rss type or let podgrab handle it?
|
||||||
|
# slice out the url prefix
|
||||||
|
rewrite '^{{ nginx_podgrab_path }}(/.*)$' $1 break;
|
||||||
|
|
||||||
|
# rewrite html responses to add the url prefix
|
||||||
|
sub_filter_once off;
|
||||||
|
sub_filter 'href="/' 'href="{{ nginx_podgrab_path }}/';
|
||||||
|
sub_filter 'src="/' 'src="{{ nginx_podgrab_path }}/';
|
||||||
|
sub_filter '= "/' '= "{{ nginx_podgrab_path }}/';
|
||||||
|
sub_filter ':"/' ':"{{ nginx_podgrab_path }}/';
|
||||||
|
sub_filter ':href="\'/' ':href="\'{{ nginx_podgrab_path }}/';
|
||||||
|
sub_filter 'return "/' 'return "{{ nginx_podgrab_path }}/';
|
||||||
|
sub_filter '("/' '("{{ nginx_podgrab_path }}/';
|
||||||
|
sub_filter '`/' '`{{ nginx_podgrab_path }}/';
|
||||||
|
sub_filter '/ws' '{{ nginx_podgrab_path }}/ws';
|
||||||
|
|
||||||
|
# nuke the service worker cache
|
||||||
|
sub_filter '.js' '.js?id=$request_id';
|
||||||
|
sub_filter '.css' '.css?id=$request_id';
|
||||||
|
|
||||||
|
# headers for websockets
|
||||||
|
#proxy_set_header Upgrade $http_upgrade;
|
||||||
|
#proxy_set_header Connection $connection_upgrade;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
#proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
#proxy_set_header X-Forwarded-Host $http_host;
|
||||||
|
#proxy_set_header Host $http_host;
|
||||||
|
|
||||||
|
proxy_pass http://localhost:{{ podgrab_port }}{{ nginx_podgrab_path }}/;
|
||||||
|
}
|
||||||
ben
commented
vhost vhost
|
|||||||
|
|
||||||
|
access_log /var/log/nginx/access_{{ hass_url }}.log main;
|
||||||
|
error_log /var/log/nginx/error_{{ hass_url }}.log warn;
|
||||||
|
|
||||||
|
ssl_session_timeout 5m;
|
||||||
|
ssl_certificate /usr/local/etc/certs/{{ domain }}/fullchain.pem;
|
||||||
|
ssl_certificate_key /usr/local/etc/certs/{{ domain }}/privkey.pem;
|
||||||
|
|
||||||
|
fastcgi_hide_header X-Powered-By;
|
||||||
|
}
|
|
@ -1,74 +0,0 @@
|
||||||
map $http_upgrade $connection_upgrade {
|
|
||||||
default upgrade;
|
|
||||||
#default $http_connection;
|
|
||||||
'' close;
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
{% if inventory_hostname in wg_clients -%}
|
|
||||||
listen {{ wg_clients[inventory_hostname].ip }}:443 ssl http2;
|
|
||||||
{% endif -%}
|
|
||||||
|
|
||||||
include /etc/nginx/authelia_internal.conf;
|
|
||||||
include listen-proxy-protocol.conf;
|
|
||||||
include /etc/nginx/sudo-known.conf;
|
|
||||||
|
|
||||||
server_name {{ hass_url }};
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
|
|
||||||
proxy_pass http://127.0.0.1:8123;
|
|
||||||
}
|
|
||||||
|
|
||||||
location = {{ nginx_zwavejs_path }} {
|
|
||||||
# zwavejs needs to be accessed with a trailing / to respond.
|
|
||||||
#
|
|
||||||
# temporary redirects dont get remembered by the browser
|
|
||||||
# and redirect issues are no fun
|
|
||||||
return 302 https://{{ hass_url }}{{ nginx_zwavejs_path }}/;
|
|
||||||
}
|
|
||||||
|
|
||||||
location {{ nginx_zwavejs_path }} {
|
|
||||||
#add_header Access-Control-Allow-Origin "*" always;
|
|
||||||
# kill cache
|
|
||||||
add_header Last-Modified $date_gmt always;
|
|
||||||
add_header Cache-Control 'no-store' always;
|
|
||||||
if_modified_since off;
|
|
||||||
expires off;
|
|
||||||
etag off;
|
|
||||||
|
|
||||||
include /etc/nginx/require_auth.conf;
|
|
||||||
|
|
||||||
rewrite ^ $request_uri;
|
|
||||||
rewrite '^{{ nginx_zwavejs_path }}(/.*)$' $1 break;
|
|
||||||
|
|
||||||
proxy_set_header X-External-Path {{ nginx_zwavejs_path }};
|
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
#proxy_socket_keepalive on;
|
|
||||||
|
|
||||||
proxy_pass http://{{ bridgewithdns.zwavejs }}:8091$uri;
|
|
||||||
#proxy_pass http://{{ bridgewithdns.zwavejs }}:8091;
|
|
||||||
# for the special dashboard
|
|
||||||
# https://zwave-js.github.io/zwave-js-ui/#/usage/reverse-proxy?id=using-an-http-header
|
|
||||||
# proxy_set_header X-External-Path $http_x_ingress_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
access_log /var/log/nginx/access_{{ hass_url }}.log main;
|
|
||||||
error_log /var/log/nginx/error_{{ hass_url }}.log warn;
|
|
||||||
|
|
||||||
ssl_session_timeout 5m;
|
|
||||||
ssl_certificate /usr/local/etc/certs/{{ hass_url }}/fullchain.pem;
|
|
||||||
ssl_certificate_key /usr/local/etc/certs/{{ hass_url }}/privkey.pem;
|
|
||||||
|
|
||||||
fastcgi_hide_header X-Powered-By;
|
|
||||||
}
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
{% if inventory_hostname in wg_clients -%}
|
||||||
|
listen {{ wg_clients[inventory_hostname].ip }}:443 ssl http2;
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
include /etc/nginx/authelia_internal.conf;
|
||||||
|
include listen-proxy-protocol.conf;
|
||||||
|
include /etc/nginx/sudo-known.conf;
|
||||||
|
|
||||||
|
server_name {{ zwavejs_url }};
|
||||||
|
|
||||||
|
location / {
|
||||||
|
include /etc/nginx/require_auth.conf;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
|
||||||
|
# nuke cache
|
||||||
|
add_header Last-Modified $date_gmt always;
|
||||||
|
add_header Cache-Control 'no-store' always;
|
||||||
|
if_modified_since off;
|
||||||
|
expires off;
|
||||||
|
etag off;
|
||||||
|
|
||||||
|
# nuke the service worker cache
|
||||||
|
sub_filter '.js' '.js?id=$request_id';
|
||||||
|
## for the special dashboard
|
||||||
|
## https://zwave-js.github.io/zwave-js-ui/#/usage/reverse-proxy?id=using-an-http-header
|
||||||
|
#proxy_set_header X-External-Path "/";
|
||||||
|
proxy_set_header X-External-Path $http_x_ingress_path;
|
||||||
|
|
||||||
|
proxy_pass http://{{ bridgewithdns.zwavejs }}:8091;
|
||||||
|
}
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access_{{ zwavejs_url }}.log main;
|
||||||
|
error_log /var/log/nginx/error_{{ zwavejs_url }}.log warn;
|
||||||
|
|
||||||
|
ssl_session_timeout 5m;
|
||||||
|
ssl_certificate /usr/local/etc/certs/{{ domain }}/fullchain.pem;
|
||||||
|
ssl_certificate_key /usr/local/etc/certs/{{ domain }}/privkey.pem;
|
||||||
|
|
||||||
|
fastcgi_hide_header X-Powered-By;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="2838", GROUP="adm", MODE="0666", SYMLINK+="rtl_sdr"
|
|
@ -0,0 +1,174 @@
|
||||||
|
- alias: monitor_radiators_reporting
|
||||||
|
description: monitor that the battery-powered radiator knobs are working
|
||||||
|
trigger:
|
||||||
|
{% for radiator in hass_radiators -%}
|
||||||
|
{% if 'status' in radiator -%}
|
||||||
|
- platform: state
|
||||||
|
id: "radiator {{ radiator.name }}"
|
||||||
|
entity_id:
|
||||||
|
- binary_sensor.radiator_{{ radiator.name }}_reporting
|
||||||
|
to: 'off'
|
||||||
|
{% endif -%}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
condition: []
|
||||||
|
mode: single
|
||||||
|
action:
|
||||||
|
- service: notify.persistent_notification
|
||||||
|
data:
|
||||||
|
title: 'device not reporting'
|
||||||
|
message: 'stopped reporting: {%raw%}{{ trigger.id }}{%endraw%}'
|
||||||
|
- service: notify.notify
|
||||||
|
data:
|
||||||
|
title: 'device not reporting'
|
||||||
|
message: 'stopped reporting: {%raw%}{{ trigger.id }}{%endraw%}'
|
||||||
|
|
||||||
|
- alias: refresh_light_switches_state
|
||||||
|
description: the tkbhome switches dont automatically report their state
|
||||||
|
trigger:
|
||||||
|
- platform: time_pattern
|
||||||
|
minutes: "/1"
|
||||||
|
condition: []
|
||||||
|
mode: single
|
||||||
|
action:
|
||||||
|
- service: zwave_js.refresh_value
|
||||||
|
data:
|
||||||
|
entity_id:
|
||||||
|
{% for item in hass_light_switches -%}
|
||||||
|
{% if item.automation_refresh|default(false) -%}
|
||||||
|
- {{ item.entity_id }}
|
||||||
|
{% endif -%}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% for item in hass_light_switches -%}
|
||||||
|
{% set domain = item.entity_id.split('.')[0] %}
|
||||||
|
{% set name = item.entity_id.split('.')[1] %}
|
||||||
|
{% if 'auto_off' in item %}
|
||||||
|
- alias: {{ name }}_turn_off
|
||||||
|
description: automatically turn off {{ name }} {{ domain}}
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id:
|
||||||
|
- {{ item.entity_id }}
|
||||||
|
to: "on"
|
||||||
|
for:
|
||||||
|
minutes: {{ item.auto_off }}
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: {{ item.entity_id }}
|
||||||
|
state: "on"
|
||||||
|
action:
|
||||||
|
- service: {{ domain }}.turn_off
|
||||||
|
data: {}
|
||||||
|
target:
|
||||||
|
entity_id: {{ item.entity_id }}
|
||||||
|
mode: single
|
||||||
|
{% endif -%}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% for linux_tracker in hass_linux_presence_trackers -%}
|
||||||
|
- alias: "webhook_presence_trackers_{{ linux_tracker.name }}"
|
||||||
|
description: ""
|
||||||
|
trigger:
|
||||||
|
- platform: webhook
|
||||||
|
webhook_id: {{ linux_tracker.name }}-{{ linux_tracker.webhook_key }}
|
||||||
|
id: webhook
|
||||||
|
mode: single
|
||||||
|
action:
|
||||||
|
- if:
|
||||||
|
- condition: template
|
||||||
|
value_template: >-
|
||||||
|
{%raw -%} {% {%endraw%} set current_value = states('input_text.webhook_{{ linux_tracker.name }}') {%raw%} %} {%endraw%}
|
||||||
|
{% raw %}
|
||||||
|
{{ current_value != trigger.json['state'] }}
|
||||||
|
{% endraw %}
|
||||||
|
|
||||||
|
then:
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: input_text.webhook_{{ linux_tracker.name }}
|
||||||
|
data:
|
||||||
|
value: "{% raw %}{{ trigger.json.state }}{% endraw %}"
|
||||||
|
|
||||||
|
- alias: "inactive_webhook_presence_trackers_{{ linux_tracker.name }}"
|
||||||
|
description: ""
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id: binary_sensor.{{ linux_tracker.name }}_webhook_triggering
|
||||||
|
to: "off"
|
||||||
|
action:
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: input_text.webhook_{{ linux_tracker.name }}
|
||||||
|
data:
|
||||||
|
value: "inactive"
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
- alias: flood_sensor_washing_machine
|
||||||
|
description: ""
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id:
|
||||||
|
- binary_sensor.flood_sensor_water_leak_detected
|
||||||
|
to: "on"
|
||||||
|
condition: []
|
||||||
|
mode: single
|
||||||
|
action:
|
||||||
|
- service: switch.turn_off
|
||||||
|
data: {}
|
||||||
|
target:
|
||||||
|
entity_id: switch.washing_machine
|
||||||
|
- service: notify.notify
|
||||||
|
data:
|
||||||
|
title: "FLOOD SENSOR BATHROOM"
|
||||||
|
message: "WATER DETECTED! power to washing machine was cut"
|
||||||
|
- if:
|
||||||
|
- condition: zone
|
||||||
|
entity_id: person.ben
|
||||||
|
zone: zone.home
|
||||||
|
then:
|
||||||
|
- service: switch.turn_on
|
||||||
|
data: {}
|
||||||
|
target:
|
||||||
|
entity_id: switch.nad_c370
|
||||||
|
- service: media_player.play_media
|
||||||
|
data:
|
||||||
|
media_content_type: video/webm
|
||||||
|
media_content_id: media-source://media_source/media/flood_alert.mp3
|
||||||
|
target:
|
||||||
|
entity_id: media_player.den_tv
|
||||||
ben
commented
improve improve
|
|||||||
|
|
||||||
|
- alias: buzzer_normally_closed
|
||||||
|
description: "keep the buzzer switch closed"
|
||||||
|
mode: single
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id:
|
||||||
|
- switch.doorbell_buzzer
|
||||||
|
to: "on"
|
||||||
|
for:
|
||||||
|
hours: 0
|
||||||
|
minutes: 0
|
||||||
|
seconds: 1
|
||||||
|
condition: []
|
||||||
|
action:
|
||||||
|
- service: switch.turn_off
|
||||||
|
data: {}
|
||||||
|
target:
|
||||||
|
entity_id: switch.doorbell_buzzer
|
||||||
|
|
||||||
|
{% for item in hass_feedreader -%}
|
||||||
|
- alias: "podcast_parse_feed_{{ item.short_name }}"
|
||||||
|
trigger:
|
||||||
|
platform: event
|
||||||
|
event_type: feedreader
|
||||||
|
event_data:
|
||||||
|
feed_url: "{{ item.url }}"
|
||||||
|
action:
|
||||||
|
service: persistent_notification.create
|
||||||
|
data:
|
||||||
|
title: "Podcast parsed"
|
||||||
|
message: {% raw %}"{{ trigger.event.data }}"{% endraw %}
|
||||||
|
|
||||||
|
{% endfor %}
|
|
@ -0,0 +1,38 @@
|
||||||
|
{#
|
||||||
|
# nmcli device wifi blackbox ifname wlo1 ssid {{ hass_wifi_blackbox.ssid }} password {{ hass_wifi_blackbox.pass }}
|
||||||
|
#}
|
||||||
|
[connection]
|
||||||
|
id=blackbox
|
||||||
|
uuid={{ hass_wifi_blackbox.uuid }}
|
||||||
|
type=wifi
|
||||||
|
autoconnect=false
|
||||||
|
interface-name={{ hass_wifi_blackbox.iface }}
|
||||||
|
{% if timestamp.stdout %}
|
||||||
|
{{ timestamp.stdout }}
|
||||||
|
{% else %}
|
||||||
|
timestamp={{ ansible_date_time.epoch }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
[wifi]
|
||||||
|
mode=ap
|
||||||
|
ssid={{ hass_wifi_blackbox.ssid }}
|
||||||
|
{% if hass_wifi_blackbox.hidden|default(false) -%}
|
||||||
|
hidden=true
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
[wifi-security]
|
||||||
|
group=ccmp;
|
||||||
|
key-mgmt=wpa-psk
|
||||||
|
pairwise=ccmp;
|
||||||
|
proto=rsn;
|
||||||
|
psk={{ hass_wifi_blackbox.pass }}
|
||||||
|
|
||||||
|
[ipv4]
|
||||||
|
address1={{ hass_wifi_blackbox.ip }}/{{ hass_wifi_blackbox.cidr_prefix }}
|
||||||
|
method=manual
|
||||||
|
|
||||||
|
[ipv6]
|
||||||
|
addr-gen-mode=stable-privacy
|
||||||
|
method=ignore
|
||||||
|
|
||||||
|
[proxy]
|
|
@ -0,0 +1,71 @@
|
||||||
|
{% if blink1_enabled -%}
|
||||||
|
friendly_name: blink1
|
||||||
|
value_template: >-
|
||||||
|
{% raw -%}
|
||||||
|
{{ state_attr('sensor.blink1', 'rgb') != "#000000" }}
|
||||||
|
{% endraw %}
|
||||||
|
|
||||||
|
# color_template: >-
|
||||||
|
# {% raw -%}
|
||||||
|
# {{ state_attr('sensor.blink1', 'rgb') }}
|
||||||
|
# {% endraw %}
|
||||||
|
|
||||||
|
turn_on:
|
||||||
|
- service: rest_command.blink1_turn_on
|
||||||
|
- delay:
|
||||||
|
milliseconds: 500
|
||||||
|
- service: homeassistant.update_entity
|
||||||
|
target:
|
||||||
|
entity_id: sensor.blink1
|
||||||
|
turn_off:
|
||||||
|
- service: rest_command.blink1_turn_off
|
||||||
|
- delay:
|
||||||
|
milliseconds: 500
|
||||||
|
- service: homeassistant.update_entity
|
||||||
|
target:
|
||||||
|
entity_id: sensor.blink1
|
||||||
|
set_color:
|
||||||
|
- service: rest_command.blink1_turn_off
|
||||||
|
- service: rest_command.blink1_set_color
|
||||||
|
data:
|
||||||
|
# https://github.com/velijv/home-assistant-color-helpers#rgb-to-hex
|
||||||
|
# https://community.home-assistant.io/t/advanced-light-template-help/175654
|
||||||
|
# https://community.home-assistant.io/t/using-hsv-hsb-to-set-colored-lights/15472
|
||||||
|
rgb: >-
|
||||||
|
{%raw%}
|
||||||
|
{%- set h2 = h / 360 -%}
|
||||||
|
{%- set s2 = s / 100 -%}
|
||||||
|
{%- set v = 100 -%}
|
||||||
|
{%- set i = (h2 * 6 ) | round(2,'floor') | int-%}
|
||||||
|
{%- set f = h2 * 6 - i -%}
|
||||||
|
{%- set p = v * (1 - s2) -%}
|
||||||
|
{%- set q = v * (1 - f * s2) -%}
|
||||||
|
{%- set t = v * (1 - (1 - f) * s2) -%}
|
||||||
|
{%- if i % 6 == 0 -%}
|
||||||
|
{%- set r = v | int -%}
|
||||||
|
{%- set g = t | int -%}
|
||||||
|
{%- set b = p | int -%}
|
||||||
|
{%- elif i % 6 == 1 -%}
|
||||||
|
{%- set r = q | int -%}
|
||||||
|
{%- set g = v | int -%}
|
||||||
|
{%- set b = p | int -%}
|
||||||
|
{%- elif i % 6 == 2 -%}
|
||||||
|
{%- set r = p | int -%}
|
||||||
|
{%- set g = v | int -%}
|
||||||
|
{%- set b = t | int -%}
|
||||||
|
{%- elif i % 6 == 3 -%}
|
||||||
|
{%- set r = p | int -%}
|
||||||
|
{%- set g = q | int -%}
|
||||||
|
{%- set b = v | int -%}
|
||||||
|
{%- elif i % 6 == 4 -%}
|
||||||
|
{%- set r = t | int -%}
|
||||||
|
{%- set g = p | int -%}
|
||||||
|
{%- set b = v | int -%}
|
||||||
|
{%- elif i % 6 == 5 -%}
|
||||||
|
{%- set r = v | int -%}
|
||||||
|
{%- set g = p | int -%}
|
||||||
|
{%- set b = q | int -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{{ '%02x%02x%02x' | format(r, g, b) }}
|
||||||
|
{%endraw%}
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,52 @@
|
||||||
|
{% raw -%}
|
||||||
|
- platform: climate_template
|
||||||
|
name: Radiators
|
||||||
|
modes:
|
||||||
|
- "auto"
|
||||||
|
- "heat"
|
||||||
|
- "cool"
|
||||||
|
- "off"
|
||||||
|
min_temp: 0
|
||||||
|
max_temp: 30
|
||||||
|
|
||||||
|
current_temperature_template: "{{ states('input_number.heating_setpoint_test') }}"
|
||||||
|
hvac_mode_template: "{{ states('input_select.heating_mode_test') }}"
|
||||||
|
current_humidity_template: 0.0
|
||||||
|
swing_mode_template: false
|
||||||
|
availability_template: true
|
||||||
|
|
||||||
|
set_temperature:
|
||||||
|
- service: input_number.set_value
|
||||||
|
data:
|
||||||
|
value: >-
|
||||||
|
{% set set_point = float(state_attr('climate.radiators', 'temperature'), 14.0) %}
|
||||||
|
{{ set_point }}
|
||||||
|
target:
|
||||||
|
entity_id: input_number.heating_setpoint_test
|
||||||
|
|
||||||
|
set_hvac_mode:
|
||||||
|
- service: input_select.select_option
|
||||||
|
data:
|
||||||
|
option: >-
|
||||||
|
{% set hvac_mode = state_attr('climate.radiators', 'hvac_mode') | default('off') %}
|
||||||
|
{{ hvac_mode }}
|
||||||
|
target:
|
||||||
|
entity_id: input_select.heating_mode_test
|
||||||
|
|
||||||
|
{% endraw %}
|
||||||
|
|
||||||
|
{# use this in script?
|
||||||
|
{{ state_attr('climate.radiators', 'temperature') }}
|
||||||
|
|
||||||
|
this should work, but doesnt
|
||||||
|
docs: https://www.home-assistant.io/integrations/template/
|
||||||
|
{{ this.attributes.temperature }}
|
||||||
|
|
||||||
|
https://github.com/jcwillox/hass-template-climate/issues/29
|
||||||
|
|
||||||
|
this syntax works:
|
||||||
|
{% set set_point = float(state_attr('climate.radiators', 'temperature'), 14.0) %}
|
||||||
|
{{ set_point }}
|
||||||
|
|
||||||
|
target_temperature_template: "{{ states('input_number.heating_setpoint_test') }}"
|
||||||
|
#}
|
|
@ -57,48 +57,84 @@ default_config:
|
||||||
# zeroconf:
|
# zeroconf:
|
||||||
# zone:
|
# zone:
|
||||||
|
|
||||||
|
automation ui: !include automations.yaml
|
||||||
|
automation ansible: !include automations-ansible-managed.yaml
|
||||||
|
script: !include scripts.yaml
|
||||||
|
scene: !include scenes.yaml
|
||||||
|
template: !include templates.yaml
|
||||||
|
climate: !include climate.yaml
|
||||||
|
|
||||||
# Text to speech
|
# Text to speech
|
||||||
tts:
|
tts:
|
||||||
- platform: voicerss
|
- platform: voicerss
|
||||||
api_key: !secret voicerss_api_key
|
api_key: !secret voicerss_api_key
|
||||||
- platform: google_translate
|
- platform: google_translate
|
||||||
|
- platform: picotts
|
||||||
automation: !include automations.yaml
|
language: "en-GB"
|
||||||
script: !include scripts.yaml
|
|
||||||
scene: !include scenes.yaml
|
|
||||||
template: !include templates.yaml
|
|
||||||
|
|
||||||
{# calendar:
|
|
||||||
# {% for item in hass_caldav.urls %}
|
|
||||||
#
|
|
||||||
# - platform: caldav
|
|
||||||
# days: 30
|
|
||||||
# username: !secret caldav_user
|
|
||||||
# password: !secret caldav_passwd
|
|
||||||
# # {{ item.name }}
|
|
||||||
# url: {{ item.url }}
|
|
||||||
#
|
|
||||||
# {% endfor %}
|
|
||||||
#}
|
|
||||||
|
|
||||||
calendar:
|
calendar:
|
||||||
|
{% for item in hass_caldav.calendars -%}
|
||||||
- platform: caldav
|
- platform: caldav
|
||||||
days: 30
|
days: 30
|
||||||
username: !secret caldav_user
|
username: !secret caldav_user
|
||||||
password: !secret caldav_passwd
|
password: !secret caldav_passwd
|
||||||
# {{ hass_caldav.urls[0].name }}
|
# {{ item.name | trim }}
|
||||||
url: {{ hass_caldav.urls[0].url }}
|
url: {{ item.url | trim }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
http:
|
http:
|
||||||
# container runs with network_mode=host, so no network isolation. the docs say to not
|
server_host: 127.0.0.1
|
||||||
# do this, and it doesnt work as expected either.
|
server_port: 8123
|
||||||
# using ufw/iptables for now....
|
|
||||||
#
|
|
||||||
#server_host: 127.0.0.1
|
|
||||||
trusted_proxies:
|
trusted_proxies:
|
||||||
- 127.0.0.1
|
- 127.0.0.1
|
||||||
use_x_forwarded_for: true
|
use_x_forwarded_for: true
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
themes: !include_dir_merge_named themes
|
||||||
|
|
||||||
|
panel_custom:
|
||||||
|
- name: zwave
|
||||||
|
sidebar_title: Z-Wave
|
||||||
|
sidebar_icon: mdi:z-wave
|
||||||
|
js_url: /api/hassio/app/entrypoint.js
|
||||||
|
url_path: 'config/devices/dashboard?historyBack=1&config_entry=d6e38621854098348266029e18f93048'
|
||||||
|
embed_iframe: true
|
||||||
|
require_admin: true
|
||||||
|
config:
|
||||||
|
ingress: core_configurator
|
||||||
|
- name: automations
|
||||||
|
sidebar_title: Automations
|
||||||
|
sidebar_icon: mdi:robot
|
||||||
|
js_url: /api/hassio/app/entrypoint.js
|
||||||
|
url_path: 'config/automation/dashboard'
|
||||||
|
embed_iframe: true
|
||||||
|
require_admin: true
|
||||||
|
config:
|
||||||
|
ingress: core_configurator
|
||||||
|
- name: scripts
|
||||||
|
sidebar_title: Scripts
|
||||||
|
sidebar_icon: mdi:script
|
||||||
|
js_url: /api/hassio/app/entrypoint.js
|
||||||
|
url_path: 'config/script/dashboard'
|
||||||
|
embed_iframe: true
|
||||||
|
require_admin: true
|
||||||
|
config:
|
||||||
|
ingress: core_configurator
|
||||||
|
- name: integrations
|
||||||
|
sidebar_title: Integrations
|
||||||
|
sidebar_icon: mdi:integrated-circuit-chip
|
||||||
|
js_url: /api/hassio/app/entrypoint.js
|
||||||
|
url_path: 'config/integrations'
|
||||||
|
embed_iframe: true
|
||||||
|
require_admin: true
|
||||||
|
config:
|
||||||
|
ingress: core_configurator
|
||||||
|
|
||||||
|
|
||||||
|
{% set zone = {'zone': hass_zones} %}
|
||||||
|
{{ zone | to_nice_yaml }}
|
||||||
|
|
||||||
|
|
||||||
homeassistant:
|
homeassistant:
|
||||||
auth_providers:
|
auth_providers:
|
||||||
- type: command_line
|
- type: command_line
|
||||||
|
@ -109,6 +145,7 @@ homeassistant:
|
||||||
currency: EUR
|
currency: EUR
|
||||||
unit_system: metric
|
unit_system: metric
|
||||||
time_zone: "Europe/Berlin"
|
time_zone: "Europe/Berlin"
|
||||||
|
country: DE
|
||||||
external_url: https://{{ hass_url }}
|
external_url: https://{{ hass_url }}
|
||||||
internal_url: https://{{ hass_url }}
|
internal_url: https://{{ hass_url }}
|
||||||
allowlist_external_dirs:
|
allowlist_external_dirs:
|
||||||
|
@ -118,6 +155,42 @@ homeassistant:
|
||||||
- "https://{{ hass_notflix_url }}"
|
- "https://{{ hass_notflix_url }}"
|
||||||
media_dirs:
|
media_dirs:
|
||||||
media: "/usr/var/media"
|
media: "/usr/var/media"
|
||||||
|
customize:
|
||||||
|
zone.home:
|
||||||
|
friendly_name: S21
|
||||||
|
|
||||||
|
lovelace:
|
||||||
|
mode: storage
|
||||||
|
dashboards:
|
||||||
|
lovelace-yaml:
|
||||||
|
mode: yaml
|
||||||
|
title: Mini
|
||||||
|
icon: mdi:view-dashboard
|
||||||
|
show_in_sidebar: true
|
||||||
|
require_admin: false
|
||||||
|
filename: mini.yaml
|
||||||
|
lovelace-yaml2:
|
||||||
|
mode: yaml
|
||||||
|
title: Test
|
||||||
|
icon: mdi:view-dashboard
|
||||||
|
show_in_sidebar: true
|
||||||
|
require_admin: false
|
||||||
|
filename: ui-test.yaml
|
||||||
|
|
||||||
|
{# resources:
|
||||||
|
# - url: /config/custom_components/ui_lovelace_minimalist/cards/button-card/button-card.js
|
||||||
|
# type: module
|
||||||
|
# - url: /config/custom_components/ui_lovelace_minimalist/cards/button-card/button-card.js
|
||||||
|
# type: module #}
|
||||||
|
|
||||||
|
recorder:
|
||||||
|
purge_keep_days: 3
|
||||||
|
exclude:
|
||||||
|
entity_globs:
|
||||||
|
- binary_sensor.1066d799*
|
||||||
|
- sensor.1066d799*
|
||||||
|
- light.1066d799*
|
||||||
|
|
||||||
|
|
||||||
sensor:
|
sensor:
|
||||||
# https://www.home-assistant.io/integrations/dwd_weather_warnings/
|
# https://www.home-assistant.io/integrations/dwd_weather_warnings/
|
||||||
|
@ -144,28 +217,116 @@ sensor:
|
||||||
# Stadt Berlin
|
# Stadt Berlin
|
||||||
region_name: 811000000
|
region_name: 811000000
|
||||||
|
|
||||||
|
{% for item in hass_bvg -%}
|
||||||
|
- platform: bvg_berlin_public_transport
|
||||||
|
name: {{ item.name }}
|
||||||
|
stop_id: "{{ item.stop_id }}"
|
||||||
|
direction: {{ item.direction | trim }}
|
||||||
|
{% if item.walking_distance is defined -%}
|
||||||
|
walking_distance: {{ item.walking_distance | trim }}
|
||||||
|
{% endif -%}
|
||||||
|
file_path: "/config/bvg/"
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
- platform: waqi
|
||||||
|
token: !secret waqi_token
|
||||||
|
locations:
|
||||||
|
{% for item in hass_waqi.locations -%}
|
||||||
|
- "{{ item | trim }}"
|
||||||
|
{%- endfor +%}
|
||||||
|
{#stations:
|
||||||
|
#{% for item in hass_waqi.stations -%}
|
||||||
|
#- "{{ item | trim }}"
|
||||||
|
#{% endfor %}
|
||||||
|
#}
|
||||||
|
|
||||||
|
{% if blink1_enabled -%}
|
||||||
|
- platform: rest
|
||||||
|
resource: http://localhost:{{ blink1_server_port }}/blink1
|
||||||
|
name: blink1
|
||||||
|
json_attributes:
|
||||||
|
- rgb
|
||||||
|
- bright
|
||||||
|
value_template: "{%raw%}{{ value_json.rgb }}{%endraw%}"
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: workday
|
- platform: workday
|
||||||
country: DE
|
country: DE
|
||||||
workdays: [mon, tue, wed, thu, fri]
|
workdays: [mon, tue, wed, thu, fri]
|
||||||
excludes: [sat, sun, holiday]
|
excludes: [sat, sun, holiday]
|
||||||
|
|
||||||
|
{% for radiator in hass_radiators -%}
|
||||||
|
{% if 'status' in radiator -%}
|
||||||
|
- platform: threshold
|
||||||
|
entity_id: sensor.radiator_{{ radiator.name }}_last_updated
|
||||||
|
# defined in templates.yaml
|
||||||
|
name: radiator_{{ radiator.name }}_reporting
|
||||||
|
# minutes
|
||||||
|
lower: 10
|
||||||
|
{% endif -%}
|
||||||
|
{% endfor -%}
|
||||||
{% for target in hass_ping -%}
|
{% for target in hass_ping -%}
|
||||||
- platform: ping
|
- platform: ping
|
||||||
name: ping_{{ target.name }}
|
name: ping_{{ target.name }}
|
||||||
host: {{ target.host }}
|
host: {{ target.host }}
|
||||||
count: 1
|
count: {{ target.count | default('1') }}
|
||||||
scan_interval: {{ target.interval_secs }}
|
scan_interval: {{ target.interval_secs | default('30') }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
input_select:
|
||||||
|
heating_mode_test:
|
||||||
|
name: Heating Mode Test
|
||||||
|
options:
|
||||||
|
- "auto"
|
||||||
|
- "heat"
|
||||||
|
- "cool"
|
||||||
|
- "off"
|
||||||
|
initial: "off"
|
||||||
|
icon: mdi:thermometer-lines
|
||||||
|
|
||||||
|
|
||||||
|
input_number:
|
||||||
|
heating_setpoint_test:
|
||||||
|
name: Heating Setpoint Test
|
||||||
|
icon: mdi:home-thermometer
|
||||||
|
initial: 0
|
||||||
|
min: 0
|
||||||
|
max: 35
|
||||||
|
step: 0.5
|
||||||
|
|
||||||
|
input_text:
|
||||||
|
{% for linux_tracker in hass_linux_presence_trackers -%}
|
||||||
|
webhook_{{ linux_tracker.name }}:
|
||||||
|
name: webhook_{{ linux_tracker.name }}
|
||||||
|
icon: "mdi:laptop"
|
||||||
|
initial: "inactive"
|
||||||
|
pattern: "^active|inactive$"
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
device_tracker:
|
device_tracker:
|
||||||
|
- platform: bluetooth_le_tracker
|
||||||
|
interval_seconds: 12
|
||||||
|
track_new_devices: false
|
||||||
|
track_battery: false
|
||||||
|
consider_home: 150
|
||||||
|
new_device_defaults:
|
||||||
|
track_new_devices: false
|
||||||
|
- platform: bluetooth_tracker
|
||||||
|
request_rssi: false
|
||||||
|
interval_seconds: 12
|
||||||
|
track_new_devices: false
|
||||||
|
consider_home: 150
|
||||||
|
new_device_defaults:
|
||||||
|
track_new_devices: false
|
||||||
- platform: ping
|
- platform: ping
|
||||||
hosts:
|
hosts:
|
||||||
{% for target in hass_ping -%}
|
{% for target in hass_ping -%}
|
||||||
|
{% if target.device_tracker|default(true) -%}
|
||||||
{{ target.name }}: {{ target.host }}
|
{{ target.name }}: {{ target.host }}
|
||||||
|
{% endif -%}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
# enabling bluetooth
|
|
||||||
bluetooth:
|
|
||||||
|
|
||||||
influxdb:
|
influxdb:
|
||||||
host: "{{ influxdb_url }}"
|
host: "{{ influxdb_url }}"
|
||||||
|
@ -186,5 +347,79 @@ influxdb:
|
||||||
source: hass
|
source: hass
|
||||||
home: S21
|
home: S21
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
homeserver: https://{{ matrix_url }}
|
||||||
|
username: !secret matrix_username
|
||||||
|
password: !secret matrix_password
|
||||||
|
rooms: !secret matrix_rooms
|
||||||
|
commands:
|
||||||
|
- word: hass
|
||||||
|
name: hass
|
||||||
|
|
||||||
|
notify:
|
||||||
|
- name: matrix
|
||||||
|
platform: matrix
|
||||||
|
default_room: !secret matrix_default_room
|
||||||
|
- name: pagerduty
|
||||||
|
platform: smtp
|
||||||
|
sender: hass@{{ domain }}
|
||||||
|
recipient:
|
||||||
|
- !secret smtp_recipient_email
|
||||||
|
server: !secret smtp_server
|
||||||
|
port: {{ smtp_port_starttls }}
|
||||||
|
username: !secret smtp_username
|
||||||
|
password: !secret smtp_passwd
|
||||||
|
encryption: starttls
|
||||||
|
sender_name: "{{ hass_url }}"
|
||||||
|
|
||||||
shell_command:
|
shell_command:
|
||||||
matrixmsg: /usr/local/bin/matrixmsg.py
|
matrixmsg: /usr/local/bin/matrixmsg.py
|
||||||
|
|
||||||
|
rest_command:
|
||||||
|
{% if blink1_enabled -%}
|
||||||
|
blink1_turn_on:
|
||||||
|
url: {{ hass_blink1_url }}/blink1/on?bright=250
|
||||||
|
#url: http://localhost:{{ blink1_server_port }}/blink1/fadeToRGB?rgb=ff0ff
|
||||||
|
method: GET
|
||||||
|
content_type: "application/json"
|
||||||
|
blink1_turn_off:
|
||||||
|
url: {{ hass_blink1_url }}/blink1/off
|
||||||
|
method: GET
|
||||||
|
content_type: "application/json"
|
||||||
|
blink1_turn_magenta:
|
||||||
|
url: {{ hass_blink1_url }}/blink1/fadeToRGB?rgb=ff00ff
|
||||||
|
method: GET
|
||||||
|
content_type: "application/json"
|
||||||
|
blink1_set_color:
|
||||||
|
url: "{{ hass_blink1_url }}/blink1/fadeToRGB?rgb={%raw%}{{ rgb }}{%endraw%}"
|
||||||
|
method: GET
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
light:
|
||||||
|
{% if blink1_enabled -%}
|
||||||
|
- platform: template
|
||||||
|
lights:
|
||||||
|
blink1: !include blink1.yaml
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# enable 'wake_on_lan' for 'samsungtv'
|
||||||
|
wake_on_lan:
|
||||||
|
|
||||||
|
samsungtv:
|
||||||
|
- host: {{ hass_wifi_blackbox.tv_ip }}
|
||||||
|
name: The TV
|
||||||
|
turn_on_action:
|
||||||
|
- service: wake_on_lan.send_magic_packet
|
||||||
|
data:
|
||||||
|
mac: "{{ hass_wifi_blackbox.tv_mac }}"
|
||||||
|
|
||||||
|
feedreader:
|
||||||
|
urls:
|
||||||
|
{% for item in hass_feedreader -%}
|
||||||
|
- "{{ item.url | trim }}"
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{# logger:
|
||||||
|
# logs:
|
||||||
|
# pyatv: debug
|
||||||
|
# homeassistant.components.apple_tv: debug #}
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
# we can "safely" template in the actual secrets here and keep them out of
|
# we can "safely" template in the actual secrets here and keep them out of
|
||||||
# configuration.yaml, which does get synced to the repo.
|
# configuration.yaml, which does get synced to the repo.
|
||||||
|
|
||||||
|
openwrt_user: "{{ hass_openwrt_user }}"
|
||||||
|
openwrt_pass: "{{ hass_openwrt_pass }}"
|
||||||
|
|
||||||
caldav_user: "{{ hass_caldav.user }}"
|
caldav_user: "{{ hass_caldav.user }}"
|
||||||
caldav_passwd: "{{ hass_caldav.passwd }}"
|
caldav_passwd: "{{ hass_caldav.passwd }}"
|
||||||
|
|
||||||
|
@ -10,3 +13,17 @@ voicerss_api_key: {{ voicerss_api_key }}
|
||||||
|
|
||||||
# see group_vars/monitoring.yml
|
# see group_vars/monitoring.yml
|
||||||
influxdb_pass: {{ hass_influxdb_pass }}
|
influxdb_pass: {{ hass_influxdb_pass }}
|
||||||
|
|
||||||
|
matrix_username: "{{ hass_matrix.username }}"
|
||||||
|
matrix_password: "{{ hass_matrix.password }}"
|
||||||
|
{% set rooms = {'matrix_rooms': hass_matrix.rooms} -%}
|
||||||
|
{{ rooms | to_nice_yaml }}
|
||||||
|
matrix_default_room: "{{ hass_matrix.rooms[0] }}"
|
||||||
|
|
||||||
|
smtp_recipient_email: "{{ pagerduty_email }}"
|
||||||
|
smtp_server: "{{ smtp_server }}"
|
||||||
|
smtp_username: "{{ smtp_username }}"
|
||||||
|
smtp_passwd: "{{ smtp_passwd }}"
|
||||||
|
|
||||||
|
|
||||||
|
waqi_token: {{ hass_waqi.token }}
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
- sensor:
|
||||||
ben marked this conversation as resolved
ben
commented
this file needs serious work but thats not for this pr this file needs serious work but thats not for this pr
|
|||||||
|
- name: "chance_of_rain"
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
icon: "mdi:weather-pouring"
|
||||||
|
state: >-
|
||||||
|
{% raw -%}
|
||||||
|
{% set ipma_2h = state_attr('weather.ipma_hourly_home', 'forecast')[:2] | map(attribute='precipitation_probability') %}
|
||||||
|
{% set ipma = state_attr('weather.ipma_hourly_home', 'forecast')[0]['precipitation_probability'] | int %}
|
||||||
|
{% set owm = states('sensor.owm_home_forecast_precipitation_probability') | int %}
|
||||||
|
{{ [owm, ipma, 0] | max | int }}
|
||||||
|
{% endraw %}
|
||||||
|
|
||||||
|
{% for radiator in hass_radiators %}
|
||||||
|
{% if 'status' in radiator %}
|
||||||
|
|
||||||
|
- name: "radiator_{{ radiator.name }}_last_updated"
|
||||||
|
unit_of_measurement: "minutes"
|
||||||
|
icon: "mdi:update"
|
||||||
|
device_class: duration
|
||||||
|
state: >-
|
||||||
|
{% raw %} {% {% endraw -%}
|
||||||
|
set since_last_update = now() - states.{{ radiator.status }}.last_updated
|
||||||
|
{%- raw %} %} {% endraw %}
|
||||||
|
|
||||||
|
{% raw %} {{ {% endraw -%}
|
||||||
|
since_last_update.seconds|int // 60
|
||||||
|
{%- raw %} }} {% endraw -%}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for linux_tracker in hass_linux_presence_trackers -%}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
- binary_sensor:
|
||||||
|
{% if blink1_enabled -%}
|
||||||
|
- name: "blink1_on"
|
||||||
|
device_class: light
|
||||||
|
state: >-
|
||||||
|
{% raw -%}
|
||||||
|
{{ state_attr('sensor.blink1', 'rgb') != "#000000" }}
|
||||||
|
{% endraw %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
- name: "heating_on"
|
||||||
|
icon: "mdi:home-thermometer"
|
||||||
|
device_class: heat
|
||||||
|
state: >-
|
||||||
|
{% raw -%}
|
||||||
|
{% set all_radiators = states.climate | selectattr("attributes", "defined") | map(attribute="attributes") | selectattr("temperature", "defined") | map(attribute="temperature") | default([]) | list %}
|
||||||
|
{% set max_radiator_temp = all_radiators | max | default(0.0) | float %}
|
||||||
|
{% set target_temp = states('input_number.target_temp_heat') | default(0.0) | float %}
|
||||||
|
{{ max_radiator_temp >= target_temp }}
|
||||||
|
{% endraw %}
|
||||||
|
|
||||||
|
- name: s21_anyone_home
|
||||||
ben marked this conversation as resolved
ben
commented
remove remove
ben
commented
fixed, not in this pr. fixed, not in this pr.
|
|||||||
|
icon: "mdi:home-account"
|
||||||
|
attributes:
|
||||||
|
friendly_name: "Anyone home"
|
||||||
|
state: >-
|
||||||
|
{% raw -%}
|
||||||
|
{{ state_attr("zone.home", "persons") | default([]) | length > 0 }}
|
||||||
|
{% endraw %}
|
||||||
|
|
||||||
|
- name: doorbell_buzzer
|
||||||
|
state: >-
|
||||||
|
{% raw %} {{ is_state("switch.doorbell_buzzer", "on") }} {% endraw +%}
|
||||||
|
icon: >-
|
||||||
|
{% raw -%}
|
||||||
|
{% if is_state("switch.doorbell_buzzer", "on") %}
|
||||||
|
mdi:electric-switch-closed
|
||||||
|
{% else %}
|
||||||
|
mdi:electric-switch
|
||||||
|
{% endif %}
|
||||||
|
{% endraw %}
|
||||||
|
|
||||||
|
- name: washing_machine_on
|
||||||
|
icon: "mdi:washing-machine"
|
||||||
|
device_class: running
|
||||||
|
delay_on: "00:00:05"
|
||||||
|
delay_off: "00:00:05"
|
||||||
|
state: >-
|
||||||
|
{% raw -%}
|
||||||
|
{% set current = states('sensor.washing_machine_electric_a') %}
|
||||||
|
{% set power = states('sensor.washing_machine_electric_w') %}
|
||||||
|
{% if current == "unavailable" or power == "unavailable" %}
|
||||||
|
{{ false }}
|
||||||
|
{% else %}
|
||||||
|
{{ current|default(0.0)|float > 0.14 or power|default(0.0)|float > 2.8 }}
|
||||||
|
{% endif %}
|
||||||
|
{% endraw %}
|
||||||
|
|
||||||
|
{% for linux_tracker in hass_linux_presence_trackers -%}
|
||||||
|
- name: {{ linux_tracker.name }}_active
|
||||||
|
icon: "mdi:laptop"
|
||||||
|
state: >-
|
||||||
|
{% raw -%} {% {% endraw %} set state_text = states('input_text.webhook_{{ linux_tracker.name }}') {%raw%} %} {%endraw%}
|
||||||
|
{% raw %}
|
||||||
|
{{ state_text == "active" }}
|
||||||
|
{% endraw %}
|
||||||
|
|
||||||
|
- name: "{{ linux_tracker.name }}_webhook_triggering"
|
||||||
|
state: >-
|
||||||
|
{% raw %} {% {% endraw -%}
|
||||||
|
set since_last_triggered = now() - state_attr('automation.webhook_presence_trackers_{{ linux_tracker.name }}', 'last_triggered')
|
||||||
|
{%- raw %} %} {% endraw %}
|
||||||
|
|
||||||
|
{% raw %} {{ {% endraw -%}
|
||||||
|
since_last_triggered.seconds|int < 666
|
||||||
|
{%- raw %} }} {% endraw -%}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
- button:
|
||||||
|
name: doorbell_buzzer
|
||||||
|
icon: >-
|
||||||
|
{% raw -%}
|
||||||
|
{% if is_state("switch.doorbell_buzzer", "on") %}
|
||||||
|
mdi:electric-switch-closed
|
||||||
|
{% else %}
|
||||||
|
mdi:electric-switch
|
||||||
|
{% endif %}
|
||||||
|
{% endraw +%}
|
||||||
|
press:
|
||||||
|
- service: script.toggle_switch_like_button
|
||||||
|
data:
|
||||||
|
target_switch: switch.doorbell_buzzer
|
||||||
|
press_for_ms: 200
|
||||||
ben marked this conversation as resolved
ben
commented
duplicate file? duplicate file?
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- unifi
|
||||||
|
- sudoisbot
|
||||||
|
- hass
|
||||||
|
- homeaudio
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- podgrab
|
||||||
|
- airconnect
|
||||||
|
- shairplay
|
||||||
|
- owntone
|
|
@ -0,0 +1,452 @@
|
||||||
|
# A quick guide to configuring OwnTone:
|
||||||
|
#
|
||||||
|
# For regular use, the most important setting to configure is "directories",
|
||||||
|
# which should be the location of your media. Whatever user you have set as
|
||||||
|
# "uid" must have read access to this location. If the location is a network
|
||||||
|
# mount, please see the README.
|
||||||
|
#
|
||||||
|
# In all likelihood, that's all you need to do!
|
||||||
|
|
||||||
|
general {
|
||||||
|
# Username
|
||||||
|
# Make sure the user has read access to the library directories you set
|
||||||
|
# below, and full access to the databases, log and local audio
|
||||||
|
uid = "abc"
|
||||||
|
|
||||||
|
# Database location
|
||||||
|
db_path = "/config/dbase_and_logs/songs3.db"
|
||||||
|
|
||||||
|
# Database backup location
|
||||||
|
# Uncomment and specify a full path to enable abilty to use REST endpoint
|
||||||
|
# to initiate backup of songs3.db
|
||||||
|
#db_backup_path = "/var/cache/owntone/songs3.bak"
|
||||||
|
|
||||||
|
# Log file and level
|
||||||
|
# Available levels: fatal, log, warning, info, debug, spam
|
||||||
|
logfile = "/config/dbase_and_logs/owntone.log"
|
||||||
|
loglevel = log
|
||||||
|
|
||||||
|
# Admin password for the web interface
|
||||||
|
# Note that access to the web interface from computers in
|
||||||
|
# "trusted_network" (see below) does not require password
|
||||||
|
#admin_password = ""
|
||||||
|
|
||||||
|
# Websocket port for the web interface.
|
||||||
|
websocket_port = 3688
|
||||||
|
|
||||||
|
# Websocket interface to bind listener to (e.g. "eth0"). Default is
|
||||||
|
# disabled, which means listen on all interfaces.
|
||||||
|
#websocket_interface = ""
|
||||||
|
|
||||||
|
# Sets who is allowed to connect without authorisation. This applies to
|
||||||
|
# client types like Remotes, DAAP clients (iTunes) and to the web
|
||||||
|
# interface. Options are "any", "localhost" or the prefix to one or
|
||||||
|
# more ipv4/6 networks. The default is { "localhost", "192.168", "fd" }
|
||||||
|
trusted_networks = { "localhost", "192.168.21", "10.102.47", "fd" }
|
||||||
|
|
||||||
|
# Enable/disable IPv6
|
||||||
|
ipv6 = no
|
||||||
|
|
||||||
|
# Set this if you want the server to bind to a specific IP address. Can
|
||||||
|
# be ipv6 or ipv4. Default (commented out or "::") is to listen on all
|
||||||
|
# IP addresses.
|
||||||
|
#bind_address = "::"
|
||||||
|
|
||||||
|
# Location of cache database
|
||||||
|
cache_path = "/config/dbase_and_logs/cache.db"
|
||||||
|
|
||||||
|
# DAAP requests that take longer than this threshold (in msec) get their
|
||||||
|
# replies cached for next time. Set to 0 to disable caching.
|
||||||
|
#cache_daap_threshold = 1000
|
||||||
|
|
||||||
|
# When starting playback, autoselect speaker (if none of the previously
|
||||||
|
# selected speakers/outputs are available)
|
||||||
|
#speaker_autoselect = no
|
||||||
|
|
||||||
|
# Most modern systems have a high-resolution clock, but if you are on an
|
||||||
|
# unusual platform and experience audio drop-outs, you can try changing
|
||||||
|
# this option
|
||||||
|
#high_resolution_clock = yes
|
||||||
|
}
|
||||||
|
|
||||||
|
# Library configuration
|
||||||
|
library {
|
||||||
|
# Name of the library as displayed by the clients (%h: hostname). If you
|
||||||
|
# change the name after pairing with Remote you may have to re-pair.
|
||||||
|
name = "audio.sudo.is"
|
||||||
|
|
||||||
|
# TCP port to listen on. Default port is 3689 (daap)
|
||||||
|
port = 3689
|
||||||
|
|
||||||
|
# Password for the library. Optional.
|
||||||
|
#password = ""
|
||||||
|
|
||||||
|
# Directories to index
|
||||||
|
directories = { "/music" }
|
||||||
|
|
||||||
|
# Follow symlinks. Default: true.
|
||||||
|
#follow_symlinks = true
|
||||||
|
|
||||||
|
# Directories containing podcasts
|
||||||
|
# For each directory that is indexed the path is matched against these
|
||||||
|
# names. If there is a match all items in the directory are marked as
|
||||||
|
# podcasts. Eg. if you index /music, and your podcasts are in
|
||||||
|
# /music/Podcasts, you can set this to "/Podcasts".
|
||||||
|
# (changing this setting only takes effect after rescan, see the README)
|
||||||
|
podcasts = { "/podcasts" }
|
||||||
|
|
||||||
|
# Directories containing audiobooks
|
||||||
|
# For each directory that is indexed the path is matched against these
|
||||||
|
# names. If there is a match all items in the directory are marked as
|
||||||
|
# audiobooks.
|
||||||
|
# (changing this setting only takes effect after rescan, see the README)
|
||||||
|
audiobooks = { "/audiobooks" }
|
||||||
|
|
||||||
|
# Directories containing compilations (eg soundtracks)
|
||||||
|
# For each directory that is indexed the path is matched against these
|
||||||
|
# names. If there is a match all items in the directory are marked as
|
||||||
|
# compilations.
|
||||||
|
# (changing this setting only takes effect after rescan, see the README)
|
||||||
|
compilations = { "/compilations" }
|
||||||
|
|
||||||
|
# Compilations usually have many artists, and sometimes no album artist.
|
||||||
|
# If you dont want every artist to be listed in artist views, you can
|
||||||
|
# set a single name which will be used for all compilation tracks
|
||||||
|
# without an album artist, and for all tracks in the compilation
|
||||||
|
# directories.
|
||||||
|
# (changing this setting only takes effect after rescan, see the README)
|
||||||
|
compilation_artist = "Various Artists"
|
||||||
|
|
||||||
|
# If your album and artist lists are cluttered, you can choose to hide
|
||||||
|
# albums and artists with only one track. The tracks will still be
|
||||||
|
# visible in other lists, e.g. songs and playlists. This setting
|
||||||
|
# currently only works in some remotes.
|
||||||
|
#hide_singles = false
|
||||||
|
|
||||||
|
# Internet streams in your playlists will by default be shown in the
|
||||||
|
# "Radio" library, like iTunes does. However, some clients (like
|
||||||
|
# TunesRemote+) wont show the "Radio" library. If you would also like
|
||||||
|
# to have them shown like normal playlists, you can enable this option.
|
||||||
|
radio_playlists = true
|
||||||
|
|
||||||
|
# These are the default playlists. If you want them to have other names,
|
||||||
|
# you can set it here.
|
||||||
|
#name_library = "Library"
|
||||||
|
#name_music = "Music"
|
||||||
|
#name_movies = "Movies"
|
||||||
|
#name_tvshows = "TV Shows"
|
||||||
|
#name_podcasts = "Podcasts"
|
||||||
|
#name_audiobooks = "Audiobooks"
|
||||||
|
#name_radio = "Radio"
|
||||||
|
|
||||||
|
# Artwork file names (without file type extension)
|
||||||
|
# OwnTone will look for jpg and png files with these base names
|
||||||
|
artwork_basenames = { "artwork", "cover", "Folder" }
|
||||||
|
|
||||||
|
# Enable searching for artwork corresponding to each individual media
|
||||||
|
# file instead of only looking for album artwork. This is disabled by
|
||||||
|
# default to reduce cache size.
|
||||||
|
#artwork_individual = false
|
||||||
|
|
||||||
|
# File types the scanner should ignore
|
||||||
|
# Non-audio files will never be added to the database, but here you
|
||||||
|
# can prevent the scanner from even probing them. This might improve
|
||||||
|
# scan time. By default .db, .ini, .db-journal, .pdf and .metadata are
|
||||||
|
# ignored.
|
||||||
|
#filetypes_ignore = { ".db", ".ini", ".db-journal", ".pdf", ".metadata" }
|
||||||
|
|
||||||
|
# File paths the scanner should ignore
|
||||||
|
# If you want to exclude files on a more advanced basis you can enter
|
||||||
|
# one or more POSIX regular expressions, and any file with a matching
|
||||||
|
# path will be ignored.
|
||||||
|
#filepath_ignore = { "myregex" }
|
||||||
|
|
||||||
|
# Disable startup file scanning
|
||||||
|
# When OwnTone starts it will do an initial file scan of your
|
||||||
|
# library (and then watch it for changes). If you are sure your library
|
||||||
|
# never changes while OwnTone is not running, you can disable the
|
||||||
|
# initial file scan and save some system ressources. Disabling this scan
|
||||||
|
# may lead to OwnTones database coming out of sync with the
|
||||||
|
# library. If that happens read the instructions in the README on how
|
||||||
|
# to trigger a rescan.
|
||||||
|
#filescan_disable = false
|
||||||
|
|
||||||
|
# Should metadata from m3u playlists, e.g. artist and title in EXTINF,
|
||||||
|
# override the metadata we get from radio streams?
|
||||||
|
#m3u_overrides = false
|
||||||
|
|
||||||
|
# Should iTunes metadata override ours?
|
||||||
|
itunes_overrides = true
|
||||||
|
|
||||||
|
# Should we import the content of iTunes smart playlists?
|
||||||
|
#itunes_smartpl = false
|
||||||
|
|
||||||
|
# Decoding options for DAAP clients
|
||||||
|
# Since iTunes has native support for mpeg, mp4a, mp4v, alac and wav,
|
||||||
|
# such files will be sent as they are. Any other formats will be decoded
|
||||||
|
# to raw wav. If OwnTone detects a non-iTunes DAAP client, it is
|
||||||
|
# assumed to only support mpeg and wav, other formats will be decoded.
|
||||||
|
# Here you can change when to decode. Note that these settings have no
|
||||||
|
# effect on AirPlay.
|
||||||
|
# Formats: mp4a, mp4v, mpeg, alac, flac, mpc, ogg, wma, wmal, wmav, aif, wav
|
||||||
|
# Formats that should never be decoded
|
||||||
|
#no_decode = { "format", "format" }
|
||||||
|
# Formats that should always be decoded
|
||||||
|
#force_decode = { "format", "format" }
|
||||||
|
|
||||||
|
# Watch named pipes in the library for data and autostart playback when
|
||||||
|
# there is data to be read. To exclude specific pipes from watching,
|
||||||
|
# consider using the above _ignore options.
|
||||||
|
#pipe_autostart = true
|
||||||
|
|
||||||
|
# Enable automatic rating updates
|
||||||
|
# If enabled, rating is automatically updated after a song has either been
|
||||||
|
# played or skipped (only skipping to the next song is taken into account).
|
||||||
|
# The calculation is taken from the beets plugin "mpdstats" (see
|
||||||
|
# https://beets.readthedocs.io/en/latest/plugins/mpdstats.html).
|
||||||
|
# It consist of calculating a stable rating based only on the play- and
|
||||||
|
# skipcount and a rolling rating based on the current rating and the action
|
||||||
|
# (played or skipped). Both results are combined with a mix-factor of 0.75:
|
||||||
|
# new rating = 0.75 * stable rating + 0.25 * rolling rating)
|
||||||
|
#rating_updates = false
|
||||||
|
|
||||||
|
# Allows creating, deleting and modifying m3u playlists in the library directories.
|
||||||
|
# Only supported by the player web interface and some mpd clients
|
||||||
|
# Defaults to being disabled.
|
||||||
|
allow_modifying_stored_playlists = true
|
||||||
|
|
||||||
|
# A directory in one of the library directories that will be used as the default
|
||||||
|
# playlist directory. OwnTone creates new playlists in this directory if only
|
||||||
|
# a playlist name is provided (requires "allow_modify_stored_playlists" set to true).
|
||||||
|
default_playlist_directory = "/music/playlists"
|
||||||
|
|
||||||
|
# By default OwnTone will - like iTunes - clear the playqueue if
|
||||||
|
# playback stops. Setting clear_queue_on_stop_disable to true will keep
|
||||||
|
# the playlist like MPD does. Note that some dacp clients do not show
|
||||||
|
# the playqueue if playback is stopped.
|
||||||
|
#clear_queue_on_stop_disable = false
|
||||||
|
}
|
||||||
|
|
||||||
|
# Local audio output
|
||||||
|
audio {
|
||||||
|
# Name - used in the speaker list in Remote
|
||||||
|
nickname = "Computer"
|
||||||
|
|
||||||
|
# Type of the output (alsa, pulseaudio, dummy or disabled)
|
||||||
|
#type = "alsa"
|
||||||
|
|
||||||
|
# For pulseaudio output, an optional server hostname or IP can be
|
||||||
|
# specified (e.g. "localhost"). If not set, connection is made via local
|
||||||
|
# socket.
|
||||||
|
#server = ""
|
||||||
|
|
||||||
|
# Audio PCM device name for local audio output - ALSA only
|
||||||
|
#card = "default"
|
||||||
|
|
||||||
|
# Mixer channel to use for volume control - ALSA only
|
||||||
|
# If not set, PCM will be used if available, otherwise Master.
|
||||||
|
#mixer = ""
|
||||||
|
|
||||||
|
# Mixer device to use for volume control - ALSA only
|
||||||
|
# If not set, the value for "card" will be used.
|
||||||
|
#mixer_device = ""
|
||||||
|
|
||||||
|
# Enable or disable audio resampling to keep local audio in sync with
|
||||||
|
# e.g. Airplay. This feature relies on accurate ALSA measurements of
|
||||||
|
# delay, and some devices dont provide that. If that is the case you
|
||||||
|
# are better off disabling the feature.
|
||||||
|
#sync_disable = false
|
||||||
|
|
||||||
|
# Here you can adjust when local audio is started relative to other
|
||||||
|
# speakers, e.g. Airplay. Negative values correspond to moving local
|
||||||
|
# audio ahead, positive correspond to delaying it. The unit is
|
||||||
|
# milliseconds. The offset must be between -1000 and 1000 (+/- 1 sec).
|
||||||
|
#offset_ms = 0
|
||||||
|
|
||||||
|
# To calculate what and if resampling is required, local audio delay is
|
||||||
|
# measured each second. After a period the collected measurements are
|
||||||
|
# used to estimate drift and latency, which determines if corrections
|
||||||
|
# are required. This setting sets the length of that period in seconds.
|
||||||
|
#adjust_period_seconds = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
# ALSA device settings
|
||||||
|
# If you have multiple ALSA devices you can configure them individually via
|
||||||
|
# sections like the below. Make sure to set the "card name" correctly. See the
|
||||||
|
# README about ALSA for details. Note that these settings will override the ALSA
|
||||||
|
# settings in the "audio" section above.
|
||||||
|
#alsa "card name" {
|
||||||
|
# Name used in the speaker list. If not set, the card name will be used.
|
||||||
|
#nickname = "Computer"
|
||||||
|
|
||||||
|
# Mixer channel to use for volume control
|
||||||
|
# If not set, PCM will be used if available, otherwise Master
|
||||||
|
#mixer = ""
|
||||||
|
|
||||||
|
# Mixer device to use for volume control
|
||||||
|
# If not set, the card name will be used
|
||||||
|
#mixer_device = ""
|
||||||
|
# }
|
||||||
|
|
||||||
|
# Pipe output
|
||||||
|
# Allows OwnTone to output audio data to a named pipe
|
||||||
|
#fifo {
|
||||||
|
#nickname = "fifo"
|
||||||
|
#path = "/path/to/fifo"
|
||||||
|
# }
|
||||||
|
|
||||||
|
# AirPlay settings common to all devices
|
||||||
|
#airplay_shared {
|
||||||
|
# UDP ports used when airplay devices make connections back to
|
||||||
|
# OwnTone (choosing specific ports may be helpful when running
|
||||||
|
# OwnTone behind a firewall)
|
||||||
|
# control_port = 0
|
||||||
|
# timing_port = 0
|
||||||
|
# }
|
||||||
|
|
||||||
|
# AirPlay per device settings
|
||||||
|
# (make sure you get the capitalization of the device name right)
|
||||||
|
#airplay "My AirPlay device" {
|
||||||
|
# OwnTone's volume goes to 11! If that's more than you can handle
|
||||||
|
# you can set a lower value here
|
||||||
|
#max_volume = 11
|
||||||
|
|
||||||
|
# Enable this option to exclude a particular AirPlay device from the
|
||||||
|
# speaker list
|
||||||
|
#exclude = false
|
||||||
|
|
||||||
|
# Enable this option to keep a particular AirPlay device in the speaker
|
||||||
|
# list and thus ignore mdns notifications about it no longer being
|
||||||
|
# present. The speaker will remain until restart of OwnTone.
|
||||||
|
#permanent = false
|
||||||
|
|
||||||
|
# Some devices spuriously disconnect during playback, and based on the
|
||||||
|
# device type OwnTone may attempt to reconnect. Setting this option
|
||||||
|
# overrides this so reconnecting is either always enabled or disabled.
|
||||||
|
#reconnect = false
|
||||||
|
|
||||||
|
# AirPlay password
|
||||||
|
#password = "s1kr3t"
|
||||||
|
|
||||||
|
# Disable AirPlay 1 (RAOP)
|
||||||
|
#raop_disable = false
|
||||||
|
|
||||||
|
# Name used in the speaker list, overrides name from the device
|
||||||
|
#nickname = "My speaker name"
|
||||||
|
# }
|
||||||
|
|
||||||
|
# Chromecast settings
|
||||||
|
# (make sure you get the capitalization of the device name right)
|
||||||
|
#chromecast "My Chromecast device" {
|
||||||
|
# OwnTone's volume goes to 11! If that's more than you can handle
|
||||||
|
# you can set a lower value here
|
||||||
|
#max_volume = 11
|
||||||
|
|
||||||
|
# Enable this option to exclude a particular device from the speaker
|
||||||
|
# list
|
||||||
|
#exclude = false
|
||||||
|
|
||||||
|
# Name used in the speaker list, overrides name from the device
|
||||||
|
#nickname = "My speaker name"
|
||||||
|
# }
|
||||||
|
|
||||||
|
# Spotify settings (only have effect if Spotify enabled - see README/INSTALL)
|
||||||
|
spotify {
|
||||||
|
# Set preferred bitrate for music streaming
|
||||||
|
# 0: No preference (default), 1: 96kbps, 2: 160kbps, 3: 320kbps
|
||||||
|
#bitrate = 0
|
||||||
|
|
||||||
|
# Your Spotify playlists will by default be put in a "Spotify" playlist
|
||||||
|
# folder. If you would rather have them together with your other
|
||||||
|
# playlists you can set this option to true.
|
||||||
|
#base_playlist_disable = false
|
||||||
|
|
||||||
|
# Spotify playlists usually have many artist, and if you dont want
|
||||||
|
# every artist to be listed when artist browsing in Remote, you can set
|
||||||
|
# the artist_override flag to true. This will use the compilation_artist
|
||||||
|
# as album artist for Spotify items.
|
||||||
|
#artist_override = false
|
||||||
|
|
||||||
|
# Similar to the different artists in Spotify playlists, the playlist
|
||||||
|
# items belong to different albums, and if you do not want every album
|
||||||
|
# to be listed when browsing in Remote, you can set the album_override
|
||||||
|
# flag to true. This will use the playlist name as album name for
|
||||||
|
# Spotify items. Notice that if an item is in more than one playlist,
|
||||||
|
# it will only appear in one album when browsing (in which album is
|
||||||
|
# random).
|
||||||
|
#album_override = false
|
||||||
|
}
|
||||||
|
|
||||||
|
# RCP/Roku Soundbridge output settings
|
||||||
|
# (make sure you get the capitalization of the device name right)
|
||||||
|
#rcp "My SoundBridge device" {
|
||||||
|
# Enable this option to exclude a particular device from the speaker
|
||||||
|
# list
|
||||||
|
#exclude = false
|
||||||
|
|
||||||
|
# A Roku/SoundBridge can power up in 2 modes: (default) reconnect to the
|
||||||
|
# previously used library (ie OwnTone) or in a 'cleared library' mode.
|
||||||
|
# The Roku power up behaviour is affected by how OwnTone disconnects
|
||||||
|
# from the Roku device.
|
||||||
|
#
|
||||||
|
# Set to false to maintain default Roku power on behaviour
|
||||||
|
#clear_on_close = false
|
||||||
|
# }
|
||||||
|
|
||||||
|
|
||||||
|
# MPD configuration (only have effect if MPD enabled - see README/INSTALL)
|
||||||
|
mpd {
|
||||||
|
# TCP port to listen on for MPD client requests.
|
||||||
|
# Default port is 6600, set to 0 to disable MPD support.
|
||||||
|
#port = 6600
|
||||||
|
|
||||||
|
# HTTP port to listen for artwork requests (only supported by some MPD
|
||||||
|
# clients and will need additional configuration in the MPD client to
|
||||||
|
# work). Set to 0 to disable serving artwork over http.
|
||||||
|
#http_port = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# SQLite configuration (allows to modify the operation of the SQLite databases)
|
||||||
|
# Make sure to read the SQLite documentation for the corresponding PRAGMA
|
||||||
|
# statements as changing them from the defaults may increase the possibility of
|
||||||
|
# database corruptions! By default the SQLite default values are used.
|
||||||
|
sqlite {
|
||||||
|
# Cache size in number of db pages for the library database
|
||||||
|
# (SQLite default page size is 1024 bytes and cache size is 2000 pages)
|
||||||
|
#pragma_cache_size_library = 2000
|
||||||
|
|
||||||
|
# Cache size in number of db pages for the daap cache database
|
||||||
|
# (SQLite default page size is 1024 bytes and cache size is 2000 pages)
|
||||||
|
#pragma_cache_size_cache = 2000
|
||||||
|
|
||||||
|
# Sets the journal mode for the database
|
||||||
|
# DELETE (default), TRUNCATE, PERSIST, MEMORY, WAL, OFF
|
||||||
|
#pragma_journal_mode = DELETE
|
||||||
|
|
||||||
|
# Change the setting of the "synchronous" flag
|
||||||
|
# 0: OFF, 1: NORMAL, 2: FULL (default)
|
||||||
|
#pragma_synchronous = 2
|
||||||
|
|
||||||
|
# Number of bytes set aside for memory-mapped I/O for the library database
|
||||||
|
# (requires sqlite 3.7.17 or later)
|
||||||
|
# 0: disables mmap (default), any other value > 0: number of bytes for mmap
|
||||||
|
#pragma_mmap_size_library = 0
|
||||||
|
|
||||||
|
# Number of bytes set aside for memory-mapped I/O for the cache database
|
||||||
|
# (requires sqlite 3.7.17 or later)
|
||||||
|
# 0: disables mmap (default), any other value > 0: number of bytes for mmap
|
||||||
|
#pragma_mmap_size_cache = 0
|
||||||
|
|
||||||
|
# Should the database be vacuumed on startup? (increases startup time,
|
||||||
|
# but may reduce database size). Default is yes.
|
||||||
|
#vacuum = yes
|
||||||
|
}
|
||||||
|
|
||||||
|
# Streaming audio settings for remote connections (ie stream.mp3)
|
||||||
|
streaming {
|
||||||
|
# Sample rate, typically 44100 or 48000
|
||||||
|
#sample_rate = 44100
|
||||||
|
|
||||||
|
# Set the MP3 streaming bit rate (in kbps), valid options: 64 / 96 / 128 / 192 / 320
|
||||||
|
bit_rate = 320
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: reload nginx
|
||||||
|
service:
|
||||||
|
name: nginx
|
||||||
|
state: reloaded
|
||||||
|
|
||||||
|
- name: restart owntone container
|
||||||
|
docker_container:
|
||||||
|
name: hass
|
||||||
|
state: started
|
||||||
|
restart: true
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- import_tasks: owntone.yml
|
||||||
|
tags: owntone
|
|
@ -0,0 +1,145 @@
|
||||||
|
---
|
||||||
ben marked this conversation as resolved
ben
commented
currently here currently here
ben
commented
owntone works reasonably well (and is building out of ben/builds/owntone), but its not done. not in this pr though. owntone works reasonably well (and is building out of ben/builds/owntone), but its not done. not in this pr though.
|
|||||||
|
|
||||||
|
- name: create dir structure
|
||||||
|
file:
|
||||||
|
state: directory
|
||||||
|
path: "{{ owntone_path }}/{{ item.name }}"
|
||||||
|
mode: "{{ item.mode | default('0770') }}"
|
||||||
|
owner: "{{ owntone_user.uid }}"
|
||||||
|
group: "{{ owntone_group.gid }}"
|
||||||
|
tags:
|
||||||
|
- owntone-dirs
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }}"
|
||||||
|
with_items:
|
||||||
|
- name: ''
|
||||||
|
- name: config
|
||||||
|
- name: log
|
||||||
|
- name: audio
|
||||||
|
- name: audio/local_music
|
||||||
|
- name: audio/playlists
|
||||||
|
- name: audio/compilations
|
||||||
|
- name: audio/pipes
|
||||||
|
#- name: audio/lidarr
|
||||||
|
#- name: audio/audiobooks
|
||||||
|
#- name: audio/podcasts
|
||||||
|
|
||||||
|
- name: create input pipe
|
||||||
|
command:
|
||||||
|
cmd: mkfifo "{{ owntone_path }}/audio/pipes/{{ item }}"
|
||||||
|
creates: "{{ owntone_path }}/audio/pipes/{{ item }}"
|
||||||
|
become_user: "{{ owntone_user.username }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item }}"
|
||||||
|
with_items:
|
||||||
|
- shairport-output.fifo
|
||||||
|
- shairport-metadata.fifo
|
||||||
|
tags:
|
||||||
|
- input.fifo
|
||||||
|
|
||||||
|
- name: install certs
|
||||||
|
copy:
|
||||||
|
src: "/usr/local/etc/letsencrypt/live/{{ item }}"
|
||||||
|
dest: "/usr/local/etc/certs/"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0755
|
||||||
|
tags:
|
||||||
|
- letsencrypt-certs
|
||||||
|
notify: reload nginx
|
||||||
|
vars:
|
||||||
|
prediff_cmd: echo
|
||||||
|
with_items:
|
||||||
|
- "{{ domain }}"
|
||||||
|
|
||||||
|
- name: template nginx vhost
|
||||||
|
template:
|
||||||
|
src: 01-owntone.conf.j2
|
||||||
|
dest: /etc/nginx/sites-enabled/01-owntone.conf
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0644
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- owntone-nginx
|
||||||
|
notify: reload nginx
|
||||||
|
|
||||||
|
- name: template config file
|
||||||
|
template:
|
||||||
|
src: owntone.conf.j2
|
||||||
|
dest: "{{ owntone_path }}/config/owntone.conf"
|
||||||
|
owner: "{{ owntone_user.uid }}"
|
||||||
|
group: "{{ owntone_group.gid }}"
|
||||||
|
mode: 0644
|
||||||
|
notify:
|
||||||
|
- restart owntone container
|
||||||
|
tags:
|
||||||
|
- owntone.conf
|
||||||
|
|
||||||
|
- name: cron file
|
||||||
|
template:
|
||||||
|
src: owntone-cron.j2
|
||||||
|
dest: /etc/cron.d/owntone
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0600
|
||||||
|
tags:
|
||||||
|
- cron
|
||||||
|
- owntone-cron
|
||||||
|
|
||||||
|
- name: install utils for tagging
|
||||||
|
apt:
|
||||||
|
name:
|
||||||
|
|
||||||
|
- id3v2
|
||||||
|
- ffmpeg
|
||||||
|
state: present
|
||||||
|
tags:
|
||||||
|
- packages
|
||||||
|
|
||||||
|
- name: install yt-dlp
|
||||||
|
pip:
|
||||||
|
name: yt-dlp
|
||||||
|
state: latest
|
||||||
|
tags:
|
||||||
|
- packages
|
||||||
|
- pip-packages
|
||||||
|
- yt-dlp
|
||||||
|
|
||||||
|
- name: fuse allow other
|
||||||
|
lineinfile:
|
||||||
|
path: /etc/fuse.conf
|
||||||
|
line: user_allow_other
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: start owntone container
|
||||||
|
docker_container:
|
||||||
|
name: owntone
|
||||||
|
#image: lscr.io/linuxserver/daapd:latest
|
||||||
|
image: git.sudo.is/ben/owntone:latest
|
||||||
|
detach: true
|
||||||
|
pull: true
|
||||||
|
restart_policy: "unless-stopped"
|
||||||
|
state: started
|
||||||
|
container_default_behavior: compatibility
|
||||||
|
networks_cli_compatible: false
|
||||||
|
# user:
|
||||||
|
network_mode: host
|
||||||
|
env:
|
||||||
|
VITE_OWNTONE_URL: "https://{{ owntone_url }}"
|
||||||
|
mounts:
|
||||||
|
- type: bind
|
||||||
|
source: "{{ owntone_path }}/config/owntone.conf"
|
||||||
|
target: "/etc/owntone.conf"
|
||||||
|
- type: bind
|
||||||
|
source: "{{ owntone_path }}/config"
|
||||||
|
target: "/config"
|
||||||
|
- type: bind
|
||||||
|
source: "{{ owntone_path }}/log"
|
||||||
|
target: "/log"
|
||||||
|
- type: bind
|
||||||
|
source: "{{ owntone_path }}/audio"
|
||||||
|
target: "/audio"
|
||||||
|
tags:
|
||||||
|
- owntone-container
|
||||||
|
- docker-containers
|
|
@ -0,0 +1,70 @@
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
# listen {{ owntone_port_tcp }};
|
||||||
|
|
||||||
|
{% if inventory_hostname in wg_clients -%}
|
||||||
|
listen {{ wg_clients[inventory_hostname].ip }}:443 ssl http2;
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
include /etc/nginx/authelia_internal.conf;
|
||||||
|
include listen-proxy-protocol.conf;
|
||||||
|
include /etc/nginx/sudo-known.conf;
|
||||||
|
|
||||||
|
server_name {{ owntone_url }};
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access_{{ owntone_url }}.log main;
|
||||||
|
error_log /var/log/nginx/error_{{ owntone_url }}.log warn;
|
||||||
|
|
||||||
|
ssl_certificate /usr/local/etc/certs/{{ domain }}/fullchain.pem;
|
||||||
|
ssl_certificate_key /usr/local/etc/certs/{{ domain }}/privkey.pem;
|
||||||
|
|
||||||
|
# !
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers off;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
sub_filter 'owntone.local:3689' '{{ owntone_url }}';
|
||||||
|
sub_filter 'http%3A%2F%2Fowntone.local%3A3689' 'https%3A%2F%2F{{ owntone_url }}';
|
||||||
|
sub_filter 'http://owntone.local:3689' 'https://{{ owntone_url }}';
|
||||||
|
sub_filter_types '*';
|
||||||
|
sub_filter_once off;
|
||||||
|
|
||||||
|
proxy_pass http://127.0.0.1:{{ owntone_port_tcp }}/;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
server {
|
||||||
|
# only needs to be accessed by players that are being streamed to
|
||||||
|
# maybe need to remove 'http2'
|
||||||
|
listen {{ ansible_default_ipv4.address }}:{{ owntone_port_ws }} ssl http2;
|
||||||
|
|
||||||
|
server_name {{ owntone_url }};
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access_{{ owntone_url }}_{{ owntone_port_ws }}.log main;
|
||||||
|
error_log /var/log/nginx/error_{{ owntone_url }}_{{ owntone_port_ws }}.log warn;
|
||||||
|
|
||||||
|
ssl_certificate /usr/local/etc/certs/{{ domain }}/fullchain.pem;
|
||||||
|
ssl_certificate_key /usr/local/etc/certs/{{ domain }}/privkey.pem;
|
||||||
|
|
||||||
|
# !
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers off;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:{{ owntone_port_ws }}/;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
# {{ ansible_managed }}
|
||||||
|
|
||||||
|
# m h dom mon dow
|
||||||
|
|
||||||
|
*/60 * * * * {{ owntone_user.username }} touch {{ owntone_path }}/audio/local_music/trigger.init-rescan
|
||||||
|
|
||||||
|
#
|
|
@ -0,0 +1,472 @@
|
||||||
|
# A quick guide to configuring OwnTone:
|
||||||
|
#
|
||||||
|
# For regular use, the most important setting to configure is "directories",
|
||||||
|
# which should be the location of your media. Whatever user you have set as
|
||||||
|
# "uid" must have read access to this location. If the location is a network
|
||||||
|
# mount, please see the README.
|
||||||
|
#
|
||||||
|
# In all likelihood, that's all you need to do!
|
||||||
|
|
||||||
|
general {
|
||||||
|
# Username
|
||||||
|
# Make sure the user has read access to the library directories you set
|
||||||
|
# below, and full access to the databases, log and local audio
|
||||||
|
uid = "owntone"
|
||||||
|
|
||||||
|
db_path = "/config/dbase_and_logs/songs3.db"
|
||||||
|
|
||||||
|
# Database backup location
|
||||||
|
# Uncomment and specify a full path to enable abilty to use REST endpoint
|
||||||
|
# to initiate backup of songs3.db
|
||||||
|
#db_backup_path = "/var/cache/owntone/songs3.bak"
|
||||||
|
|
||||||
|
# Log file and level
|
||||||
|
# Available levels: fatal, log, warning, info, debug, spam
|
||||||
|
logfile = "/log/owntone.log"
|
||||||
|
loglevel = log
|
||||||
|
|
||||||
|
# Admin password for the web interface
|
||||||
|
# Note that access to the web interface from computers in
|
||||||
|
# "trusted_network" (see below) does not require password
|
||||||
|
admin_password = "{{ owntone_admin_pass }}"
|
||||||
|
|
||||||
|
# Websocket port for the web interface.
|
||||||
|
websocket_port = {{ owntone_port_ws }}
|
||||||
|
|
||||||
|
# Websocket interface to bind listener to (e.g. "eth0"). Default is
|
||||||
|
# disabled, which means listen on all interfaces.
|
||||||
|
websocket_interface = "{{ owntone_interface }}"
|
||||||
|
|
||||||
|
# Sets who is allowed to connect without authorisation. This applies to
|
||||||
|
# client types like Remotes, DAAP clients (iTunes) and to the web
|
||||||
|
# interface. Options are "any", "localhost" or the prefix to one or
|
||||||
|
# more ipv4/6 networks. The default is { "localhost", "192.168", "fd" }
|
||||||
|
{% set s21 = s21_cidr.split(".")[:3] | join(".") -%}
|
||||||
|
trusted_networks = { "localhost", "{{ s21 }}", "fd" }
|
||||||
|
|
||||||
|
# Enable/disable IPv6
|
||||||
|
ipv6 = no
|
||||||
|
|
||||||
|
# Set this if you want the server to bind to a specific IP address. Can
|
||||||
|
# be ipv6 or ipv4. Default (commented out or "::") is to listen on all
|
||||||
|
# IP addresses.
|
||||||
|
#bind_address = "{{ owntone_interface }}"
|
||||||
|
|
||||||
|
# Location of cache database
|
||||||
|
cache_path = "/config/dbase_and_logs/cache.db"
|
||||||
|
|
||||||
|
# DAAP requests that take longer than this threshold (in msec) get their
|
||||||
|
# replies cached for next time. Set to 0 to disable caching.
|
||||||
|
#cache_daap_threshold = 1000
|
||||||
|
|
||||||
|
# When starting playback, autoselect speaker (if none of the previously
|
||||||
|
# selected speakers/outputs are available)
|
||||||
|
#speaker_autoselect = no
|
||||||
|
|
||||||
|
# Most modern systems have a high-resolution clock, but if you are on an
|
||||||
|
# unusual platform and experience audio drop-outs, you can try changing
|
||||||
|
# this option
|
||||||
|
#high_resolution_clock = yes
|
||||||
|
}
|
||||||
|
|
||||||
|
# Library configuration
|
||||||
|
library {
|
||||||
|
# Name of the library as displayed by the clients (%h: hostname). If you
|
||||||
|
# change the name after pairing with Remote you may have to re-pair.
|
||||||
|
name = "{{ owntone_url }}"
|
||||||
|
|
||||||
|
# TCP port to listen on. Default port is 3689 (daap)
|
||||||
|
port = {{ owntone_port_tcp }}
|
||||||
|
|
||||||
|
# Password for the library. Optional.
|
||||||
|
#password = "{{ owntone_library_pass }}"
|
||||||
|
|
||||||
|
# Directories to index
|
||||||
|
directories = { "/audio" }
|
||||||
|
|
||||||
|
# Follow symlinks. Default: true.
|
||||||
|
#follow_symlinks = true
|
||||||
|
|
||||||
|
# Directories containing podcasts
|
||||||
|
# For each directory that is indexed the path is matched against these
|
||||||
|
# names. If there is a match all items in the directory are marked as
|
||||||
|
# podcasts. Eg. if you index /music, and your podcasts are in
|
||||||
|
# /music/Podcasts, you can set this to "/Podcasts".
|
||||||
|
# (changing this setting only takes effect after rescan, see the README)
|
||||||
|
podcasts = { "/podcasts" }
|
||||||
|
|
||||||
|
# Directories containing audiobooks
|
||||||
|
# For each directory that is indexed the path is matched against these
|
||||||
|
# names. If there is a match all items in the directory are marked as
|
||||||
|
# audiobooks.
|
||||||
|
# (changing this setting only takes effect after rescan, see the README)
|
||||||
|
audiobooks = { "/audiobooks" }
|
||||||
|
|
||||||
|
# Directories containing compilations (eg soundtracks)
|
||||||
|
# For each directory that is indexed the path is matched against these
|
||||||
|
# names. If there is a match all items in the directory are marked as
|
||||||
|
# compilations.
|
||||||
|
# (changing this setting only takes effect after rescan, see the README)
|
||||||
|
compilations = { "/compilations" }
|
||||||
|
|
||||||
|
# Compilations usually have many artists, and sometimes no album artist.
|
||||||
|
# If you dont want every artist to be listed in artist views, you can
|
||||||
|
# set a single name which will be used for all compilation tracks
|
||||||
|
# without an album artist, and for all tracks in the compilation
|
||||||
|
# directories.
|
||||||
|
# (changing this setting only takes effect after rescan, see the README)
|
||||||
|
compilation_artist = "Various Artists"
|
||||||
|
|
||||||
|
# If your album and artist lists are cluttered, you can choose to hide
|
||||||
|
# albums and artists with only one track. The tracks will still be
|
||||||
|
# visible in other lists, e.g. songs and playlists. This setting
|
||||||
|
# currently only works in some remotes.
|
||||||
|
#hide_singles = false
|
||||||
|
|
||||||
|
# Internet streams in your playlists will by default be shown in the
|
||||||
|
# "Radio" library, like iTunes does. However, some clients (like
|
||||||
|
# TunesRemote+) wont show the "Radio" library. If you would also like
|
||||||
|
# to have them shown like normal playlists, you can enable this option.
|
||||||
|
radio_playlists = false
|
||||||
|
|
||||||
|
# These are the default playlists. If you want them to have other names,
|
||||||
|
# you can set it here.
|
||||||
|
#name_library = "Library"
|
||||||
|
#name_music = "Music"
|
||||||
|
#name_movies = "Movies"
|
||||||
|
#name_tvshows = "TV Shows"
|
||||||
|
#name_podcasts = "Podcasts"
|
||||||
|
#name_audiobooks = "Audiobooks"
|
||||||
|
#name_radio = "Radio"
|
||||||
|
|
||||||
|
# Artwork file names (without file type extension)
|
||||||
|
# OwnTone will look for jpg and png files with these base names
|
||||||
|
artwork_basenames = { "artwork", "cover", "Folder" }
|
||||||
|
|
||||||
|
# Enable searching for artwork corresponding to each individual media
|
||||||
|
# file instead of only looking for album artwork. This is disabled by
|
||||||
|
# default to reduce cache size.
|
||||||
|
artwork_individual = true
|
||||||
|
|
||||||
|
# File types the scanner should ignore
|
||||||
|
# Non-audio files will never be added to the database, but here you
|
||||||
|
# can prevent the scanner from even probing them. This might improve
|
||||||
|
# scan time. By default .db, .ini, .db-journal, .pdf and .metadata are
|
||||||
|
# ignored.
|
||||||
|
#filetypes_ignore = { ".db", ".ini", ".db-journal", ".pdf", ".metadata" }
|
||||||
|
|
||||||
|
# File paths the scanner should ignore
|
||||||
|
# If you want to exclude files on a more advanced basis you can enter
|
||||||
|
# one or more POSIX regular expressions, and any file with a matching
|
||||||
|
# path will be ignored.
|
||||||
|
#filepath_ignore = { "myregex" }
|
||||||
|
|
||||||
|
# Disable startup file scanning
|
||||||
|
# When OwnTone starts it will do an initial file scan of your
|
||||||
|
# library (and then watch it for changes). If you are sure your library
|
||||||
|
# never changes while OwnTone is not running, you can disable the
|
||||||
|
# initial file scan and save some system ressources. Disabling this scan
|
||||||
|
# may lead to OwnTones database coming out of sync with the
|
||||||
|
# library. If that happens read the instructions in the README on how
|
||||||
|
# to trigger a rescan.
|
||||||
|
#filescan_disable = false
|
||||||
|
|
||||||
|
# Should metadata from m3u playlists, e.g. artist and title in EXTINF,
|
||||||
|
# override the metadata we get from radio streams?
|
||||||
|
#m3u_overrides = false
|
||||||
|
|
||||||
|
# Should iTunes metadata override ours?
|
||||||
|
itunes_overrides = {{ owntone_itunes_metadata_override | default(false) }}
|
||||||
|
|
||||||
|
# Should we import the content of iTunes smart playlists?
|
||||||
|
#itunes_smartpl = false
|
||||||
|
|
||||||
|
# Decoding options for DAAP clients
|
||||||
|
# Since iTunes has native support for mpeg, mp4a, mp4v, alac and wav,
|
||||||
|
# such files will be sent as they are. Any other formats will be decoded
|
||||||
|
# to raw wav. If OwnTone detects a non-iTunes DAAP client, it is
|
||||||
|
# assumed to only support mpeg and wav, other formats will be decoded.
|
||||||
|
# Here you can change when to decode. Note that these settings have no
|
||||||
|
# effect on AirPlay.
|
||||||
|
# Formats: mp4a, mp4v, mpeg, alac, flac, mpc, ogg, wma, wmal, wmav, aif, wav
|
||||||
|
# Formats that should never be decoded
|
||||||
|
#no_decode = { "format", "format" }
|
||||||
|
# Formats that should always be decoded
|
||||||
|
#force_decode = { "format", "format" }
|
||||||
|
|
||||||
|
# Watch named pipes in the library for data and autostart playback when
|
||||||
|
# there is data to be read. To exclude specific pipes from watching,
|
||||||
|
# consider using the above _ignore options.
|
||||||
|
pipe_autostart = true
|
||||||
|
|
||||||
|
# Enable automatic rating updates
|
||||||
|
# If enabled, rating is automatically updated after a song has either been
|
||||||
|
# played or skipped (only skipping to the next song is taken into account).
|
||||||
|
# The calculation is taken from the beets plugin "mpdstats" (see
|
||||||
|
# https://beets.readthedocs.io/en/latest/plugins/mpdstats.html).
|
||||||
|
# It consist of calculating a stable rating based only on the play- and
|
||||||
|
# skipcount and a rolling rating based on the current rating and the action
|
||||||
|
# (played or skipped). Both results are combined with a mix-factor of 0.75:
|
||||||
|
# new rating = 0.75 * stable rating + 0.25 * rolling rating)
|
||||||
|
#rating_updates = false
|
||||||
|
|
||||||
|
# Allows creating, deleting and modifying m3u playlists in the library directories.
|
||||||
|
# Only supported by the player web interface and some mpd clients
|
||||||
|
# Defaults to being disabled.
|
||||||
|
allow_modifying_stored_playlists = true
|
||||||
|
|
||||||
|
# A directory in one of the library directories that will be used as the default
|
||||||
|
# playlist directory. OwnTone creates new playlists in this directory if only
|
||||||
|
# a playlist name is provided (requires "allow_modify_stored_playlists" set to true).
|
||||||
|
default_playlist_directory = "/audio/playlists"
|
||||||
|
|
||||||
|
# By default OwnTone will - like iTunes - clear the playqueue if
|
||||||
|
# playback stops. Setting clear_queue_on_stop_disable to true will keep
|
||||||
|
# the playlist like MPD does. Note that some dacp clients do not show
|
||||||
|
# the playqueue if playback is stopped.
|
||||||
|
clear_queue_on_stop_disable = true
|
||||||
|
}
|
||||||
|
|
||||||
|
# Local audio output
|
||||||
|
audio {
|
||||||
|
# Name - used in the speaker list in Remote
|
||||||
|
nickname = "Computer"
|
||||||
|
|
||||||
|
# Type of the output (alsa, pulseaudio, dummy or disabled)
|
||||||
|
type = "disabled"
|
||||||
|
|
||||||
|
# For pulseaudio output, an optional server hostname or IP can be
|
||||||
|
# specified (e.g. "localhost"). If not set, connection is made via local
|
||||||
|
# socket.
|
||||||
|
#server = ""
|
||||||
|
|
||||||
|
# Audio PCM device name for local audio output - ALSA only
|
||||||
|
#card = "default"
|
||||||
|
|
||||||
|
# Mixer channel to use for volume control - ALSA only
|
||||||
|
# If not set, PCM will be used if available, otherwise Master.
|
||||||
|
#mixer = ""
|
||||||
|
|
||||||
|
# Mixer device to use for volume control - ALSA only
|
||||||
|
# If not set, the value for "card" will be used.
|
||||||
|
#mixer_device = ""
|
||||||
|
|
||||||
|
# Enable or disable audio resampling to keep local audio in sync with
|
||||||
|
# e.g. Airplay. This feature relies on accurate ALSA measurements of
|
||||||
|
# delay, and some devices dont provide that. If that is the case you
|
||||||
|
# are better off disabling the feature.
|
||||||
|
#sync_disable = false
|
||||||
|
|
||||||
|
# Here you can adjust when local audio is started relative to other
|
||||||
|
# speakers, e.g. Airplay. Negative values correspond to moving local
|
||||||
|
# audio ahead, positive correspond to delaying it. The unit is
|
||||||
|
# milliseconds. The offset must be between -1000 and 1000 (+/- 1 sec).
|
||||||
|
#offset_ms = 0
|
||||||
|
|
||||||
|
# To calculate what and if resampling is required, local audio delay is
|
||||||
|
# measured each second. After a period the collected measurements are
|
||||||
|
# used to estimate drift and latency, which determines if corrections
|
||||||
|
# are required. This setting sets the length of that period in seconds.
|
||||||
|
#adjust_period_seconds = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
# ALSA device settings
|
||||||
|
# If you have multiple ALSA devices you can configure them individually via
|
||||||
|
# sections like the below. Make sure to set the "card name" correctly. See the
|
||||||
|
# README about ALSA for details. Note that these settings will override the ALSA
|
||||||
|
# settings in the "audio" section above.
|
||||||
|
#alsa "card name" {
|
||||||
|
# Name used in the speaker list. If not set, the card name will be used.
|
||||||
|
#nickname = "Computer"
|
||||||
|
|
||||||
|
# Mixer channel to use for volume control
|
||||||
|
# If not set, PCM will be used if available, otherwise Master
|
||||||
|
#mixer = ""
|
||||||
|
|
||||||
|
# Mixer device to use for volume control
|
||||||
|
# If not set, the card name will be used
|
||||||
|
#mixer_device = ""
|
||||||
|
# }
|
||||||
|
|
||||||
|
# Pipe output
|
||||||
|
# Allows OwnTone to output audio data to a named pipe
|
||||||
|
fifo {
|
||||||
|
nickname = "fifo"
|
||||||
|
path = "/audio/output.fifo"
|
||||||
|
}
|
||||||
|
|
||||||
|
# AirPlay settings common to all devices
|
||||||
|
#airplay_shared {
|
||||||
|
# UDP ports used when airplay devices make connections back to
|
||||||
|
# OwnTone (choosing specific ports may be helpful when running
|
||||||
|
# OwnTone behind a firewall)
|
||||||
|
# control_port = 0
|
||||||
|
# timing_port = 0
|
||||||
|
# }
|
||||||
|
|
||||||
|
# AirPlay per device settings
|
||||||
|
# (make sure you get the capitalization of the device name right)
|
||||||
|
#airplay "My AirPlay device" {
|
||||||
|
# OwnTone's volume goes to 11! If that's more than you can handle
|
||||||
|
# you can set a lower value here
|
||||||
|
#max_volume = 11
|
||||||
|
|
||||||
|
# Enable this option to exclude a particular AirPlay device from the
|
||||||
|
# speaker list
|
||||||
|
#exclude = false
|
||||||
|
|
||||||
|
# Enable this option to keep a particular AirPlay device in the speaker
|
||||||
|
# list and thus ignore mdns notifications about it no longer being
|
||||||
|
# present. The speaker will remain until restart of OwnTone.
|
||||||
|
#permanent = false
|
||||||
|
|
||||||
|
# Some devices spuriously disconnect during playback, and based on the
|
||||||
|
# device type OwnTone may attempt to reconnect. Setting this option
|
||||||
|
# overrides this so reconnecting is either always enabled or disabled.
|
||||||
|
#reconnect = false
|
||||||
|
|
||||||
|
# AirPlay password
|
||||||
|
#password = "s1kr3t"
|
||||||
|
|
||||||
|
# Disable AirPlay 1 (RAOP)
|
||||||
|
#raop_disable = false
|
||||||
|
|
||||||
|
# Name used in the speaker list, overrides name from the device
|
||||||
|
#nickname = "My speaker name"
|
||||||
|
# }
|
||||||
|
|
||||||
|
{% for item in owntone_airplay -%}
|
||||||
|
{% if item.exclude|default(false) -%}
|
||||||
|
# Excluded AirPlay device: {{ item.name }}
|
||||||
|
{% endif %}
|
||||||
|
airplay "{{ item.name }}" {
|
||||||
|
{% if 'nickname' in item -%}
|
||||||
|
nickname = "{{ item.nickname }}"
|
||||||
|
{% endif -%}
|
||||||
|
{% if 'password' in item -%}
|
||||||
|
password = "{{ item.password }}"
|
||||||
|
{% endif -%}
|
||||||
|
{% if 'max_volume' in item -%}
|
||||||
|
max_volume = {{ item.max_volume }}
|
||||||
|
{% endif -%}
|
||||||
|
exclude = {{ item.exclude|default(false) | lower }}
|
||||||
|
permanent = {{ item.permanent|default(false) | lower }}
|
||||||
|
reconnect = {{ item.reconnect|default(false) | lower }}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
# Chromecast settings
|
||||||
|
# (make sure you get the capitalization of the device name right)
|
||||||
|
#chromecast "My Chromecast device" {
|
||||||
|
# OwnTone's volume goes to 11! If that's more than you can handle
|
||||||
|
# you can set a lower value here
|
||||||
|
#max_volume = 11
|
||||||
|
|
||||||
|
# Enable this option to exclude a particular device from the speaker
|
||||||
|
# list
|
||||||
|
#exclude = false
|
||||||
|
|
||||||
|
# Name used in the speaker list, overrides name from the device
|
||||||
|
#nickname = "My speaker name"
|
||||||
|
# }
|
||||||
|
|
||||||
|
# Spotify settings (only have effect if Spotify enabled - see README/INSTALL)
|
||||||
|
spotify {
|
||||||
|
# Set preferred bitrate for music streaming
|
||||||
|
# 0: No preference (default), 1: 96kbps, 2: 160kbps, 3: 320kbps
|
||||||
|
bitrate = 3
|
||||||
|
|
||||||
|
# Your Spotify playlists will by default be put in a "Spotify" playlist
|
||||||
|
# folder. If you would rather have them together with your other
|
||||||
|
# playlists you can set this option to true.
|
||||||
|
base_playlist_disable = true
|
||||||
|
|
||||||
|
# Spotify playlists usually have many artist, and if you dont want
|
||||||
|
# every artist to be listed when artist browsing in Remote, you can set
|
||||||
|
# the artist_override flag to true. This will use the compilation_artist
|
||||||
|
# as album artist for Spotify items.
|
||||||
|
artist_override = true
|
||||||
|
|
||||||
|
# Similar to the different artists in Spotify playlists, the playlist
|
||||||
|
# items belong to different albums, and if you do not want every album
|
||||||
|
# to be listed when browsing in Remote, you can set the album_override
|
||||||
|
# flag to true. This will use the playlist name as album name for
|
||||||
|
# Spotify items. Notice that if an item is in more than one playlist,
|
||||||
|
# it will only appear in one album when browsing (in which album is
|
||||||
|
# random).
|
||||||
|
album_override = true
|
||||||
|
}
|
||||||
|
|
||||||
|
# RCP/Roku Soundbridge output settings
|
||||||
|
# (make sure you get the capitalization of the device name right)
|
||||||
|
#rcp "My SoundBridge device" {
|
||||||
|
# Enable this option to exclude a particular device from the speaker
|
||||||
|
# list
|
||||||
|
#exclude = false
|
||||||
|
|
||||||
|
# A Roku/SoundBridge can power up in 2 modes: (default) reconnect to the
|
||||||
|
# previously used library (ie OwnTone) or in a 'cleared library' mode.
|
||||||
|
# The Roku power up behaviour is affected by how OwnTone disconnects
|
||||||
|
# from the Roku device.
|
||||||
|
#
|
||||||
|
# Set to false to maintain default Roku power on behaviour
|
||||||
|
#clear_on_close = false
|
||||||
|
# }
|
||||||
|
|
||||||
|
|
||||||
|
# MPD configuration (only have effect if MPD enabled - see README/INSTALL)
|
||||||
|
mpd {
|
||||||
|
# TCP port to listen on for MPD client requests.
|
||||||
|
# Default port is 6600, set to 0 to disable MPD support.
|
||||||
|
port = {{ owntone_port_mpd|default('6600') }}
|
||||||
|
|
||||||
|
# HTTP port to listen for artwork requests (only supported by some MPD
|
||||||
|
# clients and will need additional configuration in the MPD client to
|
||||||
|
# work). Set to 0 to disable serving artwork over http.
|
||||||
|
#http_port = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# SQLite configuration (allows to modify the operation of the SQLite databases)
|
||||||
|
# Make sure to read the SQLite documentation for the corresponding PRAGMA
|
||||||
|
# statements as changing them from the defaults may increase the possibility of
|
||||||
|
# database corruptions! By default the SQLite default values are used.
|
||||||
|
sqlite {
|
||||||
|
# Cache size in number of db pages for the library database
|
||||||
|
# (SQLite default page size is 1024 bytes and cache size is 2000 pages)
|
||||||
|
#pragma_cache_size_library = 2000
|
||||||
|
|
||||||
|
# Cache size in number of db pages for the daap cache database
|
||||||
|
# (SQLite default page size is 1024 bytes and cache size is 2000 pages)
|
||||||
|
#pragma_cache_size_cache = 2000
|
||||||
|
|
||||||
|
# Sets the journal mode for the database
|
||||||
|
# DELETE (default), TRUNCATE, PERSIST, MEMORY, WAL, OFF
|
||||||
|
#pragma_journal_mode = DELETE
|
||||||
|
|
||||||
|
# Change the setting of the "synchronous" flag
|
||||||
|
# 0: OFF, 1: NORMAL, 2: FULL (default)
|
||||||
|
#pragma_synchronous = 2
|
||||||
|
|
||||||
|
# Number of bytes set aside for memory-mapped I/O for the library database
|
||||||
|
# (requires sqlite 3.7.17 or later)
|
||||||
|
# 0: disables mmap (default), any other value > 0: number of bytes for mmap
|
||||||
|
#pragma_mmap_size_library = 0
|
||||||
|
|
||||||
|
# Number of bytes set aside for memory-mapped I/O for the cache database
|
||||||
|
# (requires sqlite 3.7.17 or later)
|
||||||
|
# 0: disables mmap (default), any other value > 0: number of bytes for mmap
|
||||||
|
#pragma_mmap_size_cache = 0
|
||||||
|
|
||||||
|
# Should the database be vacuumed on startup? (increases startup time,
|
||||||
|
# but may reduce database size). Default is yes.
|
||||||
|
#vacuum = yes
|
||||||
|
}
|
||||||
|
|
||||||
|
# Streaming audio settings for remote connections (ie stream.mp3)
|
||||||
|
streaming {
|
||||||
|
# Sample rate, typically 44100 or 48000
|
||||||
|
#sample_rate = 44100
|
||||||
|
|
||||||
|
# Set the MP3 streaming bit rate (in kbps), valid options: 64 / 96 / 128 / 192 / 320
|
||||||
|
bit_rate = 320
|
||||||
|
}
|
|
@ -1,7 +1 @@
|
||||||
---
|
---
|
||||||
|
|
||||||
dependencies:
|
|
||||||
- mariadb
|
|
||||||
- zflux
|
|
||||||
- sudoisbot
|
|
||||||
- hass
|
|
||||||
|
|
|
@ -56,6 +56,191 @@
|
||||||
when: dht_builder|default(False)
|
when: dht_builder|default(False)
|
||||||
tags: dht
|
tags: dht
|
||||||
|
|
||||||
|
# https://bluedot.readthedocs.io/en/latest/pairpipi.html#using-the-command-line
|
||||||
|
#
|
||||||
|
# $ sudo bluetoothctl
|
||||||
|
# [bluetooth]# discoverable on
|
||||||
|
# Changing discoverable on succeeded
|
||||||
|
# [bluetooth]# pairable on
|
||||||
|
# Changing pairable on succeeded
|
||||||
|
# [bluetooth]# agent on
|
||||||
|
# Agent is already registered
|
||||||
|
# [bluetooth]# default-agent
|
||||||
|
# Default agent request successful
|
||||||
|
# [bluetooth]# scan on
|
||||||
|
# [bluetooth]# pair EA:26:7D:4A:ED:E4
|
||||||
|
# 0a-11e5-a837-0800200c9a66
|
||||||
|
# Vendor specific
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char000d/desc000f
|
||||||
|
# 00002901-0000-1000-8000-00805f9b34fb
|
||||||
|
# Characteristic User Description
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char000d/desc0010
|
||||||
|
# 00002902-0000-1000-8000-00805f9b34fb
|
||||||
|
# Client Characteristic Configuration
|
||||||
|
# [NEW] Characteristic
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char0011
|
||||||
|
# e6807d23-b90a-11e5-a837-0800200c9a66
|
||||||
|
# Vendor specific
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char0011/desc0013
|
||||||
|
# 00002901-0000-1000-8000-00805f9b34fb
|
||||||
|
# Characteristic User Description
|
||||||
|
# [NEW] Characteristic
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char0014
|
||||||
|
# e6807d24-b90a-11e5-a837-0800200c9a66
|
||||||
|
# Vendor specific
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char0014/desc0016
|
||||||
|
# 00002901-0000-1000-8000-00805f9b34fb
|
||||||
|
# Characteristic User Description
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char0014/desc0017
|
||||||
|
# 00002902-0000-1000-8000-00805f9b34fb
|
||||||
|
# Client Characteristic Configuration
|
||||||
|
# [NEW] Characteristic
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char0018
|
||||||
|
# e6807d25-b90a-11e5-a837-0800200c9a66
|
||||||
|
# Vendor specific
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char0018/desc001a
|
||||||
|
# 00002901-0000-1000-8000-00805f9b34fb
|
||||||
|
# Characteristic User Description
|
||||||
|
# [NEW] Characteristic
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char001b
|
||||||
|
# e6807d26-b90a-11e5-a837-0800200c9a66
|
||||||
|
# Vendor specific
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char001b/desc001d
|
||||||
|
# 00002901-0000-1000-8000-00805f9b34fb
|
||||||
|
# Characteristic User Description
|
||||||
|
# [NEW] Characteristic
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char001e
|
||||||
|
# e6807d27-b90a-11e5-a837-0800200c9a66
|
||||||
|
# Vendor specific
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char001e/desc0020
|
||||||
|
# 00002901-0000-1000-8000-00805f9b34fb
|
||||||
|
# Characteristic User Description
|
||||||
|
# [NEW] Characteristic
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char0021
|
||||||
|
# e6807e20-b90a-11e5-a837-0800200c9a66
|
||||||
|
# Vendor specific
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char0021/desc0023
|
||||||
|
# 00002901-0000-1000-8000-00805f9b34fb
|
||||||
|
# Characteristic User Description
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char0021/desc0024
|
||||||
|
# 00002902-0000-1000-8000-00805f9b34fb
|
||||||
|
# Client Characteristic Configuration
|
||||||
|
# [NEW] Characteristic
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char0025
|
||||||
|
# e6807e21-b90a-11e5-a837-0800200c9a66
|
||||||
|
# Vendor specific
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char0025/desc0027
|
||||||
|
# 00002901-0000-1000-8000-00805f9b34fb
|
||||||
|
# Characteristic User Description
|
||||||
|
# [NEW] Characteristic
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char0028
|
||||||
|
# e6807e24-b90a-11e5-a837-0800200c9a66
|
||||||
|
# Vendor specific
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char0028/desc002a
|
||||||
|
# 00002901-0000-1000-8000-00805f9b34fb
|
||||||
|
# Characteristic User Description
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char0028/desc002b
|
||||||
|
# 00002902-0000-1000-8000-00805f9b34fb
|
||||||
|
# Client Characteristic Configuration
|
||||||
|
# [NEW] Characteristic
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char002c
|
||||||
|
# e6807e25-b90a-11e5-a837-0800200c9a66
|
||||||
|
# Vendor specific
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0009/char002c/desc002e
|
||||||
|
# 00002901-0000-1000-8000-00805f9b34fb
|
||||||
|
# Characteristic User Description
|
||||||
|
# [NEW] Primary Service
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service002f
|
||||||
|
# 0000181a-0000-1000-8000-00805f9b34fb
|
||||||
|
# Environmental Sensing
|
||||||
|
# [NEW] Characteristic
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service002f/char0030
|
||||||
|
# 00002a6e-0000-1000-8000-00805f9b34fb
|
||||||
|
# Temperature
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service002f/char0030/desc0032
|
||||||
|
# 00002901-0000-1000-8000-00805f9b34fb
|
||||||
|
# Characteristic User Description
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service002f/char0030/desc0033
|
||||||
|
# 00002902-0000-1000-8000-00805f9b34fb
|
||||||
|
# Client Characteristic Configuration
|
||||||
|
# [NEW] Characteristic
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service002f/char0034
|
||||||
|
# 00002a6f-0000-1000-8000-00805f9b34fb
|
||||||
|
# Humidity
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service002f/char0034/desc0036
|
||||||
|
# 00002901-0000-1000-8000-00805f9b34fb
|
||||||
|
# Characteristic User Description
|
||||||
|
# [NEW] Descriptor
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service002f/char0034/desc0037
|
||||||
|
# 00002902-0000-1000-8000-00805f9b34fb
|
||||||
|
# Client Characteristic Configuration
|
||||||
|
# [NEW] Primary Service
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0038
|
||||||
|
# 0000180a-0000-1000-8000-00805f9b34fb
|
||||||
|
# Device Information
|
||||||
|
# [NEW] Characteristic
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0038/char0039
|
||||||
|
# 00002a29-0000-1000-8000-00805f9b34fb
|
||||||
|
# Manufacturer Name String
|
||||||
|
# [NEW] Characteristic
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0038/char003b
|
||||||
|
# 00002a24-0000-1000-8000-00805f9b34fb
|
||||||
|
# Model Number String
|
||||||
|
# [NEW] Characteristic
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0038/char003d
|
||||||
|
# 00002a25-0000-1000-8000-00805f9b34fb
|
||||||
|
# Serial Number String
|
||||||
|
# [NEW] Characteristic
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0038/char003f
|
||||||
|
# 00002a27-0000-1000-8000-00805f9b34fb
|
||||||
|
# Hardware Revision String
|
||||||
|
# [NEW] Characteristic
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0038/char0041
|
||||||
|
# 00002a26-0000-1000-8000-00805f9b34fb
|
||||||
|
# Firmware Revision String
|
||||||
|
# [NEW] Characteristic
|
||||||
|
# /org/bluez/hci0/dev_EA_26_7D_4A_ED_E4/service0038/char0043
|
||||||
|
# 00002a28-0000-1000-8000-00805f9b34fb
|
||||||
|
# Software Revision String
|
||||||
|
# [CHG] Device EA:26:7D:4A:ED:E4 UUIDs: 00001800-0000-1000-8000-00805f9b34fb
|
||||||
|
# [CHG] Device EA:26:7D:4A:ED:E4 UUIDs: 00001801-0000-1000-8000-00805f9b34fb
|
||||||
|
# [CHG] Device EA:26:7D:4A:ED:E4 UUIDs: 0000180a-0000-1000-8000-00805f9b34fb
|
||||||
|
# [CHG] Device EA:26:7D:4A:ED:E4 UUIDs: 0000181a-0000-1000-8000-00805f9b34fb
|
||||||
|
# [CHG] Device EA:26:7D:4A:ED:E4 UUIDs: e6807d20-b90a-11e5-a837-0800200c9a66
|
||||||
|
# [CHG] Device EA:26:7D:4A:ED:E4 ServicesResolved: yes
|
||||||
|
# [CHG] Device EA:26:7D:4A:ED:E4 Appearance: 0x03c0
|
||||||
|
# [CHG] Device EA:26:7D:4A:ED:E4 Paired: yes
|
||||||
|
# Pairing successful
|
||||||
|
# [Beddit 2564]# quit
|
||||||
|
- name: set up bluetooth
|
||||||
|
apt:
|
||||||
|
name:
|
||||||
|
- pi-bluetooth
|
||||||
|
- bluez
|
||||||
|
- libgirepository1.0-dev
|
||||||
|
# - bluez-utils
|
||||||
|
# - bluetooth
|
||||||
|
# - blueman
|
||||||
|
when: bluetooth_enabled | default(false)
|
||||||
|
tags: bluetooth
|
||||||
|
|
||||||
- name: install fpm with gem
|
- name: install fpm with gem
|
||||||
gem:
|
gem:
|
||||||
name: fpm
|
name: fpm
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- mariadb
|
||||||
|
- zflux
|
|
@ -14,7 +14,7 @@
|
||||||
vars:
|
vars:
|
||||||
prediff_cmd: echo
|
prediff_cmd: echo
|
||||||
with_items:
|
with_items:
|
||||||
- "{{ unifi_url }}"
|
- "{{ domain }}"
|
||||||
|
|
||||||
- name: template nginx vhost
|
- name: template nginx vhost
|
||||||
template:
|
template:
|
||||||
|
@ -61,10 +61,13 @@
|
||||||
# v6.5.55
|
# v6.5.55
|
||||||
# v6.0.45
|
# v6.0.45
|
||||||
# v5.14.23
|
# v5.14.23
|
||||||
|
#
|
||||||
|
# updated: v5.14.23 -> stable-5 -> stable-6 -> latest (v7)
|
||||||
- name: start docker container
|
- name: start docker container
|
||||||
docker_container:
|
docker_container:
|
||||||
name: "unifi"
|
name: "unifi"
|
||||||
image: "jacobalberty/unifi:v5.14.23"
|
#image: "jacobalberty/unifi:v5.14.23"
|
||||||
|
image: jacobalberty/unifi:latest
|
||||||
ben
commented
v5 was better v5 was better
|
|||||||
auto_remove: false
|
auto_remove: false
|
||||||
detach: true
|
detach: true
|
||||||
restart_policy: "unless-stopped"
|
restart_policy: "unless-stopped"
|
||||||
|
@ -86,8 +89,9 @@
|
||||||
- "8080:8080/tcp" # Device/ controller comm.
|
- "8080:8080/tcp" # Device/ controller comm.
|
||||||
- "127.0.0.1:8443:8443/tcp" # Controller GUI/API as seen in a web browser
|
- "127.0.0.1:8443:8443/tcp" # Controller GUI/API as seen in a web browser
|
||||||
- "10001:10001/udp" # AP discovery
|
- "10001:10001/udp" # AP discovery
|
||||||
dns_servers:
|
tags:
|
||||||
- "{{ ansible_docker0.ipv4.address }}"
|
- unifi-container
|
||||||
|
- docker-containers
|
||||||
|
|
||||||
|
|
||||||
- name: wait for controller to be responsive
|
- name: wait for controller to be responsive
|
||||||
|
|
|
@ -15,6 +15,15 @@ server {
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location /inform {
|
||||||
|
proxy_pass http://localhost:8080;
|
||||||
|
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
proxy_pass https://localhost:8443/;
|
proxy_pass https://localhost:8443/;
|
||||||
|
|
||||||
|
@ -32,8 +41,8 @@ server {
|
||||||
|
|
||||||
ssl_session_timeout 5m;
|
ssl_session_timeout 5m;
|
||||||
|
|
||||||
ssl_certificate /usr/local/etc/certs/{{ unifi_url }}/fullchain.pem;
|
ssl_certificate /usr/local/etc/certs/{{ domain }}/fullchain.pem;
|
||||||
ssl_certificate_key /usr/local/etc/certs/{{ unifi_url }}/privkey.pem;
|
ssl_certificate_key /usr/local/etc/certs/{{ domain }}/privkey.pem;
|
||||||
|
|
||||||
add_header Referrer-Policy "no-referrer" always;
|
add_header Referrer-Policy "no-referrer" always;
|
||||||
add_header X-Content-Type-Options "nosniff" always;
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
|
|
@ -1,8 +1,26 @@
|
||||||
|
server {
|
||||||
|
server_name {%- for d in server_names %} {{ d }}{% endfor %};
|
||||||
|
|
||||||
|
{% if inventory_hostname in wg_clients -%}
|
||||||
|
listen {{ wg_clients[inventory_hostname].ip }}:443 ssl http2;
|
||||||
|
{% endif -%}
|
||||||
|
listen 443 ssl http2;
|
||||||
|
|
||||||
|
include listen-proxy-protocol.conf;
|
||||||
|
|
||||||
|
ssl_certificate /usr/local/etc/certs/www.{{ domain }}/fullchain.pem;
|
||||||
|
ssl_certificate_key /usr/local/etc/certs/www.{{ domain }}/privkey.pem;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 301 https://www.$http_host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access_{{ domain }}.log main;
|
||||||
|
error_log /var/log/nginx/error_{{ domain }}.log warn;
|
||||||
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
server_name {%- for d in server_names %} www.{{ d }} {{ d }}{% endfor %};
|
server_name {%- for d in server_names %} www.{{ d }}{% endfor %};
|
||||||
|
|
||||||
{% if inventory_hostname in wg_clients -%}
|
{% if inventory_hostname in wg_clients -%}
|
||||||
listen {{ wg_clients[inventory_hostname].ip }}:443 ssl http2;
|
listen {{ wg_clients[inventory_hostname].ip }}:443 ssl http2;
|
||||||
|
|
Loading…
Reference in New Issue
.