Compare commits
33 Commits
7c70221723
...
8c225bbe06
| Author | SHA1 | Date | |
|---|---|---|---|
| 8c225bbe06 | |||
| 831a1b50a4 | |||
| 0cb199c403 | |||
| a2ed74093a | |||
| b3f1ff69b1 | |||
| a973bc8d75 | |||
| 5d853cbb8f | |||
| 804cb1bfaf | |||
| c8f19ed918 | |||
| 1b5a5e2c1d | |||
| 9bd23467f0 | |||
| 6fcc345a26 | |||
| 340eeb5433 | |||
| edca1e47dc | |||
| ca0271ba44 | |||
| 331df52f0b | |||
| 3557fe3f2b | |||
| 5763df90f8 | |||
| 9b1d01115b | |||
| 2443a75871 | |||
| ddda28be44 | |||
| 9c66b7f665 | |||
| 07e3c2797e | |||
| 85a26db46b | |||
| dae2470e67 | |||
| 3d1675528b | |||
| c49e4db304 | |||
| f043606466 | |||
| 37b75ecf81 | |||
| bb72eaec10 | |||
| ab9763ec49 | |||
| f79c106437 | |||
| 5642424697 |
7
.ansible-lint
Normal file
7
.ansible-lint
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
exclude_paths:
|
||||||
|
# A verbatim copy of the app repo's tippen-curriculum.yml. It is content the game
|
||||||
|
# reads, not ansible YAML, and reformatting it here to satisfy a line-length rule
|
||||||
|
# would make this copy diverge from the file it is copied from. Its schema is checked
|
||||||
|
# by the backend at startup, which is a stronger check than anything lint does.
|
||||||
|
- roles/pi_musicmouse/files/tippen-curriculum.yml
|
||||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,8 +1,5 @@
|
|||||||
ve_*
|
|
||||||
/server/scripts/docker-images/tagspace/tagspaces
|
|
||||||
/server/scripts/docker-images/tagspace/*.zip
|
|
||||||
*.img
|
*.img
|
||||||
/music
|
|
||||||
__pycache__
|
__pycache__
|
||||||
/roles/pi-squeezeserver/backup
|
/roles/pi_squeezeserver/backup
|
||||||
|
.ansible/
|
||||||
venv*
|
venv*
|
||||||
80
README.md
Normal file
80
README.md
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
# ansible
|
||||||
|
|
||||||
|
Personal Ansible setup for provisioning and maintaining a fleet of Raspberry
|
||||||
|
Pis (audio players, sensors, music mouse, etc.) plus one home server.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
- `inventory.yml` — hosts and group vars (Pis under `iot`, plus `server`).
|
||||||
|
`group_vars/` and `host_vars/` hold vars for the `mediapis` group (the four
|
||||||
|
parallel audio-player Pis) and their host-specific overrides.
|
||||||
|
- `mediapis.yml`, `working.yml`, `server.yml`, `newrpi-provisioning.yml`,
|
||||||
|
`octopisetup.yml` — top-level playbooks. `mediapis.yml` is the canonical
|
||||||
|
playbook for the `mediapis` group (`musicdolphin`, `kitchenpi`,
|
||||||
|
`bedroompi`, `musicmouse`); the others are narrower/ad-hoc runs kept around
|
||||||
|
for specific hosts or one-off tasks.
|
||||||
|
- `roles/` — one role per piece of functionality (audio backends, sensors,
|
||||||
|
bluetooth monitoring, server basics, etc.). Each has a short `README.md`.
|
||||||
|
- `update-packages.yml` — deliberate, fleet-wide package update (see
|
||||||
|
"Keeping packages up to date" below). `update-packages-pinned-example.yml`
|
||||||
|
is a template for pinning or bumping a single package outside that.
|
||||||
|
- `lookup_plugins/keepass.py` — custom lookup plugin that fetches secrets
|
||||||
|
(device passwords, wifi passphrase) from a running KeePassXC instance via
|
||||||
|
its browser-integration protocol, instead of storing them in the repo.
|
||||||
|
- `pis/` — loose config files/scripts used when provisioning Pis by hand.
|
||||||
|
- `scripts/` — standalone helper scripts (Raspbian image creation, a network
|
||||||
|
logger) that aren't Ansible roles.
|
||||||
|
- `archive/` — retired setups kept for reference (not actively maintained).
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
```
|
||||||
|
python3 -m venv venv
|
||||||
|
source venv/bin/activate
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Secrets are pulled from KeePassXC at run time via the `keepass` lookup
|
||||||
|
plugin — see the header of `lookup_plugins/keepass.py` for how to enable
|
||||||
|
Browser Integration in KeePassXC. Freshly-flashed Raspberry Pis are reached
|
||||||
|
first with the OS-default `pi`/`raspberry` credentials (see
|
||||||
|
`roles/pi_standard_setup`), which the role then rotates to a KeePassXC-managed
|
||||||
|
password.
|
||||||
|
|
||||||
|
## Running a playbook
|
||||||
|
|
||||||
|
```
|
||||||
|
ansible-playbook mediapis.yml --limit <host>
|
||||||
|
```
|
||||||
|
|
||||||
|
`ansible.cfg` points Ansible at `inventory.yml` and `roles/` by default, so
|
||||||
|
no extra flags are needed for those.
|
||||||
|
|
||||||
|
## Keeping packages up to date
|
||||||
|
|
||||||
|
Regular playbook runs (`mediapis.yml`, `server.yml`, etc.) use `state: present`
|
||||||
|
for packages, so they only install what's missing — they never upgrade
|
||||||
|
anything as a side effect of an unrelated config change. Two separate,
|
||||||
|
deliberate mechanisms handle upgrades instead:
|
||||||
|
|
||||||
|
**Security patches — automatic.** The `unattended_upgrades` role (applied
|
||||||
|
to every host in `mediapis.yml`/`server.yml`) configures `unattended-upgrades`
|
||||||
|
to install security-origin updates automatically, with a scheduled reboot
|
||||||
|
window (default 03:00, see `roles/unattended_upgrades/defaults/main.yml`)
|
||||||
|
for patches that need one. Not scoped to full dist-upgrades.
|
||||||
|
|
||||||
|
**Everything else — deliberate, ad hoc.**
|
||||||
|
```
|
||||||
|
just update <host_or_group> # e.g. `just update kitchenpi` or `just update`
|
||||||
|
venv/bin/ansible-playbook update-packages.yml --limit <host> --check --diff # dry run first
|
||||||
|
```
|
||||||
|
Defaults to `upgrade: safe` (upgrades in place, never installs/removes
|
||||||
|
packages to resolve dependencies — see the comment header in
|
||||||
|
`update-packages.yml` for the tradeoff against `dist`). There is no cron/
|
||||||
|
schedule wired up for this yet; run it ad hoc when you want the fleet
|
||||||
|
updated, or add a crontab entry yourself (a starting point is documented in
|
||||||
|
`update-packages.yml`'s header).
|
||||||
|
|
||||||
|
To pin a package to an exact version, or deliberately bump one named
|
||||||
|
package to latest outside this schedule, copy the pattern in
|
||||||
|
`update-packages-pinned-example.yml`.
|
||||||
6
ansible.cfg
Normal file
6
ansible.cfg
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[defaults]
|
||||||
|
inventory = inventory.yml
|
||||||
|
roles_path = roles
|
||||||
|
lookup_plugins = lookup_plugins
|
||||||
|
#strategy = free
|
||||||
|
serial = 5
|
||||||
61
full.yml
61
full.yml
@@ -1,61 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
#- hosts: esszimmerradio
|
|
||||||
# roles:
|
|
||||||
# - pi-standard-setup
|
|
||||||
# - pi-squeezelite-custom
|
|
||||||
# - pi-shairport
|
|
||||||
# - pi-lirc
|
|
||||||
# - pi-sispmctl
|
|
||||||
#
|
|
||||||
|
|
||||||
- hosts: musikserverwohnzimmeroben
|
|
||||||
roles:
|
|
||||||
- pi-standard-setup
|
|
||||||
- pi-hifiberry-amp
|
|
||||||
- pi-squeezelite-custom
|
|
||||||
- pi-shairport
|
|
||||||
- pi-irserver
|
|
||||||
#- pi-dhtsensor
|
|
||||||
- pi-squeezeserver
|
|
||||||
|
|
||||||
- hosts: kitchenpi
|
|
||||||
roles:
|
|
||||||
- pi-standard-setup
|
|
||||||
- pi-hifiberry-amp
|
|
||||||
- pi-squeezelite-custom
|
|
||||||
- pi-shairport
|
|
||||||
- pi-lirc
|
|
||||||
- pi-dhtsensor
|
|
||||||
- pi-disable-onboard-bluetooth
|
|
||||||
- bluetooth-monitor
|
|
||||||
|
|
||||||
- hosts: bedroompi
|
|
||||||
roles:
|
|
||||||
- pi-standard-setup
|
|
||||||
- pi-squeezelite-custom
|
|
||||||
- pi-shairport
|
|
||||||
- pi-lirc
|
|
||||||
- pi-dhtsensor
|
|
||||||
- pi-disable-onboard-bluetooth
|
|
||||||
- bluetooth-monitor
|
|
||||||
|
|
||||||
- hosts: musicmouse
|
|
||||||
roles:
|
|
||||||
- pi-standard-setup
|
|
||||||
- pi-hifiberry-amp
|
|
||||||
- pi-musicmouse
|
|
||||||
- pi-squeezelite-custom
|
|
||||||
- pi-shairport
|
|
||||||
- pi-lirc
|
|
||||||
- bluetooth-monitor
|
|
||||||
|
|
||||||
#- hosts: octopi
|
|
||||||
# roles:
|
|
||||||
# - pi-dhtsensor
|
|
||||||
|
|
||||||
#- hosts: newrpi
|
|
||||||
# roles:
|
|
||||||
# - pi-standard-setup
|
|
||||||
# - pi-lirc
|
|
||||||
15
group_vars/mediapis.yml
Normal file
15
group_vars/mediapis.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
mediapi_has_hifiberry_amp: false
|
||||||
|
mediapi_ir_control: lirc
|
||||||
|
mediapi_has_dhtsensor: false
|
||||||
|
mediapi_disable_onboard_bluetooth: false
|
||||||
|
mediapi_install_bluetooth_monitor: false
|
||||||
|
mediapi_install_kidsmusic: false
|
||||||
|
mediapi_has_monitor: false
|
||||||
|
|
||||||
|
# No media pi runs its own Logitech Media Server. Every squeezelite in the fleet is
|
||||||
|
# pointed at pi_squeezelite_squeezeserver (the server, 192.168.178.80) by inventory.yml,
|
||||||
|
# so a server on a pi would have no clients. false here does not mean "skip the role" -
|
||||||
|
# it means "actively remove it", which is how the stray one on musicdolphin goes away
|
||||||
|
# and stays away. See roles/pi_squeezeserver/README.md.
|
||||||
|
mediapi_has_squeezeserver: false
|
||||||
13
host_vars/bedroompi.yml
Normal file
13
host_vars/bedroompi.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
squeezelite_name: BedroomPi
|
||||||
|
pi_shairport_name: BedroomPi
|
||||||
|
alsa_card_name: Codec
|
||||||
|
sensor_room_name_ascii: schlafzimmer
|
||||||
|
sensor_room_name: Schlafzimmer
|
||||||
|
my_bt_monitor_watchdog_seconds: 600
|
||||||
|
my_btmonitor_restart_ble_interface: hci0
|
||||||
|
main_user: root
|
||||||
|
|
||||||
|
mediapi_has_dhtsensor: true
|
||||||
|
mediapi_disable_onboard_bluetooth: true
|
||||||
|
mediapi_install_bluetooth_monitor: true
|
||||||
13
host_vars/kitchenpi.yml
Normal file
13
host_vars/kitchenpi.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
squeezelite_name: KitchenPi
|
||||||
|
pi_shairport_name: KitchenPi
|
||||||
|
alsa_card_name: 0
|
||||||
|
sensor_room_name_ascii: kueche
|
||||||
|
sensor_room_name: Küche
|
||||||
|
hifiberry_overlay: hifiberry-amp
|
||||||
|
main_user: root
|
||||||
|
|
||||||
|
mediapi_has_hifiberry_amp: true
|
||||||
|
mediapi_has_dhtsensor: true
|
||||||
|
mediapi_disable_onboard_bluetooth: true
|
||||||
|
mediapi_install_bluetooth_monitor: true
|
||||||
26
host_vars/musicdolphin.yml
Normal file
26
host_vars/musicdolphin.yml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
squeezelite_name: Wohnzimmer
|
||||||
|
pi_shairport_name: _Oben_Wohnzimmer
|
||||||
|
alsa_card_name: sndrpihifiberry
|
||||||
|
sensor_room_name_ascii: wohnzimmeroben
|
||||||
|
sensor_room_name: WohnzimmerOben
|
||||||
|
hifiberry_overlay: hifiberry-dacplus
|
||||||
|
main_user: root
|
||||||
|
|
||||||
|
mediapi_has_hifiberry_amp: true
|
||||||
|
mediapi_ir_control: irserver
|
||||||
|
mediapi_has_dhtsensor: true
|
||||||
|
|
||||||
|
# Display-only MusicMouse instance: no physical mouse attached, shown on the monitor
|
||||||
|
# via pi_kiosk instead. See roles/pi_musicmouse/files/config-musicdolphin.yml.
|
||||||
|
mediapi_install_kidsmusic: true
|
||||||
|
mediapi_has_monitor: true
|
||||||
|
# Temporarily a debuggable desktop rather than a locked-down kiosk: Openbox root menu,
|
||||||
|
# visible pointer, Firefox in a normal window. Set back to "kiosk" when done.
|
||||||
|
pi_kiosk_mode: debug
|
||||||
|
# ?pi=1 is the front-end's Raspberry Pi profile (web/src/lib/lowPower.ts): the ambient
|
||||||
|
# canvas at a quarter of the pixels and 30fps, the progress bar re-rendering ten times
|
||||||
|
# a second instead of sixty, and no backdrop blur. Drop the parameter in the address
|
||||||
|
# bar to compare against the full-fat version on the same machine.
|
||||||
|
pi_kiosk_url: "http://localhost:8080/?pi=1"
|
||||||
|
musicmouse_version: deploy/musicdolphin
|
||||||
25
host_vars/musicmouse.yml
Normal file
25
host_vars/musicmouse.yml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
squeezelite_name: MusicMouse
|
||||||
|
pi_shairport_name: MusicMouse
|
||||||
|
alsa_card_name: sndrpihifiberry
|
||||||
|
hifiberry_overlay: hifiberry-dacplus
|
||||||
|
sensor_room_name: Kinderzimmer
|
||||||
|
sensor_room_name_ascii: kinderzimmer
|
||||||
|
main_user: root
|
||||||
|
|
||||||
|
mediapi_has_hifiberry_amp: true
|
||||||
|
mediapi_install_bluetooth_monitor: true
|
||||||
|
# The Kinderzimmer device still runs the pre-rearchitecture backend (deploy/musicmouse
|
||||||
|
# == b2c060f): /opt/musicmouse_venv and espmusicmouse/host_driver/main.py, installed by
|
||||||
|
# an older version of this role. The current pi_musicmouse only knows the new
|
||||||
|
# python-backend/ + web/ layout, so it is deliberately off here - a run would
|
||||||
|
# force-check-out incompatible code over a device the kids use every day, and would
|
||||||
|
# fail anyway (that commit has no python-backend/pyproject.toml, no
|
||||||
|
# python-backend/musicmouse.service and no web/ at all).
|
||||||
|
#
|
||||||
|
# deploy/musicmouse stays recorded below as the rollback marker for what is actually
|
||||||
|
# installed. Turning this back on means migrating the device at the same time: move
|
||||||
|
# /media/musicmouse/<figure>/ into Figuren/ and switch to the new config schema -
|
||||||
|
# files/config-musicmouse.yml is already written for that.
|
||||||
|
mediapi_install_kidsmusic: false
|
||||||
|
musicmouse_version: deploy/musicmouse
|
||||||
@@ -1,63 +1,21 @@
|
|||||||
|
---
|
||||||
all:
|
all:
|
||||||
hosts:
|
hosts:
|
||||||
server:
|
server:
|
||||||
ansible_host: home.bauer.tech
|
ansible_host: home.bauer.tech
|
||||||
ansible_port: 22187
|
ansible_port: 22187
|
||||||
server2:
|
server2:
|
||||||
|
|
||||||
children:
|
children:
|
||||||
iot:
|
iot:
|
||||||
hosts:
|
hosts:
|
||||||
octopi:
|
octopi:
|
||||||
sensor_room_name_ascii: prusaprinter
|
sensor_room_name_ascii: prusaprinter
|
||||||
sensor_room_name: prusaprinter
|
sensor_room_name: prusaprinter
|
||||||
dht_pin: 26
|
pi_dhtsensor_dht_pin: 26
|
||||||
main_user: root
|
|
||||||
bedroompi:
|
|
||||||
squeezelite_name: BedroomPi
|
|
||||||
shairport_name: BedroomPi
|
|
||||||
alsa_card_name: Codec
|
|
||||||
sensor_room_name_ascii: schlafzimmer
|
|
||||||
sensor_room_name: Schlafzimmer
|
|
||||||
my_bt_monitor_watchdog_seconds: 600
|
|
||||||
my_btmonitor_restart_ble_interface: hci0
|
|
||||||
main_user: root
|
|
||||||
kitchenpi:
|
|
||||||
squeezelite_name: KitchenPi
|
|
||||||
shairport_name: KitchenPi
|
|
||||||
alsa_card_name: 0
|
|
||||||
sensor_room_name_ascii: kueche
|
|
||||||
sensor_room_name: Küche
|
|
||||||
hifiberry_overlay: hifiberry-amp
|
|
||||||
main_user: root
|
|
||||||
esszimmerradio: # oben, eltern
|
|
||||||
squeezelite_name: Esszimmer
|
|
||||||
shairport_name: _Oben_Esszimmer
|
|
||||||
#alsa_card_name: Device
|
|
||||||
squeezeserver: 192.168.178.100
|
|
||||||
configure_wifi: true
|
|
||||||
alsa_card_name: 1
|
|
||||||
main_user: root
|
|
||||||
musikserverwohnzimmeroben: # oben, eltern
|
|
||||||
squeezelite_name: Wohnzimmer
|
|
||||||
shairport_name: _Oben_Wohnzimmer
|
|
||||||
alsa_card_name: 0
|
|
||||||
squeezeserver: 192.168.178.100
|
|
||||||
sensor_room_name_ascii: wohnzimmeroben
|
|
||||||
sensor_room_name: WohnzimmerOben
|
|
||||||
hifiberry_overlay: hifiberry-dacplus
|
|
||||||
main_user: root
|
|
||||||
musicmouse:
|
|
||||||
squeezelite_name: MusicMouse
|
|
||||||
shairport_name: MusicMouse
|
|
||||||
alsa_card_name: 1
|
|
||||||
hifiberry_overlay: hifiberry-dacplus
|
|
||||||
sensor_room_name: Kinderzimmer
|
|
||||||
sensor_room_name_ascii: kinderzimmer
|
|
||||||
main_user: root
|
main_user: root
|
||||||
newrpi:
|
newrpi:
|
||||||
squeezelite_name: MyTestRaspberry
|
squeezelite_name: MyTestRaspberry
|
||||||
shairport_name: MyTestRaspberry
|
pi_shairport_name: MyTestRaspberry
|
||||||
alsa_card_name: 0
|
alsa_card_name: 0
|
||||||
sensor_room_name_ascii: testraum
|
sensor_room_name_ascii: testraum
|
||||||
sensor_room_name: Test Raum
|
sensor_room_name: Test Raum
|
||||||
@@ -71,14 +29,23 @@ all:
|
|||||||
homeassistant:
|
homeassistant:
|
||||||
sensor_room_name: Anschlussraum
|
sensor_room_name: Anschlussraum
|
||||||
sensor_room_name_ascii: anschlussraum
|
sensor_room_name_ascii: anschlussraum
|
||||||
|
children:
|
||||||
|
mediapis:
|
||||||
|
hosts:
|
||||||
|
musicdolphin:
|
||||||
|
kitchenpi:
|
||||||
|
bedroompi:
|
||||||
|
musicmouse:
|
||||||
vars:
|
vars:
|
||||||
ansible_user: root
|
ansible_user: root
|
||||||
ansible_python_interpreter: /usr/bin/python3
|
ansible_python_interpreter: /usr/bin/python3
|
||||||
squeezeserver: 192.168.178.80
|
ansible_ssh_common_args: "-o ForwardAgent=yes"
|
||||||
|
pi_squeezelite_squeezeserver: 192.168.178.80
|
||||||
router_ip: 192.168.178.1
|
router_ip: 192.168.178.1
|
||||||
home_assistant_url: https://ha.bauer.tech
|
home_assistant_url: https://ha.bauer.tech
|
||||||
home_assistant_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkM2QxYjAwYjkxZjY0MWVhYjA4YmZhMDYwYTg3YjRhNyIsImlhdCI6MTcwNDI3MDU5MSwiZXhwIjoyMDE5NjMwNTkxfQ.dzvejgEQd9hf-Yftzd7NkR5pv76GaLFczeOy-a2pa1o
|
home_assistant_token:
|
||||||
|
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkM2QxYjAwYjkxZjY0MWVhYjA4YmZhMDYwYTg3YjRhNyIsImlhdCI6MTcwNDI3MDU5MSwiZXhwIjoyMDE5NjMwNTkxfQ.dzvejgEQd9hf-Yftzd7NkR5pv76GaLFczeOy-a2pa1o
|
||||||
configure_wifi: false
|
configure_wifi: false
|
||||||
wifi_ssid: BauerWLAN
|
pi_standard_setup_wifi_ssid: BauerWLAN
|
||||||
my_btmonitor_mqtt_username: my_btmonitor
|
my_btmonitor_mqtt_username: my_btmonitor
|
||||||
my_btmonitor_mqtt_password: 8aBIAC14jaKKbla
|
my_btmonitor_mqtt_password: 8aBIAC14jaKKbla
|
||||||
|
|||||||
55
justfile
Normal file
55
justfile
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
venv_bin := "venv/bin"
|
||||||
|
|
||||||
|
# List available commands
|
||||||
|
default:
|
||||||
|
@just --list
|
||||||
|
|
||||||
|
# Create the Python virtualenv used to run ansible
|
||||||
|
venv:
|
||||||
|
python3 -m venv venv
|
||||||
|
{{venv_bin}}/pip install --upgrade pip
|
||||||
|
|
||||||
|
# Install Python deps (requirements.txt) and Galaxy collections (requirements.yml)
|
||||||
|
install:
|
||||||
|
{{venv_bin}}/pip install -r requirements.txt
|
||||||
|
{{venv_bin}}/ansible-galaxy collection install -r requirements.yml < /dev/null
|
||||||
|
|
||||||
|
# Ping all hosts, or a group/host, e.g. `just ping kitchenpi`
|
||||||
|
ping group="all":
|
||||||
|
{{venv_bin}}/ansible {{group}} -m ping
|
||||||
|
|
||||||
|
# Show the resolved inventory as a tree
|
||||||
|
inventory:
|
||||||
|
{{venv_bin}}/ansible-inventory --graph
|
||||||
|
|
||||||
|
# Syntax-check a playbook, e.g. `just syntax mediapis.yml`
|
||||||
|
syntax playbook:
|
||||||
|
{{venv_bin}}/ansible-playbook {{playbook}} --syntax-check
|
||||||
|
|
||||||
|
# Dry-run a playbook against a host/group without making changes
|
||||||
|
check playbook limit="all":
|
||||||
|
{{venv_bin}}/ansible-playbook {{playbook}} --limit {{limit}} --check --diff
|
||||||
|
|
||||||
|
# Run a playbook against a host/group, e.g. `just run mediapis.yml kitchenpi`
|
||||||
|
run playbook limit="all":
|
||||||
|
{{venv_bin}}/ansible-playbook {{playbook}} --limit {{limit}}
|
||||||
|
|
||||||
|
# Run mediapis.yml (pi roles) against one host/group, e.g. `just mediapis kitchenpi`
|
||||||
|
mediapis limit="all":
|
||||||
|
just run mediapis.yml {{limit}}
|
||||||
|
|
||||||
|
# Run server.yml against the server host
|
||||||
|
server:
|
||||||
|
just run server.yml server
|
||||||
|
|
||||||
|
# Run the deliberate fleet package-update playbook, e.g. `just update kitchenpi`
|
||||||
|
update limit="all":
|
||||||
|
just run update-packages.yml {{limit}}
|
||||||
|
|
||||||
|
# List installed Galaxy collections
|
||||||
|
collections:
|
||||||
|
{{venv_bin}}/ansible-galaxy collection list
|
||||||
|
|
||||||
|
# Lint playbooks and roles
|
||||||
|
lint:
|
||||||
|
{{venv_bin}}/ansible-lint
|
||||||
Binary file not shown.
@@ -1,63 +1,191 @@
|
|||||||
# Copy this to ".ansible/plugins/lookup"
|
# Copy this file to ~/.ansible/plugins/lookup/keepass.py
|
||||||
|
#
|
||||||
|
# Prerequisites:
|
||||||
|
# pip install keepassxc-proxy-client
|
||||||
|
#
|
||||||
|
# KeePassXC setup:
|
||||||
|
# Tools > Settings > Browser Integration > Enable browser integration
|
||||||
|
# The plugin will prompt you to approve the association in KeePassXC on first run.
|
||||||
|
# Association credentials are saved to ~/.keepassxc_ansible_assoc (override with
|
||||||
|
# env var KEEPASSXC_ASSOC_FILE).
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# {{ lookup('keepass', 'https://example.com', 'password') }}
|
||||||
|
# {{ lookup('keepass', 'https://example.com', 'username') }}
|
||||||
|
# {{ lookup('keepass', 'https://example.com') }} # defaults to password
|
||||||
|
#
|
||||||
|
# Terms:
|
||||||
|
# terms[0] URL (or title) to search for — matched against KeePassXC entries
|
||||||
|
# terms[1] Attribute to return: username / user / password / pass / passwd
|
||||||
|
# Defaults to 'password' if omitted.
|
||||||
|
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
from ansible.errors import AnsibleError
|
from ansible.errors import AnsibleError
|
||||||
from ansible.plugins.lookup import LookupBase
|
from ansible.plugins.lookup import LookupBase
|
||||||
from keepasshttplib import keepasshttplib, encrypter
|
|
||||||
import requests
|
|
||||||
|
|
||||||
DOCUMENTATION = """
|
DOCUMENTATION = r"""
|
||||||
lookup: keepass
|
lookup: keepass
|
||||||
author: Martin Bauer <bauer_martin@gmx.de>
|
short_description: Fetch credentials from KeePassXC via the browser proxy protocol
|
||||||
version_added: '0.2'
|
|
||||||
short_description: fetch data from KeePass over KeePassHTTP
|
|
||||||
description:
|
description:
|
||||||
- This lookup returns a username or password queried by the URL of the keepass entry
|
- Connects to a running KeePassXC instance over its browser-integration Unix socket
|
||||||
|
(or Windows named pipe) and retrieves credentials for a given URL.
|
||||||
|
- On first use the plugin associates itself with KeePassXC; you will see an
|
||||||
|
approval dialog in KeePassXC. The association is saved to disk so subsequent
|
||||||
|
runs are silent.
|
||||||
options:
|
options:
|
||||||
_terms:
|
_terms:
|
||||||
description:
|
description:
|
||||||
- first is the URL to search for
|
- First term is the URL (or entry title URL) to look up.
|
||||||
- second is a property name of the entry, e.g. username or password
|
- Second term (optional) is the attribute to return.
|
||||||
required: True
|
Accepted values are username, user, password, pass, passwd.
|
||||||
|
Defaults to password.
|
||||||
|
required: true
|
||||||
notes:
|
notes:
|
||||||
- https://github.com/viczem/ansible-keepass
|
- KeePassXC must be running with Browser Integration enabled.
|
||||||
|
- Requires the Python package keepassxc-proxy-client.
|
||||||
example:
|
|
||||||
- "{{ lookup('keepass', 'urlOfEntry', 'password') }}"
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
EXAMPLES = r"""
|
||||||
|
- name: Get password for an entry
|
||||||
|
debug:
|
||||||
|
msg: "{{ lookup('keepass', 'https://example.com') }}"
|
||||||
|
|
||||||
|
- name: Get username for an entry
|
||||||
|
debug:
|
||||||
|
msg: "{{ lookup('keepass', 'https://example.com', 'username') }}"
|
||||||
|
|
||||||
|
- name: Set pi account password from KeePassXC
|
||||||
|
user:
|
||||||
|
name: pi
|
||||||
|
password: "{{ lookup('keepass', 'default_rpi_password') | password_hash('sha512') }}"
|
||||||
|
"""
|
||||||
|
|
||||||
|
ASSOC_FILE_ENV = "KEEPASSXC_ASSOC_FILE"
|
||||||
|
ASSOC_FILE_DEFAULT = os.path.expanduser("~/.keepassxc_ansible_assoc")
|
||||||
|
ASSOC_NAME = "ansible-keepassxc"
|
||||||
|
|
||||||
|
USERNAME_ATTRS = {"username", "user"}
|
||||||
|
PASSWORD_ATTRS = {"password", "pass", "passwd"}
|
||||||
|
|
||||||
|
|
||||||
|
def _get_assoc_file():
|
||||||
|
return os.environ.get(ASSOC_FILE_ENV, ASSOC_FILE_DEFAULT)
|
||||||
|
|
||||||
|
|
||||||
|
def _load_assoc(connection):
|
||||||
|
"""Load a previously saved association from disk into *connection*. Returns True on success."""
|
||||||
|
path = _get_assoc_file()
|
||||||
|
if not os.path.exists(path):
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
with open(path, "r") as fh:
|
||||||
|
data = json.load(fh)
|
||||||
|
connection.load_associate(data["name"], bytes(data["public_key"]))
|
||||||
|
return True
|
||||||
|
except (KeyError, ValueError, OSError):
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _save_assoc(connection):
|
||||||
|
"""Persist the current association to disk."""
|
||||||
|
path = _get_assoc_file()
|
||||||
|
assoc_id, public_key = connection.dump_associate()
|
||||||
|
data = {"name": assoc_id, "public_key": list(public_key)}
|
||||||
|
with open(path, "w") as fh:
|
||||||
|
json.dump(data, fh)
|
||||||
|
os.chmod(path, 0o600)
|
||||||
|
|
||||||
|
|
||||||
|
def _connect():
|
||||||
|
"""Return an authenticated, test-verified Connection to KeePassXC."""
|
||||||
|
try:
|
||||||
|
from keepassxc_proxy_client.protocol import Connection, ResponseUnsuccesfulException
|
||||||
|
except ImportError:
|
||||||
|
raise AnsibleError(
|
||||||
|
"keepassxc-proxy-client is not installed. "
|
||||||
|
"Run: pip install keepassxc-proxy-client"
|
||||||
|
)
|
||||||
|
|
||||||
|
conn = Connection()
|
||||||
|
|
||||||
|
try:
|
||||||
|
conn.connect()
|
||||||
|
except Exception as exc:
|
||||||
|
raise AnsibleError(
|
||||||
|
"Cannot connect to KeePassXC. Is it running with Browser Integration enabled? "
|
||||||
|
"Error: {}".format(exc)
|
||||||
|
)
|
||||||
|
|
||||||
|
conn.change_public_keys()
|
||||||
|
|
||||||
|
# Try to reuse an existing association
|
||||||
|
if _load_assoc(conn):
|
||||||
|
try:
|
||||||
|
conn.test_associate(trigger_unlock=True)
|
||||||
|
return conn # existing association is still valid
|
||||||
|
except Exception:
|
||||||
|
pass # fall through and re-associate
|
||||||
|
|
||||||
|
# First run (or stale association) — ask KeePassXC to authorise us
|
||||||
|
try:
|
||||||
|
conn.associate()
|
||||||
|
except Exception as exc:
|
||||||
|
raise AnsibleError(
|
||||||
|
"KeePassXC association failed. "
|
||||||
|
"Please approve the request in the KeePassXC dialog. "
|
||||||
|
"Error: {}".format(exc)
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
conn.test_associate(trigger_unlock=True)
|
||||||
|
except Exception as exc:
|
||||||
|
raise AnsibleError("KeePassXC association test failed: {}".format(exc))
|
||||||
|
|
||||||
|
_save_assoc(conn)
|
||||||
|
return conn
|
||||||
|
|
||||||
|
|
||||||
class LookupModule(LookupBase):
|
class LookupModule(LookupBase):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(LookupModule, self).__init__(*args, **kwargs)
|
|
||||||
self.k = keepasshttplib.Keepasshttplib()
|
|
||||||
|
|
||||||
def run(self, terms, variables=None, **kwargs):
|
def run(self, terms, variables=None, **kwargs):
|
||||||
if not terms or len(terms) > 2:
|
if not terms or len(terms) > 2:
|
||||||
raise AnsibleError('Keepass wrong request format')
|
raise AnsibleError(
|
||||||
if len(terms) == 1:
|
"keepass lookup expects 1 or 2 arguments: "
|
||||||
entry_path, entry_attr = terms[0], 'password'
|
"lookup('keepass', '<url>', '<attribute>')"
|
||||||
|
)
|
||||||
|
|
||||||
|
url = terms[0]
|
||||||
|
attr = terms[1].lower() if len(terms) == 2 else "password"
|
||||||
|
|
||||||
|
if attr not in USERNAME_ATTRS | PASSWORD_ATTRS:
|
||||||
|
raise AnsibleError(
|
||||||
|
"keepass: unsupported attribute '{}'. "
|
||||||
|
"Use one of: username, user, password, pass, passwd".format(attr)
|
||||||
|
)
|
||||||
|
|
||||||
|
conn = _connect()
|
||||||
|
|
||||||
|
try:
|
||||||
|
entries = conn.get_logins(url)
|
||||||
|
except Exception as exc:
|
||||||
|
raise AnsibleError(
|
||||||
|
"keepass: failed to retrieve logins for '{}': {}".format(url, exc)
|
||||||
|
)
|
||||||
|
|
||||||
|
if not entries:
|
||||||
|
raise AnsibleError(
|
||||||
|
"keepass: no entries found in KeePassXC for URL '{}'".format(url)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Return the first matching entry (KeePassXC already filters by URL)
|
||||||
|
entry = entries[0]
|
||||||
|
|
||||||
|
if attr in USERNAME_ATTRS:
|
||||||
|
return [entry.get("login", "")]
|
||||||
else:
|
else:
|
||||||
entry_path, entry_attr = terms[0], terms[1]
|
return [entry.get("password", "")]
|
||||||
|
|
||||||
#if not self._test_connection():
|
|
||||||
# raise AnsibleError('Keepass is closed!')
|
|
||||||
try:
|
|
||||||
auth = self.k.get_credentials(entry_path)
|
|
||||||
except Exception as e:
|
|
||||||
raise AnsibleError('Keepass error obtaining entry {}: {}'.format(entry_path, e))
|
|
||||||
if auth:
|
|
||||||
if entry_attr not in ('username', 'user', 'pass', 'passwd', 'password'):
|
|
||||||
raise AnsibleError("Keepass wrong entry")
|
|
||||||
|
|
||||||
ret = auth[0] if entry_attr.startswith('user') else auth[1]
|
|
||||||
return [ret]
|
|
||||||
|
|
||||||
def _test_connection(self):
|
|
||||||
key = self.k.get_key_from_keyring()
|
|
||||||
if key is None:
|
|
||||||
key = encrypter.generate_key()
|
|
||||||
id_ = self.k.get_id_from_keyring()
|
|
||||||
try:
|
|
||||||
return self.k.test_associate(key, id_)
|
|
||||||
except requests.exceptions.ConnectionError as e:
|
|
||||||
raise AnsibleError('Keepass Connection Error: {}'.format(e))
|
|
||||||
|
|||||||
28
mediapis.yml
Normal file
28
mediapis.yml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
- name: Media Pis (squeezelite/shairport audio players)
|
||||||
|
hosts: mediapis
|
||||||
|
roles:
|
||||||
|
- unattended_upgrades
|
||||||
|
- pi_modern_shell_env
|
||||||
|
- pi_standard_setup
|
||||||
|
- role: pi_hifiberry_amp
|
||||||
|
when: mediapi_has_hifiberry_amp
|
||||||
|
- role: pi_musicmouse
|
||||||
|
when: mediapi_install_kidsmusic
|
||||||
|
- role: pi_kiosk
|
||||||
|
when: mediapi_has_monitor
|
||||||
|
- pi_squeezelite_custom
|
||||||
|
- role: pi_squeezeserver
|
||||||
|
vars:
|
||||||
|
pi_squeezeserver_state: "{{ 'present' if mediapi_has_squeezeserver else 'absent' }}"
|
||||||
|
- pi_shairport
|
||||||
|
- role: pi_irserver
|
||||||
|
when: mediapi_ir_control == 'irserver'
|
||||||
|
- role: pi_lirc
|
||||||
|
when: mediapi_ir_control == 'lirc'
|
||||||
|
- role: pi_dhtsensor
|
||||||
|
when: mediapi_has_dhtsensor
|
||||||
|
- role: pi_disable_onboard_bluetooth
|
||||||
|
when: mediapi_disable_onboard_bluetooth
|
||||||
|
- role: bluetooth_monitor
|
||||||
|
when: mediapi_install_bluetooth_monitor
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
---
|
---
|
||||||
- hosts: musicmouse
|
- name: Musicmouse
|
||||||
|
hosts: musicmouse
|
||||||
roles:
|
roles:
|
||||||
- pi-standard-setup
|
- pi_standard_setup
|
||||||
- pi-hifiberry-amp
|
- pi_hifiberry_amp
|
||||||
- pi-squeezelite
|
- pi_squeezelite
|
||||||
- pi-shairport
|
- pi_shairport
|
||||||
- pi-lirc
|
- pi_lirc
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
- hosts: octopi
|
---
|
||||||
|
- name: Octopi
|
||||||
|
hosts: octopi
|
||||||
roles:
|
roles:
|
||||||
- pi-dhtsensor
|
- pi_dhtsensor
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
---
|
---
|
||||||
|
- name: Install Debmatic
|
||||||
- hosts: kitchenpi
|
hosts: kitchenpi
|
||||||
tasks:
|
tasks:
|
||||||
- name: Add Key for Debmatic Repository
|
- name: Add Key for Debmatic Repository
|
||||||
apt_key:
|
ansible.builtin.apt_key:
|
||||||
url: https://www.debmatic.de/debmatic/public.key
|
url: https://www.debmatic.de/debmatic/public.key
|
||||||
state: present
|
state: present
|
||||||
- name: Add Debmatic Repository
|
- name: Add Debmatic Repository
|
||||||
repo: deb https://www.debmatic.de/debmatic stable main
|
ansible.builtin.apt_repository:
|
||||||
state: present
|
repo: deb https://www.debmatic.de/debmatic stable main
|
||||||
filename: debmatic
|
state: present
|
||||||
|
filename: debmatic
|
||||||
- name: Install Pre-requesites
|
- name: Install Pre-requesites
|
||||||
apt:
|
ansible.builtin.apt:
|
||||||
update_cache: yes
|
update_cache: true
|
||||||
name:
|
name:
|
||||||
- build-essential
|
- build-essential
|
||||||
- bison
|
- bison
|
||||||
@@ -21,8 +22,8 @@
|
|||||||
- raspberrypi-kernel-headers
|
- raspberrypi-kernel-headers
|
||||||
- pivccu-modules-dkms
|
- pivccu-modules-dkms
|
||||||
- name: Reboot
|
- name: Reboot
|
||||||
reboot:
|
ansible.builtin.reboot:
|
||||||
- name: Install Debmatic package
|
- name: Install Debmatic package
|
||||||
apt:
|
ansible.builtin.apt:
|
||||||
update_cache: no
|
update_cache: false
|
||||||
name: debmatic
|
name: debmatic
|
||||||
|
|||||||
7
requirements.txt
Normal file
7
requirements.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Python dependencies for the Ansible *control node* (the machine running
|
||||||
|
# ansible-playbook). Dependencies needed only on managed hosts (Pis/server)
|
||||||
|
# are installed by the relevant roles themselves via apt/pip tasks.
|
||||||
|
ansible-core>=2.14
|
||||||
|
ansible-lint
|
||||||
|
keepassxc-proxy-client
|
||||||
|
passlib
|
||||||
4
requirements.yml
Normal file
4
requirements.yml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
collections:
|
||||||
|
- name: ansible.posix
|
||||||
|
- name: community.general
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
function dot -w git -d "Manages dotfiles"
|
|
||||||
git --git-dir=$HOME/.dot --work-tree=$HOME $argv
|
|
||||||
end
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
---
|
|
||||||
#
|
|
||||||
- name: Install packages
|
|
||||||
apt:
|
|
||||||
name:
|
|
||||||
- bat
|
|
||||||
- broot
|
|
||||||
- duf
|
|
||||||
- fd-find
|
|
||||||
- fish
|
|
||||||
- fzf
|
|
||||||
- git
|
|
||||||
- glances
|
|
||||||
- lsd
|
|
||||||
- neovim
|
|
||||||
- ripgrep
|
|
||||||
- tmux
|
|
||||||
- zoxide
|
|
||||||
|
|
||||||
# TODO: Dust, btm
|
|
||||||
|
|
||||||
block:
|
|
||||||
become: true
|
|
||||||
become_user: {{main_user}}
|
|
||||||
- name: Create bin folder
|
|
||||||
ansible.builtin.file:
|
|
||||||
path: ~/bin
|
|
||||||
state: directory
|
|
||||||
mode: '0755'
|
|
||||||
|
|
||||||
# Oh-my-fish
|
|
||||||
- name: get oh-my-fish repo
|
|
||||||
git:
|
|
||||||
repo: 'https://github.com/oh-my-fish/oh-my-fish.git'
|
|
||||||
dest: ~/.local/share/git/oh-my-fish
|
|
||||||
- name: install oh-my-fish
|
|
||||||
shell:
|
|
||||||
cmd: "bin/install --offline --noninteractive"
|
|
||||||
executable: /usr/bin/fish
|
|
||||||
chdir: ~/.local/share/git/oh-my-fish
|
|
||||||
creates:
|
|
||||||
- ~/.local/share/omf
|
|
||||||
- ~/.config/omf
|
|
||||||
- copy:
|
|
||||||
content: "bobthefish"
|
|
||||||
dst: "~/.config/omf/theme"
|
|
||||||
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
- name: Apt install bluez, firmware and Python requirements
|
|
||||||
apt:
|
|
||||||
name:
|
|
||||||
- bluez
|
|
||||||
- bluez-firmware
|
|
||||||
- firmware-realtek
|
|
||||||
- firmware-realtek-rtl8723cs-bt
|
|
||||||
- python3-pycryptodome
|
|
||||||
- python3-bleak
|
|
||||||
- python3-asyncio-mqtt
|
|
||||||
- python3-numpy
|
|
||||||
- name: Copy monitor script
|
|
||||||
template: src=my_btmonitor.py dest=/usr/bin/my_btmonitor owner=root mode=u+rwx
|
|
||||||
- name: Install systemd service file
|
|
||||||
copy: src=my_btmonitor.service dest=/etc/systemd/system/
|
|
||||||
- name: Add script to autostart and start now
|
|
||||||
systemd: name=my_btmonitor state=restarted enabled=yes daemon_reload=yes
|
|
||||||
#- name: Add to sysdweb
|
|
||||||
# include_role:
|
|
||||||
# name: pi-sysdweb
|
|
||||||
# vars:
|
|
||||||
# sysdweb_name: my_btmonitor
|
|
||||||
12
roles/bluetooth_monitor/README.md
Normal file
12
roles/bluetooth_monitor/README.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# bluetooth_monitor
|
||||||
|
|
||||||
|
Installs `my_btmonitor.py` (BLE scanning via `bleak`) as a systemd service
|
||||||
|
that watches for nearby devices, publishes state over MQTT, and can restart
|
||||||
|
the local BLE interface on a watchdog timeout.
|
||||||
|
|
||||||
|
**Key vars:** `my_bt_monitor_watchdog_seconds`, `my_btmonitor_restart_ble_interface`,
|
||||||
|
`my_btmonitor_mqtt_username`, `my_btmonitor_mqtt_password`
|
||||||
|
|
||||||
|
`other/` is not part of the deployed role — it's a separate, standalone
|
||||||
|
data-analysis project (Jupyter notebook, Dockerfile, collected CSV data) used
|
||||||
|
to analyze data captured by the monitor.
|
||||||
5
roles/bluetooth_monitor/handlers/main.yml
Normal file
5
roles/bluetooth_monitor/handlers/main.yml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
- name: Restart my_btmonitor
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: my_btmonitor
|
||||||
|
state: restarted
|
||||||
|
Can't render this file because it is too large.
|
|
Can't render this file because it is too large.
|
36
roles/bluetooth_monitor/tasks/main.yml
Normal file
36
roles/bluetooth_monitor/tasks/main.yml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
- name: Apt install bluez, firmware and Python requirements
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- bluez
|
||||||
|
- bluez-firmware
|
||||||
|
- firmware-realtek
|
||||||
|
- firmware-realtek-rtl8723cs-bt
|
||||||
|
- python3-pycryptodome
|
||||||
|
- python3-bleak
|
||||||
|
- python3-asyncio-mqtt
|
||||||
|
- python3-numpy
|
||||||
|
- name: Copy monitor script
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: my_btmonitor.py
|
||||||
|
dest: /usr/bin/my_btmonitor
|
||||||
|
owner: root
|
||||||
|
mode: u+rwx
|
||||||
|
notify: Restart my_btmonitor
|
||||||
|
- name: Install systemd service file
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: my_btmonitor.service
|
||||||
|
dest: /etc/systemd/system/
|
||||||
|
mode: "0644"
|
||||||
|
notify: Restart my_btmonitor
|
||||||
|
- name: Add script to autostart and start now
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: my_btmonitor
|
||||||
|
state: started
|
||||||
|
enabled: "yes"
|
||||||
|
daemon_reload: "yes"
|
||||||
|
# - name: Add to sysdweb
|
||||||
|
# include_role:
|
||||||
|
# name: pi_sysdweb
|
||||||
|
# vars:
|
||||||
|
# pi_sysdweb_name: my_btmonitor
|
||||||
@@ -10,6 +10,7 @@ import json
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
import subprocess
|
||||||
|
|
||||||
# ------------------- Config ----------------------------------------------------------------
|
# ------------------- Config ----------------------------------------------------------------
|
||||||
|
|
||||||
@@ -78,6 +79,12 @@ async def ble_scan():
|
|||||||
await stop_event.wait()
|
await stop_event.wait()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Error", e)
|
print("Error", e)
|
||||||
|
try:
|
||||||
|
subprocess.run(["hciconfig", "hci0", "reset"], check=True)
|
||||||
|
except Exception as reset_err:
|
||||||
|
print(f"Reset failed: {reset_err}")
|
||||||
|
await asyncio.sleep(3)
|
||||||
|
|
||||||
print("Starting again")
|
print("Starting again")
|
||||||
|
|
||||||
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Sync alsa config
|
|
||||||
template: src=asound.conf dest=/etc/asound.conf
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
dht_pin: "D12"
|
|
||||||
dht_polling_sleep_time_seconds: 20
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
---
|
|
||||||
- name: apt install libgpiod2
|
|
||||||
apt: name=libgpiod2 cache_valid_time=7200 state=present
|
|
||||||
- name: pip install adafruit-circuitpython-dht
|
|
||||||
pip:
|
|
||||||
name: adafruit-circuitpython-dht
|
|
||||||
executable: pip3
|
|
||||||
- name: Install script config
|
|
||||||
template: src=dht22_sensing.json dest=/etc/dht22_sensing.json
|
|
||||||
- name: Install script
|
|
||||||
copy: src=dht22_sensing.py dest=/usr/bin/dht22_sensing owner=root mode=u+rwx
|
|
||||||
- name: Install systemd service file
|
|
||||||
copy: src=dht22_sensing.service dest=/lib/systemd/system/
|
|
||||||
- name: Add script to autostart and start now
|
|
||||||
systemd: name=dht22_sensing state=started enabled=yes daemon_reload=yes
|
|
||||||
- name: Add to sysdweb
|
|
||||||
include_role:
|
|
||||||
name: pi-sysdweb
|
|
||||||
vars:
|
|
||||||
sysdweb_name: dht22_sensing
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
dht_pin: 12
|
|
||||||
dht_polling_sleep_time_seconds: 20
|
|
||||||
Binary file not shown.
@@ -1,31 +0,0 @@
|
|||||||
---
|
|
||||||
# Use the deprecated version here instead, not the new circuitpython adafruit-circuitpython-dht version
|
|
||||||
# the new version needs a lot of CPU time and doesn't work correctly on old raspi 1
|
|
||||||
# a copy of the deprecated repo is downloaded as zip (if it goes away)
|
|
||||||
|
|
||||||
- name: Uninstall libgpiod2 (circuitpython) if present
|
|
||||||
apt: name=libgpiod2 cache_valid_time=7200 state=absent
|
|
||||||
- name: pip uninstall adafruit-circuitpython-dht
|
|
||||||
pip:
|
|
||||||
name: adafruit-circuitpython-dht
|
|
||||||
executable: pip3
|
|
||||||
state: absent
|
|
||||||
extra_args: "--break-system-packages"
|
|
||||||
- name: pip install adafruit-dht
|
|
||||||
pip:
|
|
||||||
name: adafruit-dht
|
|
||||||
executable: pip3
|
|
||||||
extra_args: "--break-system-packages"
|
|
||||||
- name: Install script config
|
|
||||||
template: src=dht22_sensing.json dest=/etc/dht22_sensing.json
|
|
||||||
- name: Install script
|
|
||||||
copy: src=dht22_sensing.py dest=/usr/bin/dht22_sensing owner=root mode=u+rwx
|
|
||||||
- name: Install systemd service file
|
|
||||||
copy: src=dht22_sensing.service dest=/etc/systemd/system/
|
|
||||||
- name: Add script to autostart and start now
|
|
||||||
systemd: name=dht22_sensing state=restarted enabled=yes daemon_reload=yes
|
|
||||||
- name: Add to sysdweb
|
|
||||||
include_role:
|
|
||||||
name: pi-sysdweb
|
|
||||||
vars:
|
|
||||||
sysdweb_name: dht22_sensing
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
---
|
|
||||||
- name: reboot
|
|
||||||
reboot:
|
|
||||||
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
---
|
|
||||||
- name: reboot
|
|
||||||
reboot:
|
|
||||||
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
dependencies:
|
|
||||||
- role: pi-alsasetup
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Copy irserver
|
|
||||||
copy: src=irserver dest=/usr/bin/irserver mode=u+rx
|
|
||||||
- name: Make config dir for remotes
|
|
||||||
file: path=/usr/bin/remotes state=directory
|
|
||||||
- name: Copy hauppauge remote
|
|
||||||
copy: src=hauppauge.rem dest=/usr/bin/remotes/
|
|
||||||
- name: Copy irserver systemd file
|
|
||||||
copy: src=irserver.service dest=/lib/systemd/system/
|
|
||||||
- name: Enable irserver autostart
|
|
||||||
systemd: name=irserver state=restarted enabled=yes daemon_reload=yes
|
|
||||||
- name: Add irserver to sysdweb
|
|
||||||
include_role:
|
|
||||||
name: pi-sysdweb
|
|
||||||
vars:
|
|
||||||
sysdweb_name: irserver
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Install lirc
|
|
||||||
apt:
|
|
||||||
name: lirc
|
|
||||||
- name: Install config file lirc_options.conf
|
|
||||||
copy: src=lirc_options.conf dest=/etc/lirc/lirc_options.conf
|
|
||||||
- name: Install config file lircd.conf
|
|
||||||
copy: src=lircd.conf dest=/etc/lirc/lircd.conf
|
|
||||||
- name: Install remote file
|
|
||||||
copy: src=hauppauge.conf dest=/etc/lirc/hauppauge.conf
|
|
||||||
- name: Activate overlay in boot config
|
|
||||||
lineinfile:
|
|
||||||
path: /boot/firmware/config.txt
|
|
||||||
regexp: "^#?dtoverlay=gpio-ir"
|
|
||||||
line: "dtoverlay=gpio-ir,gpio_pin=17"
|
|
||||||
register: boot_overlay
|
|
||||||
- name: Restart lircd
|
|
||||||
systemd: name=lircd state=started enabled=yes daemon_reload=yes
|
|
||||||
- name: Reboot if boot overlay changed
|
|
||||||
reboot:
|
|
||||||
when: boot_overlay.changed
|
|
||||||
- name: Add to sysdweb
|
|
||||||
include_role:
|
|
||||||
name: pi-sysdweb
|
|
||||||
vars:
|
|
||||||
sysdweb_name: lircd
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
general:
|
|
||||||
alsa_device: softvol_effects
|
|
||||||
mqtt:
|
|
||||||
user: musicmouse
|
|
||||||
password: KNLEFLZF94yA6Zhj141
|
|
||||||
server: homeassistant
|
|
||||||
hass_url: https://ha.bauer.tech
|
|
||||||
hass_token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI4N2ExMzM2ZmQ4ZWQ0ZDgzOWZhMjU3NmZjYTg1NWQ1ZiIsImlhdCI6MTcwNDAyOTUyOSwiZXhwIjoyMDE5Mzg5NTI5fQ.vx9L5bTSey98uc8TwodShaEXSMr-hjXugPsNviR_fEw"
|
|
||||||
button_leds_brightness: 0.5
|
|
||||||
volume_increment: 5
|
|
||||||
min_volume: 23
|
|
||||||
max_volume: 70
|
|
||||||
serial_port: "/dev/ttyUSB0"
|
|
||||||
|
|
||||||
figures:
|
|
||||||
elefant:
|
|
||||||
id: "88041174e9"
|
|
||||||
colors: ["#ffff00", "#00c8ff", "#094b46", "#c20099"]
|
|
||||||
fuchs:
|
|
||||||
id: "8804ce7230"
|
|
||||||
colors: ["#F4D35E", "#F95738", "#F95738", "#083d77"]
|
|
||||||
eule:
|
|
||||||
id: "88040d71f0"
|
|
||||||
colors: ["#e5a200", "#f8e300", "w33", "w99"]
|
|
||||||
omnom:
|
|
||||||
id: "88043c6ede"
|
|
||||||
colors: ["#005102", "#fec800", "#005102", "#3bc405"]
|
|
||||||
eichhoernchen:
|
|
||||||
id: "88040b78ff"
|
|
||||||
colors: ["#ff0ada", "#4BC6B9", "#69045a", "#4BC6B9"]
|
|
||||||
hund:
|
|
||||||
id: "8804bc7444"
|
|
||||||
colors: ["#ffff00", "#00c8ff", "#094b46", "#c20099"]
|
|
||||||
hase:
|
|
||||||
id: "88044670ba"
|
|
||||||
colors: ["#ffff00", "#00c8ff", "#094b46", "#c20099"]
|
|
||||||
schneemann:
|
|
||||||
id: "88043f71c2"
|
|
||||||
colors: ["#ff0ada", "#4BC6B9", "#69045a", "#4BC6B9"]
|
|
||||||
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=MusicMouse Player
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
Restart=always
|
|
||||||
ExecStart=/opt/musicmouse_venv/bin/python /opt/musicmouse/espmusicmouse/host_driver/main.py /media/musicmouse/
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Packages
|
|
||||||
apt:
|
|
||||||
name:
|
|
||||||
- python3
|
|
||||||
- python3-pip
|
|
||||||
- python3-vlc # also in venv - but this installs vlc + deps
|
|
||||||
- samba
|
|
||||||
- name: Checkout Musicmouse repo
|
|
||||||
ansible.builtin.git:
|
|
||||||
repo: 'ssh://git@git.bauer.tech:2222/martin/musicmouse.git'
|
|
||||||
dest: '/opt/musicmouse'
|
|
||||||
version: 'release/1.1'
|
|
||||||
accept_hostkey: true
|
|
||||||
- name: Create and update virtual env
|
|
||||||
ansible.builtin.pip:
|
|
||||||
requirements: /opt/musicmouse/espmusicmouse/host_driver/requirements.txt
|
|
||||||
virtualenv: /opt/musicmouse_venv
|
|
||||||
virtualenv_command: "/usr/bin/python3 -m venv"
|
|
||||||
- name: Create media directory
|
|
||||||
file:
|
|
||||||
path: /media/musicmouse
|
|
||||||
state: directory
|
|
||||||
- name: Install config file
|
|
||||||
copy: src=config.yml dest=/media/musicmouse/config.yml
|
|
||||||
- name: Install systemd service file
|
|
||||||
copy: src=musicmouse.service dest=/etc/systemd/system/
|
|
||||||
- name: Add script to autostart and start now
|
|
||||||
systemd: name=musicmouse state=restarted enabled=yes daemon_reload=yes
|
|
||||||
- name: Samba setup
|
|
||||||
copy: src=smb.conf dest=/etc/samba/
|
|
||||||
- name: Restart samba
|
|
||||||
systemd: name=smbd state=restarted enabled=yes
|
|
||||||
# manual steps:
|
|
||||||
# - set samba passwords with smbpasswd
|
|
||||||
# - copy music into /media/musicmouse (or via samba share)
|
|
||||||
# - upload host driver?
|
|
||||||
# - manual patching of hassclient necessary :( loop has to be passed in, to not use running_event_loop
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
shairport_sync_version: "3.3.5"
|
|
||||||
shairport_name: Unnamed Raspberry with shairport
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
dependencies:
|
|
||||||
- role: pi-alsasetup
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Check if sispmctl already exists
|
|
||||||
stat: path=/usr/bin/sispmctl
|
|
||||||
register: sispmctl_file
|
|
||||||
- name: Install dependencies
|
|
||||||
apt: name="libusb-dev" cache_valid_time=7200 state=present
|
|
||||||
- name: Copy sispmctl sources
|
|
||||||
unarchive: src=sispmctl-4.7.tar.gz dest=/tmp
|
|
||||||
when: sispmctl_file.stat.exists == false
|
|
||||||
- name: Build and install
|
|
||||||
shell: cd /tmp/sispmctl*/ && ./configure --prefix=/usr && make install
|
|
||||||
when: sispmctl_file.stat.exists == false
|
|
||||||
- name: Install systemd service file
|
|
||||||
copy: src=sispmctl.service dest=/lib/systemd/system/
|
|
||||||
- name: Add script to autostart and start now
|
|
||||||
systemd: name=sispmctl state=started enabled=yes daemon_reload=yes
|
|
||||||
- name: Add to sysdweb
|
|
||||||
include_role:
|
|
||||||
name: pi-sysdweb
|
|
||||||
vars:
|
|
||||||
sysdweb_name: sispmctl
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Uninstall system package of squeezelite
|
|
||||||
apt: name=squeezelite state=absent
|
|
||||||
- name: Install dependencies
|
|
||||||
apt:
|
|
||||||
name:
|
|
||||||
- libmad0
|
|
||||||
- libmpg123-0
|
|
||||||
- libflac12
|
|
||||||
- libvorbisfile3
|
|
||||||
- libfaad2
|
|
||||||
# for building libssl-dev, libasound2-dev, libflac-dev, libvorbis-dev, libsoxr-dev, libfaad-dev, libmad0-dev, libmpg123-dev
|
|
||||||
state: present
|
|
||||||
cache_valid_time: 7200
|
|
||||||
- name: Remove old config file if present
|
|
||||||
file: path=/etc/default/squeezelite state=absent
|
|
||||||
- name: Copy over custom compile version of squeezelite
|
|
||||||
copy: src=squeezelite dest=/opt/squeezelite mode=700
|
|
||||||
- name: Install systemd service file
|
|
||||||
template: src=squeezelite.service dest=/lib/systemd/system/
|
|
||||||
- name: Enable sysdweb autostart
|
|
||||||
systemd: name=squeezelite state=restarted enabled=yes daemon_reload=yes
|
|
||||||
- name: Add to sysdweb
|
|
||||||
include_role:
|
|
||||||
name: pi-sysdweb
|
|
||||||
vars:
|
|
||||||
sysdweb_name: squeezelite
|
|
||||||
|
|
||||||
|
|
||||||
# build with adapted Makefile.rpi:
|
|
||||||
#OPTS = -DRESAMPLE -DDSD -DUSE_SSL -DLINKALL -I./include -I./include/opus -I./include/alac -I/usr/local/include -s -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
---
|
|
||||||
squeezeserver: 192.168.178.80
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
- name: restart-squeezelite
|
|
||||||
systemd: name=squeezelite state=restarted enabled=yes daemon_reload=yes
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
dependencies:
|
|
||||||
- role: pi-alsasetup
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Apt install squeezelite package
|
|
||||||
apt: name=squeezelite cache_valid_time=7200 state=present
|
|
||||||
notify: restart-squeezelite
|
|
||||||
- name: Install config file
|
|
||||||
template: src=squeezelite.cfg dest=/etc/default/squeezelite
|
|
||||||
notify: restart-squeezelite
|
|
||||||
- name: Add to sysdweb
|
|
||||||
include_role:
|
|
||||||
name: pi-sysdweb
|
|
||||||
vars:
|
|
||||||
sysdweb_name: squeezelite
|
|
||||||
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
wifi_ssid: "" # put SSID here to configure wifi
|
|
||||||
ansible_user: "root" # "User to connect with, put in 'pi' here if you connect the first time, else leave empty"
|
|
||||||
new_hostname: "" # set this to change the hostname
|
|
||||||
|
|
||||||
|
|
||||||
timezone: "Europe/Berlin"
|
|
||||||
wifi_country: "DE"
|
|
||||||
wifi_pass_url: "bauer_wifi" # has to be in keepass with url "wifi_pass_url"
|
|
||||||
ansible_ssh_pass: "raspberry"
|
|
||||||
ansible_become_password: "raspberry"
|
|
||||||
ansible_become: yes
|
|
||||||
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
EsszimmerRadio Eltern
|
|
||||||
|
|
||||||
________
|
|
||||||
/______ |
|
|
||||||
| | | _
|
|
||||||
| ===== | | | |
|
|
||||||
| ===== | | o o
|
|
||||||
| | | |~
|
|
||||||
| .-. | | o o o
|
|
||||||
| ' . ' | | |~ |_|
|
|
||||||
..'| '._.' | | o
|
|
||||||
.' |_______|/
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
|
|
||||||
Musik Server Wohnzimmer oben
|
|
||||||
|
|
||||||
|~~~~~~~~~~~~~~~|
|
|
||||||
|~~~~~~~~~~~~~~~|
|
|
||||||
| |
|
|
||||||
/~~\| /~~\|
|
|
||||||
\__/ \__/
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo none > /sys/class/leds/led0/trigger
|
|
||||||
echo none > /sys/class/leds/led1/trigger
|
|
||||||
|
|
||||||
echo 0 >/sys/class/leds/led0/brightness
|
|
||||||
echo 0 >/sys/class/leds/led1/brightness
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
---
|
|
||||||
- name: restart sshd
|
|
||||||
service:
|
|
||||||
name: sshd
|
|
||||||
state: restarted
|
|
||||||
- name: reboot
|
|
||||||
reboot:
|
|
||||||
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Do apt update/upgrade
|
|
||||||
apt: upgrade=yes update_cache=yes cache_valid_time=7200
|
|
||||||
- name: Detect Raspi Model
|
|
||||||
slurp: src=/sys/firmware/devicetree/base/model
|
|
||||||
register: raspberry_model
|
|
||||||
- name: Show Raspi Model
|
|
||||||
debug: msg={{ raspberry_model.content | b64decode }}
|
|
||||||
- name: Add authorized SSH key to root account
|
|
||||||
authorized_key:
|
|
||||||
user: root
|
|
||||||
key: "{{ lookup('file', 'sshkey.pub') }}"
|
|
||||||
state: present
|
|
||||||
- name: Activate root login with key
|
|
||||||
lineinfile:
|
|
||||||
path: /etc/ssh/sshd_config
|
|
||||||
regexp: "^#?PermitRootLogin"
|
|
||||||
line: "PermitRootLogin prohibit-password"
|
|
||||||
notify: restart sshd
|
|
||||||
- name: Deactive SSH accepting locale vars (leads to warnings)
|
|
||||||
lineinfile:
|
|
||||||
path: /etc/ssh/sshd_config
|
|
||||||
regexp: "^#?AcceptEnv LANG LC_*"
|
|
||||||
line: "#AcceptEnv LANG LC_*"
|
|
||||||
notify: restart sshd
|
|
||||||
- name: Get hostname
|
|
||||||
command: "raspi-config nonint get_hostname"
|
|
||||||
register: pi_hostname
|
|
||||||
changed_when: False
|
|
||||||
- name: Change hostname {{ new_hostname }}
|
|
||||||
command: "raspi-config nonint do_hostname {{ new_hostname }}"
|
|
||||||
when: new_hostname | bool and pi_hostname.stdout != new_hostname
|
|
||||||
register: set_hostname
|
|
||||||
notify: reboot
|
|
||||||
- name: Get hostname
|
|
||||||
command: "raspi-config nonint get_hostname"
|
|
||||||
register: pi_hostname
|
|
||||||
changed_when: False
|
|
||||||
- name: set boot mode to CLI
|
|
||||||
command: "raspi-config nonint do_boot_behaviour B1"
|
|
||||||
#I2 Change Timezone
|
|
||||||
- name: Change timezone
|
|
||||||
command: "raspi-config nonint do_change_timezone {{ timezone }}"
|
|
||||||
- name: Change locale
|
|
||||||
command: "raspi-config nonint do_change_locale en_US.UTF-8"
|
|
||||||
- name: Change password of default pi account
|
|
||||||
user:
|
|
||||||
name: pi
|
|
||||||
update_password: always
|
|
||||||
password: "{{ lookup('keepass', 'default_rpi_password') | password_hash('sha512') }}"
|
|
||||||
- name: Install Packages (vim, git, basic python stuff)
|
|
||||||
apt:
|
|
||||||
name:
|
|
||||||
- vim
|
|
||||||
- git
|
|
||||||
- python3
|
|
||||||
- python3-pip
|
|
||||||
- python3-wheel
|
|
||||||
- telnet
|
|
||||||
cache_valid_time: 7200
|
|
||||||
state: present
|
|
||||||
- name: Copy vim config
|
|
||||||
copy: src=vimrc dest=/root/.vimrc
|
|
||||||
- name: Copy git config
|
|
||||||
copy: src=gitconfig dest=/root/.gitconfig
|
|
||||||
# Wifi
|
|
||||||
- name: Get WiFi country
|
|
||||||
command: "raspi-config nonint get_wifi_country"
|
|
||||||
register: wifi_country
|
|
||||||
changed_when: False
|
|
||||||
ignore_errors: yes #to avoid error when WiFi is not present
|
|
||||||
- name: Change WiFi country
|
|
||||||
command: "raspi-config nonint do_wifi_country {{ wifi_country }}"
|
|
||||||
when: configure_wifi
|
|
||||||
- name: Set WiFi credentials
|
|
||||||
command: "raspi-config nonint do_wifi_ssid_passphrase {{ wifi_ssid }} {{ lookup('keepass', 'bauer_wifi') }}"
|
|
||||||
when: configure_wifi
|
|
||||||
- name: Install watchdog
|
|
||||||
apt: name=watchdog cache_valid_time=7200 state=present
|
|
||||||
when: not wifi_ssid is defined
|
|
||||||
- name: Configure watchdog
|
|
||||||
blockinfile:
|
|
||||||
path: /etc/watchdog.conf
|
|
||||||
block: |
|
|
||||||
interface = wlan0
|
|
||||||
retry-timeout = 90
|
|
||||||
ping = {{router_ip}}
|
|
||||||
interval = 15
|
|
||||||
when: configure_wifi
|
|
||||||
- name: Start watchdog
|
|
||||||
systemd: name=watchdog state=started enabled=yes daemon_reload=yes # state=restarted not working, also not manually
|
|
||||||
when: configure_wifi
|
|
||||||
# Message of the day
|
|
||||||
- name: Set Message of the day
|
|
||||||
copy: src=motd/{{ pi_hostname.stdout }} dest=/etc/motd
|
|
||||||
# LED off script
|
|
||||||
- name: Copy led off script
|
|
||||||
copy: src=raspi-leds-off.sh dest=/usr/sbin/raspi-leds-off.sh mode="u+rwx"
|
|
||||||
- name: Copy led off service
|
|
||||||
copy: src=raspi-leds-off.service dest=/lib/systemd/system/
|
|
||||||
- name: Activate led off servic
|
|
||||||
systemd: name=raspi-leds-off state=restarted enabled=yes daemon_reload=yes
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
- name: Apt install python3-pip
|
|
||||||
apt:
|
|
||||||
name: python3-pip
|
|
||||||
cache_valid_time: 7200
|
|
||||||
state: present
|
|
||||||
- name: Install sysdweb
|
|
||||||
pip:
|
|
||||||
name: sysdweb
|
|
||||||
executable: pip3
|
|
||||||
extra_args: "--break-system-packages"
|
|
||||||
- name: sysdweb user
|
|
||||||
user:
|
|
||||||
name: sysdweb
|
|
||||||
shell: /usr/bin/nologin
|
|
||||||
password: "$6$TcTD23xOXln$RxN3Kd0vJRaxffoyKqjoBJM0Q5Va6REBVZ6BOgmGXs3fTAWc7voSW5QcN35t9pfro2do0LeSaeGsrMLbArZ.2."
|
|
||||||
update_password: always
|
|
||||||
- name: Configure sysdweb user
|
|
||||||
blockinfile:
|
|
||||||
path: /etc/sysdweb.conf
|
|
||||||
create: true
|
|
||||||
marker: "# {mark} ansible user"
|
|
||||||
block : |
|
|
||||||
[DEFAULT]
|
|
||||||
users = sysdweb
|
|
||||||
- name: Configure sysdweb
|
|
||||||
blockinfile:
|
|
||||||
path: /etc/sysdweb.conf
|
|
||||||
create: true
|
|
||||||
marker: "# {mark} ansible managed for {{sysdweb_name}}"
|
|
||||||
block: |
|
|
||||||
[{{sysdweb_name}}]
|
|
||||||
title = {{sysdweb_name}}
|
|
||||||
unit = {{sysdweb_name}}.service
|
|
||||||
- name: Install systemd service file
|
|
||||||
copy: src=sysdweb-system.service dest=/etc/systemd/system/
|
|
||||||
- name: Enable sysdweb autostart
|
|
||||||
systemd: name=sysdweb-system state=restarted enabled=yes daemon_reload=yes
|
|
||||||
3
roles/pi_alsasetup/README.md
Normal file
3
roles/pi_alsasetup/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# pi_alsasetup
|
||||||
|
|
||||||
|
Syncs the ALSA configuration file to the host.
|
||||||
6
roles/pi_alsasetup/tasks/main.yml
Normal file
6
roles/pi_alsasetup/tasks/main.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
- name: Sync alsa config
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: asound.conf
|
||||||
|
dest: /etc/asound.conf
|
||||||
|
mode: "0644"
|
||||||
7
roles/pi_dhtsensor/README.md
Normal file
7
roles/pi_dhtsensor/README.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# pi_dhtsensor
|
||||||
|
|
||||||
|
Installs the DHT22 temperature/humidity sensor polling script based on the
|
||||||
|
legacy `Adafruit_DHT` library (removing the circuitpython variant/
|
||||||
|
`libgpiod2` if present — mutually exclusive with `pi_dhtsensor_circuitpython`).
|
||||||
|
|
||||||
|
**Key vars:** `pi_dhtsensor_dht_pin`, `pi_dhtsensor_dht_polling_sleep_time_seconds`
|
||||||
3
roles/pi_dhtsensor/defaults/main.yml
Normal file
3
roles/pi_dhtsensor/defaults/main.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
pi_dhtsensor_dht_pin: 12
|
||||||
|
pi_dhtsensor_dht_polling_sleep_time_seconds: 20
|
||||||
5
roles/pi_dhtsensor/handlers/main.yml
Normal file
5
roles/pi_dhtsensor/handlers/main.yml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
- name: Restart dht22_sensing
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: dht22_sensing
|
||||||
|
state: restarted
|
||||||
55
roles/pi_dhtsensor/tasks/main.yml
Normal file
55
roles/pi_dhtsensor/tasks/main.yml
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
---
|
||||||
|
# Use the deprecated version here instead, not the new circuitpython adafruit-circuitpython-dht version
|
||||||
|
# the new version needs a lot of CPU time and doesn't work correctly on old raspi 1
|
||||||
|
# a copy of the deprecated repo is downloaded as zip (if it goes away)
|
||||||
|
|
||||||
|
- name: Uninstall libgpiod2 (circuitpython) if present
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: libgpiod2
|
||||||
|
cache_valid_time: "7200"
|
||||||
|
state: absent
|
||||||
|
- name: Pip uninstall adafruit-circuitpython-dht
|
||||||
|
ansible.builtin.pip:
|
||||||
|
name: adafruit-circuitpython-dht
|
||||||
|
executable: pip3
|
||||||
|
state: absent
|
||||||
|
extra_args: "--break-system-packages"
|
||||||
|
- name: Pip install adafruit-dht
|
||||||
|
ansible.builtin.pip:
|
||||||
|
name: adafruit-dht
|
||||||
|
executable: pip3
|
||||||
|
# Modern Raspberry Pi OS kernels no longer expose a "Hardware" line in
|
||||||
|
# /proc/cpuinfo, which breaks this package's built-in Pi auto-detection.
|
||||||
|
# Force it explicitly since we only ever target Raspberry Pis.
|
||||||
|
extra_args: '--break-system-packages --global-option="--force-pi"'
|
||||||
|
notify: Restart dht22_sensing
|
||||||
|
- name: Install script config
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: dht22_sensing.json
|
||||||
|
dest: /etc/dht22_sensing.json
|
||||||
|
mode: "0644"
|
||||||
|
notify: Restart dht22_sensing
|
||||||
|
- name: Install script
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: dht22_sensing.py
|
||||||
|
dest: /usr/bin/dht22_sensing
|
||||||
|
owner: root
|
||||||
|
mode: u+rwx
|
||||||
|
notify: Restart dht22_sensing
|
||||||
|
- name: Install systemd service file
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: dht22_sensing.service
|
||||||
|
dest: /etc/systemd/system/
|
||||||
|
mode: "0644"
|
||||||
|
notify: Restart dht22_sensing
|
||||||
|
- name: Add script to autostart and start now
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: dht22_sensing
|
||||||
|
state: started
|
||||||
|
enabled: "yes"
|
||||||
|
daemon_reload: "yes"
|
||||||
|
- name: Add to sysdweb
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: pi_sysdweb
|
||||||
|
vars:
|
||||||
|
pi_sysdweb_name: dht22_sensing
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"ha_url": "{{home_assistant_url}}",
|
"ha_url": "{{home_assistant_url}}",
|
||||||
"token": "{{home_assistant_token}}",
|
"token": "{{home_assistant_token}}",
|
||||||
"dht_pin": "{{dht_pin}}",
|
"dht_pin": "{{pi_dhtsensor_dht_pin}}",
|
||||||
"polling_sleep_time_seconds": "{{dht_polling_sleep_time_seconds}}",
|
"polling_sleep_time_seconds": "{{pi_dhtsensor_dht_polling_sleep_time_seconds}}",
|
||||||
|
|
||||||
"ha_temp_sensor_name": "{{sensor_room_name_ascii|lower}}_dht22_temperatur",
|
"ha_temp_sensor_name": "{{sensor_room_name_ascii|lower}}_dht22_temperatur",
|
||||||
"ha_temp_friendly_name": "{{sensor_room_name}} Temperatur",
|
"ha_temp_friendly_name": "{{sensor_room_name}} Temperatur",
|
||||||
8
roles/pi_dhtsensor_circuitpython/README.md
Normal file
8
roles/pi_dhtsensor_circuitpython/README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# pi_dhtsensor_circuitpython
|
||||||
|
|
||||||
|
Installs the DHT22 temperature/humidity sensor polling script based on
|
||||||
|
`adafruit-circuitpython-dht` (requires `libgpiod2`) — the newer alternative
|
||||||
|
to the `pi_dhtsensor` role's legacy `Adafruit_DHT` library. Mutually
|
||||||
|
exclusive with `pi_dhtsensor`.
|
||||||
|
|
||||||
|
**Key vars:** `pi_dhtsensor_circuitpython_dht_pin`, `pi_dhtsensor_circuitpython_dht_polling_sleep_time_seconds`
|
||||||
3
roles/pi_dhtsensor_circuitpython/defaults/main.yml
Normal file
3
roles/pi_dhtsensor_circuitpython/defaults/main.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
pi_dhtsensor_circuitpython_dht_pin: "D12"
|
||||||
|
pi_dhtsensor_circuitpython_dht_polling_sleep_time_seconds: 20
|
||||||
37
roles/pi_dhtsensor_circuitpython/tasks/main.yml
Normal file
37
roles/pi_dhtsensor_circuitpython/tasks/main.yml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
- name: Apt install libgpiod2
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: libgpiod2
|
||||||
|
cache_valid_time: "7200"
|
||||||
|
state: present
|
||||||
|
- name: Pip install adafruit-circuitpython-dht
|
||||||
|
ansible.builtin.pip:
|
||||||
|
name: adafruit-circuitpython-dht
|
||||||
|
executable: pip3
|
||||||
|
- name: Install script config
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: dht22_sensing.json
|
||||||
|
dest: /etc/dht22_sensing.json
|
||||||
|
mode: "0644"
|
||||||
|
- name: Install script
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: dht22_sensing.py
|
||||||
|
dest: /usr/bin/dht22_sensing
|
||||||
|
owner: root
|
||||||
|
mode: u+rwx
|
||||||
|
- name: Install systemd service file
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: dht22_sensing.service
|
||||||
|
dest: /lib/systemd/system/
|
||||||
|
mode: "0644"
|
||||||
|
- name: Add script to autostart and start now
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: dht22_sensing
|
||||||
|
state: started
|
||||||
|
enabled: "yes"
|
||||||
|
daemon_reload: "yes"
|
||||||
|
- name: Add to sysdweb
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: pi_sysdweb
|
||||||
|
vars:
|
||||||
|
pi_sysdweb_name: dht22_sensing
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"ha_url": "{{home_assistant_url}}",
|
"ha_url": "{{home_assistant_url}}",
|
||||||
"token": "{{home_assistant_token}}",
|
"token": "{{home_assistant_token}}",
|
||||||
"dht_pin": "{{dht_pin}}",
|
"dht_pin": "{{pi_dhtsensor_circuitpython_dht_pin}}",
|
||||||
"polling_sleep_time_seconds": "{{dht_polling_sleep_time_seconds}}",
|
"polling_sleep_time_seconds": "{{pi_dhtsensor_circuitpython_dht_polling_sleep_time_seconds}}",
|
||||||
|
|
||||||
"ha_temp_sensor_name": "{{sensor_room_name_ascii|lower}}_dht22_temperatur",
|
"ha_temp_sensor_name": "{{sensor_room_name_ascii|lower}}_dht22_temperatur",
|
||||||
"ha_temp_friendly_name": "{{sensor_room_name}} Temperatur",
|
"ha_temp_friendly_name": "{{sensor_room_name}} Temperatur",
|
||||||
4
roles/pi_disable_onboard_bluetooth/README.md
Normal file
4
roles/pi_disable_onboard_bluetooth/README.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# pi_disable_onboard_bluetooth
|
||||||
|
|
||||||
|
Disables the Pi's onboard Bluetooth radio via `dtoverlay=disable-bt` in the
|
||||||
|
boot config, for hosts that use an external BT/audio dongle instead.
|
||||||
3
roles/pi_disable_onboard_bluetooth/handlers/main.yml
Normal file
3
roles/pi_disable_onboard_bluetooth/handlers/main.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
- name: Reboot
|
||||||
|
ansible.builtin.reboot:
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
- name: Deactivate onboard bluetooth
|
- name: Deactivate onboard bluetooth
|
||||||
lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /boot/firmware/config.txt
|
path: /boot/firmware/config.txt
|
||||||
regexp: "^#?dtoverlay=disable-bt"
|
regexp: "^#?dtoverlay=disable-bt"
|
||||||
line: "dtoverlay=disable-bt"
|
line: "dtoverlay=disable-bt"
|
||||||
notify: reboot
|
notify: Reboot
|
||||||
6
roles/pi_hifiberry_amp/README.md
Normal file
6
roles/pi_hifiberry_amp/README.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# pi_hifiberry_amp
|
||||||
|
|
||||||
|
Deactivates the Pi's onboard analog audio and activates a HiFiBerry
|
||||||
|
amp/DAC overlay instead.
|
||||||
|
|
||||||
|
**Key vars:** `hifiberry_overlay`
|
||||||
3
roles/pi_hifiberry_amp/handlers/main.yml
Normal file
3
roles/pi_hifiberry_amp/handlers/main.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
- name: Reboot
|
||||||
|
ansible.builtin.reboot:
|
||||||
3
roles/pi_hifiberry_amp/meta/main.yml
Normal file
3
roles/pi_hifiberry_amp/meta/main.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- role: pi_alsasetup
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
---
|
---
|
||||||
- name: Deactivate normal audio
|
- name: Deactivate normal audio
|
||||||
lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /boot/config.txt
|
path: /boot/config.txt
|
||||||
regexp: "^#?dtparam=audio=on"
|
regexp: "^#?dtparam=audio=on"
|
||||||
line: "#dtparam=audio=on"
|
line: "#dtparam=audio=on"
|
||||||
notify: reboot
|
notify: Reboot
|
||||||
- name: Activate Hifiberry
|
- name: Activate Hifiberry
|
||||||
lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /boot/firmware/config.txt
|
path: /boot/firmware/config.txt
|
||||||
regexp: "^#?dtoverlay=hifiberry-amp"
|
regexp: "^#?dtoverlay=hifiberry-amp"
|
||||||
line: "dtoverlay={{hifiberry_overlay}}"
|
line: "dtoverlay={{ hifiberry_overlay }}"
|
||||||
notify: reboot
|
notify: Reboot
|
||||||
5
roles/pi_irserver/README.md
Normal file
5
roles/pi_irserver/README.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# pi_irserver
|
||||||
|
|
||||||
|
Installs and configures `irserver` (with a Hauppauge remote config) as an
|
||||||
|
autostarted systemd service for IR remote control, and registers it with
|
||||||
|
`pi_sysdweb`.
|
||||||
5
roles/pi_irserver/handlers/main.yml
Normal file
5
roles/pi_irserver/handlers/main.yml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
- name: Restart irserver
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: irserver
|
||||||
|
state: restarted
|
||||||
35
roles/pi_irserver/tasks/main.yml
Normal file
35
roles/pi_irserver/tasks/main.yml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
- name: Copy irserver
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: irserver
|
||||||
|
dest: /usr/bin/irserver
|
||||||
|
mode: u+rx
|
||||||
|
notify: Restart irserver
|
||||||
|
- name: Make config dir for remotes
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /usr/bin/remotes
|
||||||
|
state: directory
|
||||||
|
mode: "0755"
|
||||||
|
- name: Copy hauppauge remote
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: hauppauge.rem
|
||||||
|
dest: /usr/bin/remotes/
|
||||||
|
mode: "0644"
|
||||||
|
notify: Restart irserver
|
||||||
|
- name: Copy irserver systemd file
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: irserver.service
|
||||||
|
dest: /lib/systemd/system/
|
||||||
|
mode: "0644"
|
||||||
|
notify: Restart irserver
|
||||||
|
- name: Enable irserver autostart
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: irserver
|
||||||
|
state: started
|
||||||
|
enabled: "yes"
|
||||||
|
daemon_reload: "yes"
|
||||||
|
- name: Add irserver to sysdweb
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: pi_sysdweb
|
||||||
|
vars:
|
||||||
|
pi_sysdweb_name: irserver
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user