Compare commits

...

10 Commits

Author SHA1 Message Date
Martin Bauer 7501ef18a4 updates raspis to new os based on bookworm 2024-02-19 08:10:58 +01:00
Martin Bauer 7776095180 New server setup based on ubuntu 2023-09-19 10:55:47 +02:00
Martin Bauer 578be1a1cf updates 2023-01-03 20:07:56 +01:00
Martin Bauer 2a251d2700 Server scripts 2021-09-11 10:18:47 +02:00
Martin Bauer f1d104a224 Updates & fixes 2021-07-20 15:35:12 +02:00
Martin Bauer 6c421a4ae1 Octopi & dht fixes 2021-07-05 19:50:15 +02:00
Martin Bauer 23a2c1fb50 added ir server, squeeze server, ... 2020-05-16 18:35:44 +02:00
Martin Bauer 93034dd0ec Update dht22 sensing code + sispmctl fixes 2020-05-12 20:51:04 +02:00
Martin Bauer d8c9a491d1 Working sound setup for raspis 2020-05-10 15:25:38 +02:00
Martin Bauer caf6232dfb Added sysdweb 2020-05-02 11:21:52 +02:00
122 changed files with 2776 additions and 428 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
ve_*
/server/scripts/docker-images/tagspace/tagspaces
/server/scripts/docker-images/tagspace/*.zip
*.img
/music
__pycache__
/roles/pi-squeezeserver/backup

5
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"python.linting.pylintEnabled": false,
"python.linting.enabled": true,
"python.linting.flake8Enabled": true
}

49
full.yml Normal file
View File

@ -0,0 +1,49 @@
---
#- 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
#- hosts: bedroompi
# roles:
# - pi-standard-setup
# - pi-squeezelite-custom
# - pi-shairport
# - pi-lirc
# - pi-dhtsensor
#- hosts: octopi
# roles:
# - pi-dhtsensor
#- hosts: newrpi
# roles:
# - pi-standard-setup
# - pi-lirc

63
inventory.yml Normal file
View File

@ -0,0 +1,63 @@
all:
hosts:
server:
ansible_host: home.bauer.tech
ansible_port: 22187
server2:
children:
iot:
hosts:
octopi:
sensor_room_name_ascii: prusaprinter
sensor_room_name: prusaprinter
dht_pin: 26
bedroompi:
squeezelite_name: BedroomPi
shairport_name: BedroomPi
alsa_card_name: Codec
sensor_room_name_ascii: schlafzimmer
sensor_room_name: Schlafzimmer
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
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
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
musicmouse:
squeezelite_name: MusicMouse
shairport_name: MusicMouse
alsa_card_name: 0
hifiberry_overlay: hifiberry-dacplus
newrpi:
squeezelite_name: MyTestRaspberry
shairport_name: MyTestRaspberry
alsa_card_name: 0
sensor_room_name_ascii: testraum
sensor_room_name: Test Raum
heatingpi:
vars:
ansible_user: root
ansible_python_interpreter: /usr/bin/python3
squeezeserver: 192.168.178.80
router_ip: 192.168.178.1
home_assistant_url: https://ha.bauer.tech
home_assistant_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkM2QxYjAwYjkxZjY0MWVhYjA4YmZhMDYwYTg3YjRhNyIsImlhdCI6MTcwNDI3MDU5MSwiZXhwIjoyMDE5NjMwNTkxfQ.dzvejgEQd9hf-Yftzd7NkR5pv76GaLFczeOy-a2pa1o
configure_wifi: false
wifi_ssid: BauerWLAN

Binary file not shown.

View File

@ -2,7 +2,7 @@
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 from keepasshttplib import keepasshttplib, encrypter
import requests
DOCUMENTATION = """ DOCUMENTATION = """
lookup: keepass lookup: keepass
@ -39,12 +39,12 @@ class LookupModule(LookupBase):
else: else:
entry_path, entry_attr = terms[0], terms[1] entry_path, entry_attr = terms[0], terms[1]
if not self._test_connection(): #if not self._test_connection():
raise AnsibleError('Keepass is closed!') # raise AnsibleError('Keepass is closed!')
try: try:
auth = self.k.get_credentials(entry_path) auth = self.k.get_credentials(entry_path)
except Exception as e: except Exception as e:
raise AnsibleError('Keepass error obtaining entry {}: {}'.format(host_name, e)) raise AnsibleError('Keepass error obtaining entry {}: {}'.format(entry_path, e))
if auth: if auth:
if entry_attr not in ('username', 'user', 'pass', 'passwd', 'password'): if entry_attr not in ('username', 'user', 'pass', 'passwd', 'password'):
raise AnsibleError("Keepass wrong entry") raise AnsibleError("Keepass wrong entry")

8
newrpi-provisioning.yml Normal file
View File

@ -0,0 +1,8 @@
---
- hosts: musicmouse
roles:
- pi-standard-setup
- pi-hifiberry-amp
- pi-squeezelite
- pi-shairport
- pi-lirc

3
octopisetup.yml Normal file
View File

@ -0,0 +1,3 @@
- hosts: octopi
roles:
- pi-dhtsensor

View File

@ -1,96 +0,0 @@
# Run with
# ansible-playbook 01-download-and-prepare-raspi-image.yml
---
- hosts: 127.0.0.1
connection: local
gather_facts: false
vars:
target_folder: "/media/martin/data_linux/tmp/"
vars_prompt:
- name: "ansible_become_pass"
prompt: "Sudo password to mount raspi image"
- name: "new_hostname"
prompt: "New hostname for the PI"
private: no
tasks:
# --- Preparation ---
- name: Download Raspian image
get_url:
url: "https://downloads.raspberrypi.org/raspbian_lite_latest"
dest: "{{target_folder}}/raspian_lite_latest.zip"
- name: Unpack Image
unarchive:
src: "{{target_folder}}/raspian_lite_latest.zip"
dest: "{{target_folder}}"
creates: "{{target_folder}}/*raspbian*.img"
- name: Make Folders to mount to
file:
path: "{{item}}"
state: directory
with_items:
- "{{target_folder}}/mounted_raspi_image"
- "{{target_folder}}/mounted_raspi_image/boot"
- "{{target_folder}}/mounted_raspi_image/system"
- name: Setup Loopback
become: true
shell:
cmd: "losetup -P /dev/loop42 {{target_folder}}/*raspbian*.img"
creates: "/dev/loop42p1"
- name: Mount Boot Partition
become: true
shell:
warn: false
cmd: "mount /dev/loop42p1 {{target_folder}}/mounted_raspi_image/boot"
creates: "{{target_folder}}/mounted_raspi_image/boot/kernel.img"
- name: Mount System Partition
become: true
shell:
warn: false
cmd: "mount /dev/loop42p2 {{target_folder}}/mounted_raspi_image/system"
creates: "{{target_folder}}/mounted_raspi_image/system/bin"
# --- Actual work ---
- name: "Add SSH File to boot partition to allow for first remote login"
become: true
file:
path: "{{target_folder}}/mounted_raspi_image/boot/ssh"
state: touch
- name: "Writing new hostname to /etc/hostname"
become: true
copy:
content: "{{new_hostname}}"
dest: "{{target_folder}}/mounted_raspi_image/system/etc/hostname"
# --- Wind-down
- name: Unmount System Partition
become: true
shell:
warn: false
cmd: "umount /dev/loop42p2"
removes: "{{target_folder}}/mounted_raspi_image/system/bin"
- name: Unmount Boot Partition
become: true
shell:
warn: false
cmd: "umount /dev/loop42p1"
removes: "{{target_folder}}/mounted_raspi_image/boot/kernel.img"
- name: Tear down loop device
become: true
shell:
cmd: "losetup -d /dev/loop42"
removes: "/dev/loop42p1"
- name: Remove folders
file:
path: "{{item}}"
state: absent
with_items:
- "{{target_folder}}/mounted_raspi_image"
- "{{target_folder}}/mounted_raspi_image/boot"
- "{{target_folder}}/mounted_raspi_image/system"
- "{{target_folder}}/raspian_lite_latest.zip"
- name: Final Image
debug:
msg: |
The prepared image is ready at {{target_folder}}.
Copy it to sdcard with
dd bs=4M status=progress if=the_image of=/dev/your/sdcard
use e.g. /dev/sdb not /dev/sdb1 !

View File

@ -1,109 +0,0 @@
# Run with
# ansible-playbook -i raspberrypi, 02-provision_new_pi.yml
# where "raspberrypi" is the hostname of the pi
---
- hosts: kitchenpi
gather_facts: false
vars:
timezone: "Europe/Berlin"
wifi_country: "DE"
wifi_ssid: "" # put SSID here to configure wifi
wifi_pass_url: "bauer_wifi" # has to be in keepass with url "wifi_pass_url"
ansible_ssh_pass: raspberry
ansible_become: yes
ansible_become_password: raspberry
new_hostname: "" # set this to change the hostname
vars_prompt:
- name: ansible_user
prompt: "User to connect with, put in 'pi' here if you connect the first time, else leave empty"
default: root
tasks:
- 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', '../public_keys/martin_laptop.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 to {{ new_hostname }}
command: "raspi-config nonint do_hostname {{ new_hostname }}"
when: new_hostname | bool and pi_hostname.stdout != new_hostname
- 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
cache_valid_time: 7200
state: present
- name: Copy vim config
copy: src=../configs/vimrc dest=/root/.vimrc
- name: Copy git config
copy: src=../configs/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 }}"
- name: Set WiFi credentials
command: "raspi-config nonint do_wifi_ssid_passphrase {{ wifi_ssid }} {{ lookup('keepass', wifi_pass_url) }}"
when: wifi_ssid | bool
# Message of the day
- name: Set Message of the day
copy: src=configs/motd/{{ inventory_hostname }} dest=/etc/motd
#- name: Remove motd tail
# copy: dest=/etc/motd.
# LED off script
- name: Copy led off script
copy: src=configs/raspi-leds-off.sh dest=/usr/sbin/raspi-leds-off.sh mode="u+rwx"
- name: Copy led off service
copy: src=configs/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
handlers:
- name: restart sshd
service:
name: sshd
state: restarted

View File

@ -1,44 +0,0 @@
# Install instructions taken from
# https://github.com/mikebrady/shairport-sync/blob/master/INSTALL.md
---
- hosts: kitchenpi
gather_facts: false
vars:
shairport_sync_version: "3.3.5"
remote_user: root
tasks:
- name: Apt install dependencies
apt:
cache_valid_time: 7200
state: present
name:
- build-essential
- git
- xmltoman
- autoconf
- automake
- libtool
- libpopt-dev
- libconfig-dev
- libasound2-dev
- avahi-daemon
- libavahi-client-dev
- libssl-dev
- libsoxr-dev
- name: Build and Install Shairport sync (may take a while)
script: "scripts/build-shairport-sync.sh ${shairport_sync_version}"
args:
creates: /usr/local/bin/shairport-sync
- name: Copy config
template: src=configs/shairport-sync.conf dest=/etc/shairport-sync.conf
- name: Sync alsa config
template: src=configs/asound.conf dest=/etc/asound.conf
- name: Modify service file to run as root
lineinfile:
path: /lib/systemd/system/shairport-sync.service
regexp: "^#?User="
line: "User=root"
- name: Restart shairport-sync
systemd: name=shairport-sync state=restarted enabled=yes daemon_reload=yes

View File

@ -1,14 +0,0 @@
---
- hosts: kitchenpi
gather_facts: false
remote_user: root
tasks:
- name: Apt install squeezelite package
apt: name=squeezelite cache_valid_time=7200 state=present
- name: Install config file
template: src=configs/squeezelite.cfg dest=/etc/default/squeezelite
- name: Sync alsa config
template: src=configs/asound.conf dest=/etc/asound.conf
- name: Restart squeezelite
systemd: name=squeezelite state=restarted enabled=yes daemon_reload=yes

View File

@ -1,49 +0,0 @@
---
# lirc needs to be custom compiled on this kernel
# https://gist.github.com/billpatrianakos/cb72e984d4730043fe79cbe5fc8f7941
- hosts: kitchenpi
gather_facts: false
remote_user: root
tasks:
#- name: Apt install lirc package
# apt: name=lirc cache_valid_time=7200 state=present
# ignore_errors: yes
- name: Install config file lirc_options.conf
copy: src=configs/lirc/lirc_options.conf dest=/etc/lirc/lirc_options.conf
- name: Install config file lircd.conf
copy: src=configs/lirc/lircd.conf dest=/etc/lirc/lircd.conf
- name: Install remote file
copy: src=configs/lirc/hauppauge.conf dest=/etc/lirc/hauppauge.conf
- name: create temporary directory
tempfile:
state: directory
suffix: temp
register: tempdir
- name: Copy over lirc customly compiled lirc packages
copy:
src: configs/lirc/debs/
dest: "{{ tempdir.path }}"
when: tempdir.path is defined
- name: Install custom lirc package 1
apt:
deb: "{{ tempdir.path }}/liblirc0_0.10.1-5.2_armhf.deb"
when: tempdir.path is defined
- name: Install custom lirc package 2
apt:
deb: "{{ tempdir.path }}/liblircclient0_0.10.1-5.2_armhf.deb"
when: tempdir.path is defined
- name: Install custom lirc package 3
apt:
deb: "{{ tempdir.path }}/lirc_0.10.1-5.2_armhf.deb"
when: tempdir.path is defined
- name: Activate overlay in boot config
lineinfile:
path: /boot/config.txt
regexp: "^#?dtoverlay=gpio-ir"
line: "dtoverlay=gpio-ir,gpio_pin=17"
register: boot_overlay
- name: Restart lircd
systemd: name=lircd state=restarted enabled=yes daemon_reload=yes
- name: Reboot if boot overlay changed
reboot:
when: boot_overlay.changed

View File

@ -1,27 +0,0 @@
---
- hosts: newrpi
gather_facts: false
remote_user: root
tasks:
- name: Deactivate normal audio
lineinfile:
path: /boot/config.txt
regexp: "^#?dtparam=audio=on"
line: "#dtparam=audio=on"
register: boot_overlay1
- name: Activate Hifiberry
lineinfile:
path: /boot/config.txt
regexp: "^#?dtoverlay=hifiberry-amp"
line: "dtoverlay=hifiberry-amp"
register: boot_overlay2
#- name: Reboot if boot overlay changed
# reboot:
# when: boot_overlay1.changed or boot_overlay2.changed
## State in /boot/config.txt
# dtoverlay=hifiberry-amp
# # remove old:
# #dtparam=audio=on

View File

@ -1,20 +0,0 @@
---
- hosts: kitchenpi
gather_facts: false
remote_user: root
tasks:
- 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=configs/dht22_sensing.json dest=/etc/dht22_sensing.json
- name: Install script
copy: src=configs/dht22_sensing.py dest=/usr/bin/dht22_sensing owner=root mode=u+rwx
- name: Install systemd service file
copy: src=configs/dht22_sensing.service dest=/lib/systemd/system/
- name: Add script to autostart and start now
systemd: name=dht22_sensing state=restarted enabled=yes daemon_reload=yes

View File

@ -1,26 +0,0 @@
all:
hosts:
server:
ansible_host: home.bauer.tech
ansible_port: 22187
children:
iot:
hosts:
newrpi:
squeezelite_name: MyTestRaspberry
shairport_name: MyTestRaspberry
alsa_card_name: 0
sensor_room_name_ascii: testraum
sensor_room_name: Test Raum
heatingpi:
bedroompi:
kitchenpi:
squeezelite_name: KitchenPi
shairport_name: KitchenPi
alsa_card_name: 0
sensor_room_name_ascii: kueche
sensor_room_name: Küche
vars:
ansible_python_interpreter: /usr/bin/python3

View File

@ -1,2 +0,0 @@
/etc/modules
-> bedroompi: snd-bcm2835

View File

@ -1,24 +0,0 @@
# -*- coding: utf-8 -*-
import requests
key = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIxNjkxMWIzZmQ4ZWU0NDI0OTg0MjA0ZDllMDhkNGRlMCIsImlhdCI6MTU3ODE3MDU5MSwiZXhwIjoxODkzNTMwNTkxfQ.i7CdXEZy9DV9KPHAl-msK0rOfIUlPYo4zwwJ4UGhXuc"
url = "https://ha.bauer.tech"
headers = {
'x-ha-access': key,
'Authorization': "Bearer {}".format(key)
}
apiurl = url + "/api/states/sensor.schlafzimmer_temperatur"
data = {
"state": "19",
"attributes": {
"device_class": "temperature",
"friendly_name": "Schlafzimmer Temperatur",
"unit_of_measurement": "°C"
}
}
r = requests.post(apiurl, json=data, headers=headers)
print(r)

View File

@ -0,0 +1,23 @@
import asyncio
from bleak import BleakScanner
async def main():
stop_event = asyncio.Event()
# TODO: add something that calls stop_event.set()
def callback(device, advertising_data):
print("device", device.address, "advertising_data", advertising_data)
# TODO: do something with incoming data
pass
async with BleakScanner(callback, scanning_mode="active") as scanner:
# Important! Wait for an event to trigger stop, otherwise scanner
# will stop immediately.
await stop_event.wait()
# scanner stops when block exits
...
asyncio.run(main())

View File

@ -0,0 +1,38 @@
import asyncio
import logging
from bleak import BleakClient, BleakScanner
from bleak.assigned_numbers import AdvertisementDataType
from bleak.backends.bluezdbus.advertisement_monitor import OrPattern
from bleak.backends.bluezdbus.scanner import BlueZScannerArgs
async def scan():
args = BlueZScannerArgs(
or_patterns=[OrPattern(0, AdvertisementDataType.MANUFACTURER_SPECIFIC_DATA, b"\x10\x05")]
)
async with BleakScanner(bluez=args, scanning_mode="passive") as scanner:
async for _, advertisement_data in scanner.advertisement_data():
mfr_data = advertisement_data.manufacturer_data
if mfr_data.get(0x02e1):
logging.info("scan(): found correct device: %s", mfr_data)
else:
logging.info("scan(): this should never happen: %s", mfr_data)
async def connect():
device1 = await BleakScanner.find_device_by_address("01:B6:EC:10:CB:8F")
async with BleakClient(device1):
logging.info("connect(): connected to device")
await asyncio.sleep(60)
async def main():
logging.info("main(): starting scan")
asyncio.create_task(scan())
await asyncio.sleep(30)
logging.basicConfig(
level=logging.INFO,
format="%(asctime)-15s %(name)-8s %(levelname)s: %(message)s",
)
asyncio.run(main())

View File

@ -0,0 +1,92 @@
import asyncio
from bleak import BleakScanner
from bleak.assigned_numbers import AdvertisementDataType
from bleak.backends.bluezdbus.advertisement_monitor import OrPattern
from bleak.backends.bluezdbus.scanner import BlueZScannerArgs
from Crypto.Cipher import AES
from typing import Dict
irks = {
"aa67542b82c0e05d65c27fb7e313aba5": "martins_apple_watch",
"840e3892644c1ebd1594a9069c14ce0d" : "martins_iphone",
}
def resolve_rpa(rpa: bytes, irk: bytes) -> bool:
"""Compares the random address rpa to an irk (secret key) and return True if it matches"""
assert len(rpa) == 6
assert len(irk) == 16
key = irk
plain_text = b'\x00' * 16
plain_text = bytearray(plain_text)
plain_text[15] = rpa[3]
plain_text[14] = rpa[4]
plain_text[13] = rpa[5]
plain_text = bytes(plain_text)
cipher = AES.new(key, AES.MODE_ECB)
cipher_text = cipher.encrypt(plain_text)
return cipher_text[15] == rpa[0] and cipher_text[14] == rpa[1] and cipher_text[13] == rpa[2]
def addr_to_bytes(addr:str) -> bytes:
"""Converts a bluetooth mac address string with semicolons to bytes"""
str_without_colons = addr.replace(":", "")
bytearr = bytearray.fromhex(str_without_colons)
bytearr.reverse()
return bytes(bytearr)
def decode_address(addr: str, irks: Dict[str, str]):
"""
addr is a bluetooth address as a string e.g. 4d:24:12:12:34:10
irks is dict with irk as a hex string, mapping to device name
"""
for irk, name in irks.items():
if resolve_rpa(addr_to_bytes(addr), bytes.fromhex(irk)):
return name
return None
def estimate_distance(rssi, tx_power, pl0=54):
"""
RSSI in dBm
txPower is a transmitter parameter that calculated according to its physic layer and antenna in dBm
Return value in meter
You should calculate "PL0" in calibration stage:
PL0 = txPower - RSSI; // When distance is distance0 (distance0 = 1m or more)
SO, RSSI will be calculated by below formula:
RSSI = txPower - PL0 - 10 * n * log(distance/distance0) - G(t)
G(t) ~= 0 //This parameter is the main challenge in achiving to more accuracy.
n = 2 (Path Loss Exponent, in the free space is 2)
distance0 = 1 (m)
distance = 10 ^ ((txPower - RSSI - PL0 ) / (10 * n))
Read more details:
https://en.wikipedia.org/wiki/Log-distance_path_loss_model
"""
n = 2.7
return 10**(( tx_power - rssi - pl0) / (10 * n))
def callback(device, advertising_data):
print(device.address)
decoded = decode_address(device.address, irks)
if decoded:
print(f"{decoded} @ {advertising_data.rssi} distance {estimate_distance(advertising_data.rssi, advertising_data.tx_power)}")
async def main():
# Scan for
args = BlueZScannerArgs(
or_patterns=[OrPattern(0, AdvertisementDataType.MANUFACTURER_SPECIFIC_DATA, b"\x10\x05")]
)
stop_event = asyncio.Event()
#async with BleakScanner(bluez=args, scanning_mode="passive") as scanner:
async with BleakScanner(callback) as scanner:
await stop_event.wait()
asyncio.run(main())

View File

@ -0,0 +1,10 @@
import asyncio
from bleak import BleakScanner
async def main():
devices = await BleakScanner.discover()
while True:
for d in devices:
print(d)
asyncio.run(main())

View File

@ -0,0 +1,58 @@
"""Scan for iBeacons.
Copyright (c) 2022 Koen Vervloesem
SPDX-License-Identifier: MIT
"""
import asyncio
from uuid import UUID
from construct import Array, Byte, Const, Int8sl, Int16ub, Struct
from construct.core import ConstError
from bleak import BleakScanner
from bleak.backends.device import BLEDevice
from bleak.backends.scanner import AdvertisementData
ibeacon_format = Struct(
"type_length" / Const(b"\x02\x15"),
"uuid" / Array(16, Byte),
"major" / Int16ub,
"minor" / Int16ub,
"power" / Int8sl,
)
def device_found(
device: BLEDevice, advertisement_data: AdvertisementData
):
"""Decode iBeacon."""
try:
apple_data = advertisement_data.manufacturer_data[0x004C]
print("apple data", apple_data)
ibeacon = ibeacon_format.parse(apple_data)
uuid = UUID(bytes=bytes(ibeacon.uuid))
print(f"UUID : {uuid}")
print(f"Major : {ibeacon.major}")
print(f"Minor : {ibeacon.minor}")
print(f"TX power : {ibeacon.power} dBm")
print(f"RSSI : {device.rssi} dBm")
print(47 * "-")
except KeyError:
# Apple company ID (0x004c) not found
pass
except ConstError:
# No iBeacon (type 0x02 and length 0x15)
pass
async def main():
"""Scan for devices."""
scanner = BleakScanner()
scanner.register_detection_callback(device_found)
while True:
await scanner.start()
await asyncio.sleep(1.0)
await scanner.stop()
asyncio.run(main())

View File

@ -0,0 +1,3 @@
devices:
martins_iphone: 840e3892644c1ebd1594a9069c14ce0d
martins_apple_watch: aa67542b82c0e05d65c27fb7e313aba5

View File

@ -0,0 +1,8 @@
- name: Apt install bluez and firmware
apt:
name:
- bluez
- bluez-firmware
- firmware-realtek
- firmware-realtek-rtl8723cs-bt

View File

@ -0,0 +1,3 @@
---
- name: Sync alsa config
template: src=asound.conf dest=/etc/asound.conf

View File

@ -0,0 +1,36 @@
---
- name: Install packages
apt:
name:
- bat
- fish
- fzf
- fd-find
- ripgrep
- lsd
- zoxide
- name: Check if oh-my-fish is installed
stat:
path: '/etc/omf.installed'
register: omf
- name: Download omf installer
get_url:
url: https://raw.githubusercontent.com/oh-my-fish/oh-my-fish/master/bin/install
- name: Execute omf installer
shell: /usr/bin/fish /tmp/install --noninteractive
- name: Execute omf installer
shell: /usr/bin/fish -c omf install
- name: Remove the omf installer
file:
path: /tmp/install
state: absent
- name: Mark oh-my-fish installed with /etc/omf.installed
file:
path: /etc/omf.installed
state: touch

View File

@ -0,0 +1,3 @@
---
dht_pin: "D12"
dht_polling_sleep_time_seconds: 20

View File

@ -4,20 +4,21 @@
import requests import requests
import json import json
import time import time
import board import multiprocessing
import adafruit_dht
config = json.load(open("/etc/dht22_sensing.json")) config = json.load(open("/etc/dht22_sensing.json"))
dht_device = adafruit_dht.DHT22(getattr(board, config['dht_pin']))
def send_to_home_assistant(temperature, humidity): def send_to_home_assistant(temperature, humidity):
# print(f"Sending temperature {temperature}, humidity {humidity}")
headers = { headers = {
'x-ha-access': config['token'], 'x-ha-access': config['token'],
'Authorization': "Bearer {}".format(config['token']) 'Authorization': "Bearer {}".format(config['token'])
} }
temperature_url = "{}/api/states/sensor.{}".format(config['ha_url'], config['ha_temp_sensor_name']) temperature_url = "{}/api/states/sensor.{}".format(
config['ha_url'], config['ha_temp_sensor_name'])
temperatur_data = { temperatur_data = {
"state": str(temperature), "state": str(temperature),
"attributes": { "attributes": {
@ -28,7 +29,8 @@ def send_to_home_assistant(temperature, humidity):
} }
requests.post(temperature_url, json=temperatur_data, headers=headers) requests.post(temperature_url, json=temperatur_data, headers=headers)
humidity_url = "{}/api/states/sensor.{}".format(config['ha_url'], config['ha_humidity_sensor_name']) humidity_url = "{}/api/states/sensor.{}".format(
config['ha_url'], config['ha_humidity_sensor_name'])
humidity_data = { humidity_data = {
"state": str(humidity), "state": str(humidity),
"attributes": { "attributes": {
@ -41,13 +43,22 @@ def send_to_home_assistant(temperature, humidity):
def sense(): def sense():
import adafruit_dht
import board
dht_device = adafruit_dht.DHT22(getattr(board, config['dht_pin']))
try: try:
send_to_home_assistant(dht_device.temperature, dht_device.humidity) send_to_home_assistant(dht_device.temperature, dht_device.humidity)
except RuntimeError as error: except RuntimeError as error:
# Errors happen fairly often, DHT's are hard to read, just keep going # Errors happen fairly often, DHT's are hard to read, just keep going
print(error.args[0]) print(error.args[0])
time.sleep(config['polling_sleep_time_seconds'])
if __name__ == "__main__":
multiprocessing.set_start_method('spawn')
while True: while True:
sense() process = multiprocessing.Process(target=sense)
process.start()
process.join()
time.sleep(float(config['polling_sleep_time_seconds']))

View File

@ -0,0 +1,20 @@
---
- 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

View File

@ -1,8 +1,8 @@
{ {
"ha_url": "https://ha.bauer.tech", "ha_url": "{{home_assistant_url}}",
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIxNjkxMWIzZmQ4ZWU0NDI0OTg0MjA0ZDllMDhkNGRlMCIsImlhdCI6MTU3ODE3MDU5MSwiZXhwIjoxODkzNTMwNTkxfQ.i7CdXEZy9DV9KPHAl-msK0rOfIUlPYo4zwwJ4UGhXuc", "token": "{{home_assistant_token}}",
"dht_pin": "D12", "dht_pin": "{{dht_pin}}",
"polling_sleep_time_seconds": 5, "polling_sleep_time_seconds": "{{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",

Binary file not shown.

View File

@ -0,0 +1,3 @@
---
dht_pin: 12
dht_polling_sleep_time_seconds: 20

View File

@ -0,0 +1,93 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import requests
import json
import time
import Adafruit_DHT
config = json.load(open("/etc/dht22_sensing.json"))
class Filter:
def __init__(self, filter_length, max_mean_deviation):
self._length = filter_length
self.values = []
self.max_mean_deviation = max_mean_deviation
def mean(self):
return sum(self.values) / len(self.values)
def is_valid_value(self, val):
if len(self.values) == 0:
return True
else:
return abs(val - self.mean()) < self.max_mean_deviation
def add_if_valid(self, val):
if val is None:
return False
if self.is_valid_value(val):
self.values.append(val)
if len(self.values) > self._length:
self.values.pop(0)
return True
else:
return False
def send_to_home_assistant(temperature, humidity):
# print(f"Sending temperature {temperature}, humidity {humidity}")
headers = {
'x-ha-access': config['token'],
'Authorization': "Bearer {}".format(config['token'])
}
temperature_url = "{}/api/states/sensor.{}".format(
config['ha_url'], config['ha_temp_sensor_name'])
temperatur_data = {
"state": "{:.1f}".format(temperature),
"attributes": {
"device_class": "temperature",
"friendly_name": config['ha_temp_friendly_name'],
"unit_of_measurement": "°C"
}
}
requests.post(temperature_url, json=temperatur_data, headers=headers)
humidity_url = "{}/api/states/sensor.{}".format(
config['ha_url'], config['ha_humidity_sensor_name'])
humidity_data = {
"state": "{:.1f}".format(humidity),
"attributes": {
"device_class": "humidity",
"friendly_name": config['ha_humidity_friendly_name'],
"unit_of_measurement": "%"
}
}
requests.post(humidity_url, json=humidity_data, headers=headers)
if __name__ == "__main__":
temp_filter = Filter(4, 10)
humidity_filter = Filter(4, 10)
while True:
sensor = Adafruit_DHT.DHT22
humidity, temperature = Adafruit_DHT.read_retry(
sensor, config['dht_pin'])
temp_valid = temp_filter.add_if_valid(temperature)
humidity_valid = humidity_filter.add_if_valid(humidity)
if not (temp_valid and humidity_valid):
print(
f"Discarding value {temperature}C / {humidity}%, because to far from means {temp_filter.mean()}C, {humidity_filter.mean()}%")
else:
try:
send_to_home_assistant(temperature, humidity)
except Exception as e:
print("Failed sending to home assistant")
print(e)
time.sleep(float(config['polling_sleep_time_seconds']))

View File

@ -0,0 +1,10 @@
[Unit]
Description=DHT22 Temperature Humidity Sensing
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/dht22_sensing
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,31 @@
---
# 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

View File

@ -0,0 +1,12 @@
{
"ha_url": "{{home_assistant_url}}",
"token": "{{home_assistant_token}}",
"dht_pin": "{{dht_pin}}",
"polling_sleep_time_seconds": "{{dht_polling_sleep_time_seconds}}",
"ha_temp_sensor_name": "{{sensor_room_name_ascii|lower}}_dht22_temperatur",
"ha_temp_friendly_name": "{{sensor_room_name}} Temperatur",
"ha_humidity_sensor_name": "{{sensor_room_name_ascii|lower}}_dht22_luftfeuchtigkeit",
"ha_humidity_friendly_name": "{{sensor_room_name}} Luftfeuchtigkeit"
}

View File

@ -0,0 +1,4 @@
---
- name: reboot
reboot:

View File

@ -0,0 +1,3 @@
---
dependencies:
- role: pi-alsasetup

View File

@ -0,0 +1,13 @@
---
- name: Deactivate normal audio
lineinfile:
path: /boot/config.txt
regexp: "^#?dtparam=audio=on"
line: "#dtparam=audio=on"
notify: reboot
- name: Activate Hifiberry
lineinfile:
path: /boot/firmware/config.txt
regexp: "^#?dtoverlay=hifiberry-amp"
line: "dtoverlay={{hifiberry_overlay}}"
notify: reboot

View File

@ -0,0 +1,53 @@
[REMOTE]
[NAME]hauppauge
[TIMING]
[0][N]0[RC]2[RP]87[FREQ]36[RC5]
[COMMANDS]
[BTN_1][T]0[D]11011110000001
[BTN_2][T]0[D]11011110000010
[BTN_3][T]0[D]11011110000011
[BTN_4][T]0[D]11011110000100
[BTN_5][T]0[D]11011110000101
[BTN_6][T]0[D]11011110000110
[BTN_7][T]0[D]11011110000111
[BTN_8][T]0[D]11011110001000
[BTN_9][T]0[D]11011110001001
[BTN_0][T]0[D]11011110000000
[KEY_NUMERIC_STAR][T]0[D]11011110001010
[KEY_NUMERIC_POUND][T]0[D]11011110001110
[KEY_RED][T]0[D]11011110001011
[KEY_GREEN][T]0[D]11011110101110
[KEY_YELLOW][T]0[D]11011110111000
[KEY_BLUE][T]0[D]11011110101001
[KEY_PLAY][T]0[D]11011110110101
[KEY_PAUSE][T]0[D]11011110110000
[KEY_RECORD][T]0[D]11011110110111
[KEY_PREVIOUS][T]0[D]11011110110010
[KEY_FORWARD][T]0[D]11011110110100
[KEY_REWIND][T]0[D]11011110100100
[KEY_FASTFORWARD][T]0[D]11011110011110
[KEY_VOLUMEUP][T]0[D]11011110010000
[KEY_VOLUMEDOWN][T]0[D]11011110010001
[KEY_CHANNELUP][T]0[D]11011110100000
[KEY_CHANNELDOWN][T]0[D]11011110100001
[KEY_MUTE][T]0[D]11011110001111
[KEY_CHANNEL][T]0[D]11011110010010
[KEY_EXIT][T]0[D]11011110011111
[KEY_MENU][T]0[D]11011110001101
[KEY_LEFT][T]0[D]11011110010110
[KEY_RIGHT][T]0[D]11011110010111
[KEY_UP][T]0[D]11011110010100
[KEY_DOWN][T]0[D]11011110010101
[KEY_OK][T]0[D]11011110100101
[KEY_POWER][T]0[D]11011110111101
[KEY_GOTO][T]0[D]11011110111011
[KEY_TV][T]0[D]11011110011100
[KEY_VIDEOS][T]0[D]11011110011000
[KEY_MUSIC][T]0[D]11011110011001
[KEY_PICTURES][T]0[D]11011110011010
[KEY_GUIDE][T]0[D]11011110011011
[KEY_RADIO][T]0[D]11011110001100
[KEY_STOP][T]0[D]11011110110110

BIN
roles/pi-irserver/files/irserver Executable file

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,9 @@
downloaded from
http://www.irtrans.de/de/download/linux.php
build on raspberry pi using
make arm_noccfgcc
-> linker errors with libzip
-> installed libzip-dev and added lzip to linker parameters

View File

@ -0,0 +1,10 @@
[Unit]
Description=IR server for IR remotes
After=multi-user.target
[Service]
Type=simple
ExecStart=/usr/bin/irserver /dev/ttyUSB0
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,16 @@
---
- 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

32
roles/pi-knxd/README Normal file
View File

@ -0,0 +1,32 @@
Infos zum Stick
http://busware.de/tiki-index.php?page=TUL
Blog mit Tutorial:
https://www.meintechblog.de/2018/07/tul-stick-als-knx-ip-gateway-auf-dem-raspberry-pi-einrichten-mit-knxd/
Programmieren
--------------
apt-get -y install dfu-programmer
Beim Einstecken des Sticks programmiertaste auf unterseite gedrueckt halten
sudo dfu-programmer atmega32u4 erase && sudo dfu-programmer atmega32u4 flash TPUARTtransparent.hex && sudo dfu-programmer atmega32u4 reset && sudo reboot
udev-rules
----------
udevadm info -a -n /dev/ttyACM0 | grep '{idProduct}' | head -n1
udevadm info -a -n /dev/ttyACM0 | grep '{idVendor}' | head -n1
udevadm info -a -n /dev/ttyACM0 | grep '{serial}' | head -n1
# my KNX stick
SUBSYSTEM=="tty", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="204b", ATTRS{serial}=="8543934393935171A0B1", SYMLINK+="ttyKNX"
# z-wave stick
SUBSYSTEM=="tty", ATTRS{idVendor}=="0658", ATTRS{idProduct}=="0200", SYMLINK+="ttyZWave"
# HomeMatic stick (for fhem)
SUBSYSTEM=="tty", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="204b", ATTRS{product}=="CUL868", SYMLINK+="ttyHomeMatic"

View File

@ -0,0 +1,255 @@
:1000000093C00000ACC00000AAC00000A8C000005F
:10001000A6C00000A4C00000A2C00000A0C0000054
:100020009EC000009CC0000008C40000CBC30000BC
:1000300096C0000094C0000092C0000090C0000074
:100040008EC000008CC000008AC0000088C0000084
:1000500086C0000084C0000082C0000080C0000094
:100060007EC0000081C000007AC0000078C000009F
:1000700076C0000074C0000072C0000070C00000B4
:100080006EC000006CC000006AC0000068C00000C4
:1000900066C0000064C0000062C0000060C00000D4
:1000A0005EC000005CC000005AC0000012011001D8
:1000B00002000008EB034B2001000102DC010902F1
:1000C0003E00020100C032090400000102020100EA
:1000D000052400100104240206052406000107057A
:1000E00082030800FF09040100020A00000007055E
:1000F0000402100001070583021000010403090433
:1001000018036200750073007700610072006500DB
:100110002E006400650000003003540050005500BC
:10012000410052005400000011241FBECFEFDAE05E
:10013000DEBFCDBF11E0A0E0B1E0E8EBFFE002C020
:1001400005900D92AC31B107D9F712E0ACE1B1E006
:1001500001C01D92A034B107E1F76FD02BC750CF7B
:1001600088980895889808951F920F920FB60F925D
:1001700011242F933F938F939F93CF93DF93EF930C
:10018000FF939091CE008EB38430D9F4C8EAD1E0C9
:10019000E881F98190838881998101969983888388
:1001A0002E813F818217930721F48C819D81998351
:1001B00088832FB7F8948A859B8501969B878A87C9
:1001C0002FBFFF91EF91DF91CF919F918F913F9141
:1001D0002F910F900FBE0F901F901895089580E0FB
:1001E00091E03CC680E091E012C684B7877F84BF6F
:1001F00088E10FB6F89480936000109260000FBE03
:1002000080E090E020E80FB6F8942093610080939E
:1002100061000FBE809A8898B8D287E690E09093EC
:10022000CD008093CC0086E28093CA0082E0809368
:10023000C80088E98093C9000895EF92FF920F9358
:100240001F93CF93DF93D1DFECE1F1E02FB7F89468
:1002500088E291E091838083938382839583848372
:1002600088EA91E09783868380E890E09187808791
:10027000138612862FBFE8EAF1E02FB7F89484EBDB
:1002800091E091838083938382839583848384E345
:1002900092E09783868380E890E091878087138639
:1002A00012862FBF889878940CE111E088EAE82E36
:1002B00081E0F82E8EB391B39E7F20E0843009F464
:1002C00021E0922B91BB8FB7F894209126013091B9
:1002D00027018FBF809124019091250128173907AC
:1002E00001F180E091E0E8D497FD1BC08898E80117
:1002F000E881F98180838881998101969983888337
:100300002E813F818217930721F48C819D819983EF
:1003100088832FB7F8948A859B8501969B878A8767
:100320002FBF8FB7F894C091B201D091B3018FBFA6
:10033000209721F18898E091AA01F091AB0180E02B
:1003400091E060813FD58823C9F4F70182819381D0
:10035000019693838283268137818217930721F444
:1003600084819581938382832FB7F89482859385C6
:100370000197938782872FBF2197E9F62FB7F894CB
:1003800080912601909127012FBF892BF1F0889849
:10039000E801EA81FB813191FB83EA838E819F81B1
:1003A000E817F90721F48C819D819B838A832FB7FD
:1003B000F8948A859B8501979B878A872FBF8091B8
:1003C000C80085FFFCCF3093CE0080E091E0E3D4FD
:1003D0005FD470CFDA01923049F0933061F0913000
:1003E000F9F4ECEAF0E022E130E01EC0EEEBF0E0E0
:1003F0002EE330E019C0813049F0813018F08230AE
:1004000079F408C0ECEFF0E0849107C0E0E0F1E09F
:10041000849103C0E8E1F1E08491282F30E004C02A
:10042000E0E0F0E020E030E0ED93FC93C9010895B6
:100430009C0140913E0250913F024617570718F425
:10044000F90190E044C06115710511F0AB01F8CFDE
:100450008091E8008E778093E80040E050E0F0CF94
:100460008EB3882309F444C0853009F443C08091D9
:10047000E80083FF02C081E008958091E80082FDDA
:1004800031C08091E80080FF22C08091F3009091FC
:10049000F200782F60E0292F30E0262B372B07C0A1
:1004A00081918093F100415050402F5F3F4F4115A3
:1004B000510519F02830310598F390E028303105C6
:1004C00009F491E08091E8008E778093E80041156F
:1004D000510531F6992321F605C08EB3882341F0EA
:1004E000853041F08091E80082FFF7CF80E00895E9
:1004F00082E0089583E008959C0140913E0250916E
:100500003F024617570718F4F90190E045C06115FE
:10051000710511F0AB01F8CF8091E8008E778093E0
:10052000E80040E050E0F0CF8EB3882309F446C0E5
:10053000853009F445C08091E80083FF02C081E066
:1005400008958091E80082FD33C08091E80080FF2B
:1005500023C08091F3009091F200782F60E0292F62
:1005600030E0262B372B08C084918093F100319620
:10057000415050402F5F3F4F4115510519F0283031
:10058000310590F390E02830310509F491E0809135
:10059000E8008E778093E8004115510529F69923EC
:1005A00009F0C2CF05C08EB3882341F0853041F0F9
:1005B0008091E80082FFF7CF80E0089582E00895FF
:1005C00083E008958F708093E9008091EB00816053
:1005D0008093EB001092ED006093EC004093ED00EF
:1005E0008091EE00881F8827881F08950F931F931E
:1005F000CF93DF93062FEC0110E02AC09881992356
:1006000029F16B81E981FA812C81892F8F708730E4
:1006100018F5223010F452E001C056E040E028E026
:1006200030E003C04F5F220F331F2E173F07D0F378
:100630006295660F660F607C991F9927991F692B39
:100640004295407F452BBEDF882331F01F5F259602
:100650001017A0F281E001C080E0DF91CF911F91DF
:100660000F9108958091380288238CF403C08EB3D3
:100670008823B1F08091E80082FFF9CF8091E800F3
:100680008B778093E80008958EB3882349F080919A
:10069000E80080FFF9CF8091E8008E778093E80032
:1006A00008954091E4005091E50024E68091EC002B
:1006B00080FF23C08091E80080FD1DC08EB3882399
:1006C00011F482E00895853011F483E0089580915B
:1006D000EB0085FF02C081E008958091E4009091D5
:1006E000E5008417950711F3222311F484E008959F
:1006F0002150AC01DBCF80E008958091E80082FFBB
:10070000DDCFF9CFEF92FF920F931F934ED055D0CC
:1007100008ED10E0F80180818F7780838081806808
:10072000808380818F7D808319BC1EBA1092340231
:10073000109236021092350280EEE82EF12CF7016D
:1007400080818B7F8083F80180818160808380E05D
:1007500060E042E037DFE1EEF0E080818E7F808371
:10076000E2EEF0E080818160808380818860808318
:10077000F70180818E7F8083F80180818061808392
:100780001F910F91FF90EF900895E8EDF0E08081C8
:100790008F7E8083E7EDF0E080818160808384E05C
:1007A00082BF81E080933702ADCFE8EDF0E0808139
:1007B0008E7F80831092E20008951092DA001092EA
:1007C000E10008951F920F920FB60F9211241F930C
:1007D0002F933F934F935F936F937F938F939F9349
:1007E000AF93BF93EF93FF931091E9008091EC00DA
:1007F0001092E9008091F000877F8093F000789458
:10080000E0D01092E9008091F00088608093F000C1
:100810001F701093E900FF91EF91BF91AF919F91ED
:100820008F917F916F915F914F913F912F911F9188
:100830000F900FBE0F901F9018951F920F920FB63A
:100840000F9211242F933F934F935F936F937F9356
:100850008F939F93AF93BF93EF93FF938091E100AA
:1008600082FF0AC08091E20082FF06C08091E10011
:100870008B7F8093E1000BD28091DA0080FF1BC058
:100880008091D80080FF17C08091DA008E7F80931E
:10089000DA008091D90080FF0BC080E189BD82E140
:1008A00089BD09B400FEFDCF81E08EBB59DC03C0D9
:1008B00019BC1EBA57DC8091E10080FF17C08091FF
:1008C000E20080FF13C08091E2008E7F8093E200FF
:1008D0008091E20080618093E2008091D800806284
:1008E0008093D80019BC85E08EBBD1D18091E10006
:1008F00084FF2CC08091E20084FF28C080E189BD84
:1009000082E189BD09B400FEFDCF8091D8008F7DC2
:100910008093D8008091E1008F7E8093E1008091E8
:10092000E2008F7E8093E2008091E20081608093FC
:10093000E20080913402882331F48091E30087FD46
:1009400002C081E001C084E08EBBA1D18091E100B2
:1009500083FF26C08091E20083FF22C08091E100E6
:10096000877F8093E10082E08EBB109234028091F9
:10097000E1008E7F8093E1008091E2008E7F809382
:10098000E2008091E20080618093E20080E060E01C
:1009900042E018DE8091F00088608093F00077D10B
:1009A000FF91EF91BF91AF919F918F917F916F9147
:1009B0005F914F913F912F910F900FBE0F901F901D
:1009C00018951F93DF93CF93CDB7DEB7AC970FB6D3
:1009D000F894DEBF0FBECDBFE8E3F2E08091F100F6
:1009E000819322E0E034F207C9F7F9DB8091E80057
:1009F00083FF35C18091380230913902353009F4D6
:100A000087C0363040F43130C9F1313070F03330C6
:100A100009F025C133C0383009F4F4C0393009F485
:100A200003C1363009F01BC195C0803821F08238EF
:100A300009F015C108C090913502809136028823D3
:100A400099F0926011C080913C028F708093E90010
:100A50008091EB0090E025E0969587952A95E1F747
:100A6000982F91701092E9008091E800877F809321
:100A7000E8009093F1001092F100CFC0882319F0A4
:100A8000823009F0ECC090E08F719070009721F0F7
:100A9000029709F0E4C00CC080913A02813009F05D
:100AA000DEC010923602333069F5809336022AC0D8
:100AB00080913A02882331F520913C022F7009F48D
:100AC000CEC02093E9008091EB0080FF1BC0333043
:100AD00021F48091EB00806213C08091EB00806173
:100AE0008093EB0081E090E002C0880F991F2A9567
:100AF000E2F78093EA001092EA008091EB008860B0
:100B00008093EB001092E9008091E800877F88C015
:100B1000882309F0A4C010913A021F778091E30066
:100B20008078812B8093E3008091E800877F809319
:100B3000E80098DD8091E80080FFFCCF8091E30021
:100B400080688093E300112311F482E001C083E008
:100B50008EBB85C08058823008F081C080913A02F7
:100B600090913B0223E08C3D920709F033C083E073
:100B70008C838AE28B837FB7F894DE0115966EE052
:100B800040E050E011E2E62FF0E01093570084912E
:100B900040FF03C082958F706F5F8F70282F30E009
:100BA0008A3018F0C901C79602C0C901C0968D935A
:100BB0009D934F5F5F4F4431510529F77FBF80916F
:100BC000E800877F8093E800CE0103966AE270E038
:100BD0002FDC12C060913C02AE014F5F5F4FFADB29
:100BE000BC01009709F43BC08091E800877F8093A7
:100BF000E80089819A8180DC8091E8008B7780937E
:100C0000E8002DC0803859F58091E800877F8093F7
:100C1000E800809134028093F1008091E8008E77A3
:100C20008093E8001FDD1BC08823C9F490913A022D
:100C30009230A8F48091E800877F8093E800909339
:100C4000340210DD80913402882331F48091E30076
:100C500087FD02C081E001C084E08EBBC3DA8091D1
:100C6000E80083FF0AC08091E800877F8093E80056
:100C70008091EB0080628093EB00AC960FB6F89405
:100C8000DEBF0FBECDBFCF91DF911F9108950895B4
:100C90001F938EB3882371F01091E9008091EC00CE
:100CA0001092E9008091E80083FF01C08ADE1F7086
:100CB0001093E9001F910895FC018EB3843099F5DB
:100CC00084899589A689B7890097A105B10559F14D
:100CD00086818F708093E9008091E80082FF23C0B5
:100CE0004091F3002091F200942F80E030E0822BBD
:100CF000932B892B19F46FEF7FEF04C08091F100E3
:100D0000682F70E04091F3002091F200942F80E072
:100D100030E0822B932B892B41F48091E8008B7774
:100D20008093E80002C06FEF7FEFCB010895089534
:100D3000FC018EB3843051F584899589A689B789E1
:100D40000097A105B10511F181818F708093E900B1
:100D50004091F3002091F200942F80E030E0822B4C
:100D6000932B892BA9F09091E8008091E8008E7771
:100D70008093E80095FD0CC094DC982F882349F4FB
:100D80008091E8008E778093E80003C092E001C074
:100D900090E0892F0895FC018EB3843091F484890A
:100DA0009589A689B7890097A105B10551F0818180
:100DB0008F708093E9008091E80080FF02C0CF012E
:100DC000B7CF08951F93FC01162F8EB38430E1F442
:100DD00084899589A689B7890097A105B105A1F0F5
:100DE00081818F708093E9008091E80085FD08C0C3
:100DF0008091E8008E778093E80053DC882329F403
:100E00001093F10080E001C082E01F910895CF931C
:100E1000DF93EC014096FC018BE0DF011D928A9587
:100E2000E9F782E08C83898783E08E87CE01019683
:100E300061E0DCDB882371F0CE01069661E0D6DB51
:100E4000882341F0CE010B9661E0D0DB882319F0B6
:100E500081E001C080E0DF91CF910895CF93DF93CF
:100E6000EC018091E80083FFA2C0888190E020918E
:100E70003C0230913D022817390709F098C0809153
:100E80003902813269F0823220F4803209F08FC059
:100E90003CC0823209F46AC0833209F088C079C04C
:100EA00080913802813A09F082C08091E800877F02
:100EB0008093E8008091E80080FFFCCF8C899D89B9
:100EC000AE89BF898093F100292F3A2F4B2F5527E8
:100ED0002093F1009D01442755272093F1008B2F8B
:100EE0009927AA27BB278093F100888D8093F10072
:100EF000898D8093F1008A8D8093F1008091E800C4
:100F00008E778093E800AEDB52C080913802813248
:100F100009F04DC08091E800877F8093E80004C00D
:100F20008EB3882309F443C08091E80082FFF8CF94
:100F30008091F1009091F1002091F1003091F10049
:100F40008C8B9D8B2E8B3F8B8091F100888F8091B5
:100F5000F100898F8091F1008A8F8091E8008B7772
:100F60008093E8007FDBCE0139D921C0809138021F
:100F70008132E9F48091E800877F8093E80072DB9A
:100F800080913A0290913B02998B888BCE01CFDE03
:100F90000EC080913802813251F48091E800877F41
:100FA0008093E8005FDBCE0160913A02C0DEDF9102
:080FB000CF910895F894FFCFE2
:100FB80000831000000104100000018208000001F5
:0C0FC8000000000000000000000000001D
:00000001FF

View File

@ -0,0 +1,8 @@
#!/bin/bash
apt-get -y install dfu-programmer
dfu-programmer atmega32u4 erase
dfu-programmer atmega32u4 flash TPUARTtransparent.hex
dfu-programmer atmega32u4 reset

View File

@ -0,0 +1,26 @@
---
- 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

View File

@ -0,0 +1,3 @@
---
shairport_sync_version: "3.3.5"
shairport_name: Unnamed Raspberry with shairport

View File

@ -0,0 +1,3 @@
---
dependencies:
- role: pi-alsasetup

View File

@ -0,0 +1,38 @@
---
- name: Apt install dependencies
apt:
cache_valid_time: 7200
state: present
name:
- build-essential
- git
- xmltoman
- autoconf
- automake
- libtool
- libpopt-dev
- libconfig-dev
- libasound2-dev
- avahi-daemon
- libavahi-client-dev
- libssl-dev
- libsoxr-dev
- name: Build and Install Shairport sync (may take a while)
script: "build-shairport-sync.sh ${shairport_sync_version}"
args:
creates: /usr/local/bin/shairport-sync
- name: Copy config
template: src=shairport-sync.conf dest=/etc/shairport-sync.conf
- name: Modify service file to run as root
lineinfile:
path: /lib/systemd/system/shairport-sync.service
regexp: "^#?User="
line: "User=root"
- name: Restart shairport-sync
systemd: name=shairport-sync state=restarted enabled=yes daemon_reload=yes
- name: Add to sysdweb
include_role:
name: pi-sysdweb
vars:
sysdweb_name: shairport-sync

Binary file not shown.

View File

@ -0,0 +1,36 @@
[Unit]
Description=SiS PM Control for Linux
Wants=network-online.target
After=network-online.target
Wants=systemd-udev-settle.service
After=systemd-udev-settle.service
[Install]
WantedBy=multi-user.target
[Service]
CapabilityBoundingSet=
LockPersonality=true
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateTmp=true
PrivateUsers=true
ProtectClock=true
ProtectControlGroups=true
ProtectHome=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectSystem=strict
RemoveIPC=true
RestrictAddressFamilies=AF_INET AF_INET6
RestrictNamespaces=true
RestrictRealtime=true
SystemCallFilter=@system-service
SystemCallArchitectures=native
UMask=177
Type=forking
ExecStart=/usr/bin/sispmctl -p 2638 -l
SyslogIdentifier=sispmctl
Restart=always
RestartSec=5

View File

@ -0,0 +1,21 @@
---
- 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

View File

@ -0,0 +1,47 @@
Repository: https://github.com/ralph-irving/squeezelite.git
Version: c89faf3280c5dca3f04906a4ff7796a0043e99f0
Packages to build:
- libmad0
- libmpg123-0
- libflac8
- libvorbisfile3
- libfaad2
# for building libssl-dev, libasound2-dev, libflac-dev, libvorbis-dev, libsoxr-dev, libfaad-dev, libmad0-dev, libmpg123-dev
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
Old
---
Repository: https://github.com/ralph-irving/squeezelite.git
Version: 779fe9035a2dfcaeeb5335497a012d5e7241a409
Custom Makefile based on Makefile.rpi:
```Makefile
OPTS = -DLINUX -DUSE_SSL -DLINKALL -I./include -I./include/opus -I./include/alac -I/usr/local/include -s -march=armv6 -mfloat-abi=hard -mfpu=vfp
LDFLAGS=-L./lib -L/usr/local/lib -s -lgomp -lasound
include Makefile
```
Required packages:
```bash
apt-get install libasound2 libasound2-dev libflac-dev libmad0-dev libfaad-dev libmpg123-dev libvorbis-dev
```
- no RPI switch (this is only when wanting to do switiching based on GPIO headers)
- manually added -lasound (don't know why it wasn't in there)
Then just build with
make -f mymakefile (on a raspi)

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,31 @@
---
- 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

View File

@ -0,0 +1,10 @@
[Unit]
Description=Squeezelite
After=network.target
[Service]
ExecStart=/opt/squeezelite -n {{squeezelite_name}} -s {{squeezeserver}} -o softvol_squeezelite
Restart=on-failure
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,2 @@
---
squeezeserver: 192.168.178.80

View File

@ -0,0 +1,3 @@
---
- name: restart-squeezelite
systemd: name=squeezelite state=restarted enabled=yes daemon_reload=yes

View File

@ -0,0 +1,3 @@
---
dependencies:
- role: pi-alsasetup

View File

@ -0,0 +1,13 @@
---
- 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

View File

@ -1,3 +1,3 @@
SL_NAME="{{squeezelite_name}}" SL_NAME="{{squeezelite_name}}"
SL_SOUNDCARD="softvol_squeezelite" SL_SOUNDCARD="softvol_squeezelite"
SB_SERVER_IP="192.168.178.80" SB_SERVER_IP="{{squeezeserver}}"

View File

@ -0,0 +1,2 @@
#http://downloads.slimdevices.com/LogitechMediaServer_v7.9.2/logitechmediaserver_7.9.2_arm.deb
https://downloads.slimdevices.com/LogitechMediaServer_v8.4.0/logitechmediaserver_8.4.0_arm.deb

View File

@ -0,0 +1,39 @@
---
- name: Install packages required for squeeze server
apt:
name:
- libsox-fmt-all
- libflac-dev
- libfaad2
- libmad0
- perl-openssl-abi-1.1
- libnet-ssleay-perl
- libio-socket-ssl-perl
- nasm
- build-essential
- iptables-persistent
cache_valid_time: 7200
state: present
- name: copy squeezeserver package
copy: src=logitechmediaserver_8.4.0_arm.deb dest=/tmp
- name: install squeezeserver package
apt: deb=/tmp/logitechmediaserver_8.4.0_arm.deb
- name: Enable sysdweb autostart
systemd: name=logitechmediaserver state=started enabled=yes
- name: Add to sysdweb
include_role:
name: pi-sysdweb
vars:
sysdweb_name: logitechmediaserver
- name: Forward port 80 to 9000
iptables:
table: nat
chain: PREROUTING
in_interface: eth0
protocol: tcp
match: tcp
destination_port: "80"
jump: REDIRECT
to_ports: "9000"
comment: Redirect web traffic to port 9000

View File

@ -0,0 +1,13 @@
---
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

View File

@ -0,0 +1,12 @@
EsszimmerRadio Eltern
________
/______ |
| | | _
| ===== | | | |
| ===== | | o o
| | | |~
| .-. | | o o o
| ' . ' | | |~ |_|
..'| '._.' | | o
.' |_______|/

View File

@ -0,0 +1,7 @@
Music Mouse
___
_ _ .-' '-.
(.)(.)/ \
/@@ ;
o_\\-mm-......-mm`~~~~~~~~~~~~~~~~`

View File

@ -0,0 +1,10 @@
Musik Server Wohnzimmer oben
|~~~~~~~~~~~~~~~|
|~~~~~~~~~~~~~~~|
| |
/~~\| /~~\|
\__/ \__/

View File

@ -0,0 +1,3 @@
=================
WELCOME TO OCTOPI
=================

View File

@ -0,0 +1,10 @@
#!/bin/bash
if /sbin/ifconfig wlan0 | /bin/grep -q "inet addr:" ; then
logger "Tested Inet connection - everything ok"
echo "Tested Inet connection - everything ok"
else
logger "Network connection down! Attempting reconnection."
echo "Network connection down! Attempting reconnection."
/sbin/ifup --force wlan0
fi

View File

@ -0,0 +1,8 @@
---
- name: restart sshd
service:
name: sshd
state: restarted
- name: reboot
reboot:

View File

@ -0,0 +1,102 @@
---
- 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

View File

@ -0,0 +1,12 @@
[Unit]
Description=Control systemd services through Web or REST API
Documentation=https://github.com/ogarcia/sysdweb
After=network.target
Requires=dbus.socket
[Service]
ExecStart=/usr/local/bin/sysdweb -p 10080 -l 0.0.0.0
Restart=on-failure
[Install]
WantedBy=multi-user.target

Some files were not shown because too many files have changed in this diff Show More