updates raspis to new os based on bookworm

This commit is contained in:
Martin Bauer 2024-02-19 08:10:58 +01:00
parent 7776095180
commit 7501ef18a4
25 changed files with 359 additions and 74 deletions

3
.gitignore vendored
View File

@ -2,3 +2,6 @@ ve_*
/server/scripts/docker-images/tagspace/tagspaces /server/scripts/docker-images/tagspace/tagspaces
/server/scripts/docker-images/tagspace/*.zip /server/scripts/docker-images/tagspace/*.zip
*.img *.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
}

View File

@ -1,21 +1,14 @@
--- ---
- hosts: bedroompi, kitchenpi #- hosts: esszimmerradio
roles: # roles:
- pi-dhtsensor # - pi-standard-setup
# - pi-squeezelite-custom
# - pi-shairport
# - pi-lirc
# - pi-sispmctl
- hosts: esszimmerradio #
roles:
- pi-standard-setup
- pi-squeezelite-custom
- pi-shairport
- pi-lirc
- pi-sispmctl
- hosts: musikserverwohnzimmeroben - hosts: musikserverwohnzimmeroben
roles: roles:
- pi-standard-setup - pi-standard-setup
@ -26,17 +19,27 @@
- pi-dhtsensor - pi-dhtsensor
- pi-squeezeserver - pi-squeezeserver
- hosts: bedroompi, kitchenpi
roles:
- pi-standard-setup
- pi-squeezelite-custom
- pi-shairport
- pi-lirc
- pi-dhtsensor
- hosts: octopi #- hosts: kitchenpi
roles: # roles:
- pi-dhtsensor # - 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 #- hosts: newrpi

View File

@ -28,9 +28,10 @@ all:
esszimmerradio: # oben, eltern esszimmerradio: # oben, eltern
squeezelite_name: Esszimmer squeezelite_name: Esszimmer
shairport_name: _Oben_Esszimmer shairport_name: _Oben_Esszimmer
alsa_card_name: Device #alsa_card_name: Device
squeezeserver: 192.168.178.100 squeezeserver: 192.168.178.100
configure_wifi: true configure_wifi: true
alsa_card_name: 1
musikserverwohnzimmeroben: # oben, eltern musikserverwohnzimmeroben: # oben, eltern
squeezelite_name: Wohnzimmer squeezelite_name: Wohnzimmer
shairport_name: _Oben_Wohnzimmer shairport_name: _Oben_Wohnzimmer
@ -57,6 +58,6 @@ all:
squeezeserver: 192.168.178.80 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: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIxNjkxMWIzZmQ4ZWU0NDI0OTg0MjA0ZDllMDhkNGRlMCIsImlhdCI6MTU3ODE3MDU5MSwiZXhwIjoxODkzNTMwNTkxfQ.i7CdXEZy9DV9KPHAl-msK0rOfIUlPYo4zwwJ4UGhXuc home_assistant_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkM2QxYjAwYjkxZjY0MWVhYjA4YmZhMDYwYTg3YjRhNyIsImlhdCI6MTcwNDI3MDU5MSwiZXhwIjoyMDE5NjMwNTkxfQ.dzvejgEQd9hf-Yftzd7NkR5pv76GaLFczeOy-a2pa1o
configure_wifi: false configure_wifi: false
wifi_ssid: BauerWLAN wifi_ssid: BauerWLAN

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,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

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

View File

@ -10,16 +10,18 @@
name: adafruit-circuitpython-dht name: adafruit-circuitpython-dht
executable: pip3 executable: pip3
state: absent state: absent
extra_args: "--break-system-packages"
- name: pip install adafruit-dht - name: pip install adafruit-dht
pip: pip:
name: adafruit-dht name: adafruit-dht
executable: pip3 executable: pip3
extra_args: "--break-system-packages"
- name: Install script config - name: Install script config
template: src=dht22_sensing.json dest=/etc/dht22_sensing.json template: src=dht22_sensing.json dest=/etc/dht22_sensing.json
- name: Install script - name: Install script
copy: src=dht22_sensing.py dest=/usr/bin/dht22_sensing owner=root mode=u+rwx copy: src=dht22_sensing.py dest=/usr/bin/dht22_sensing owner=root mode=u+rwx
- name: Install systemd service file - name: Install systemd service file
copy: src=dht22_sensing.service dest=/lib/systemd/system/ copy: src=dht22_sensing.service dest=/etc/systemd/system/
- name: Add script to autostart and start now - name: Add script to autostart and start now
systemd: name=dht22_sensing state=restarted enabled=yes daemon_reload=yes systemd: name=dht22_sensing state=restarted enabled=yes daemon_reload=yes
- name: Add to sysdweb - name: Add to sysdweb

View File

@ -7,7 +7,7 @@
notify: reboot notify: reboot
- name: Activate Hifiberry - name: Activate Hifiberry
lineinfile: lineinfile:
path: /boot/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

View File

@ -1,43 +1,16 @@
--- ---
# Lirc needs a custom build on Raspian Buster, more details here: - name: Install lirc
# https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=235256 apt:
# https://gist.github.com/billpatrianakos/cb72e984d4730043fe79cbe5fc8f7941 name: lirc
- name: Create lirc config dir
file: path=/etc/lirc state=directory
- name: Install config file lirc_options.conf - name: Install config file lirc_options.conf
copy: src=lirc_options.conf dest=/etc/lirc/lirc_options.conf copy: src=lirc_options.conf dest=/etc/lirc/lirc_options.conf
- name: Install config file lircd.conf - name: Install config file lircd.conf
copy: src=lircd.conf dest=/etc/lirc/lircd.conf copy: src=lircd.conf dest=/etc/lirc/lircd.conf
- name: Install remote file - name: Install remote file
copy: src=hauppauge.conf dest=/etc/lirc/hauppauge.conf copy: src=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: debs/
dest: "{{ tempdir.path }}"
when: tempdir.path is defined
- name: Install custom lirc package 1
apt:
force: True
deb: "{{ tempdir.path }}/liblirc0_0.10.1-5.2_armhf.deb"
when: tempdir.path is defined
- name: Install custom lirc package 2
apt:
force: True
deb: "{{ tempdir.path }}/liblircclient0_0.10.1-5.2_armhf.deb"
when: tempdir.path is defined
- name: Install custom lirc package 3
apt:
force: True
deb: "{{ tempdir.path }}/lirc_0.10.1-5.2_armhf.deb"
when: tempdir.path is defined
- name: Activate overlay in boot config - name: Activate overlay in boot config
lineinfile: lineinfile:
path: /boot/config.txt path: /boot/firmware/config.txt
regexp: "^#?dtoverlay=gpio-ir" regexp: "^#?dtoverlay=gpio-ir"
line: "dtoverlay=gpio-ir,gpio_pin=17" line: "dtoverlay=gpio-ir,gpio_pin=17"
register: boot_overlay register: boot_overlay

View File

@ -1,3 +1,25 @@
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 Repository: https://github.com/ralph-irving/squeezelite.git
Version: 779fe9035a2dfcaeeb5335497a012d5e7241a409 Version: 779fe9035a2dfcaeeb5335497a012d5e7241a409
@ -22,3 +44,4 @@ apt-get install libasound2 libasound2-dev libflac-dev libmad0-dev libfaad-dev li
Then just build with Then just build with
make -f mymakefile (on a raspi) make -f mymakefile (on a raspi)

Binary file not shown.

View File

@ -6,9 +6,10 @@
name: name:
- libmad0 - libmad0
- libmpg123-0 - libmpg123-0
- libflac8 - libflac12
- libvorbisfile3 - libvorbisfile3
- libfaad2 - libfaad2
# for building libssl-dev, libasound2-dev, libflac-dev, libvorbis-dev, libsoxr-dev, libfaad-dev, libmad0-dev, libmpg123-dev
state: present state: present
cache_valid_time: 7200 cache_valid_time: 7200
- name: Remove old config file if present - name: Remove old config file if present
@ -24,3 +25,7 @@
name: pi-sysdweb name: pi-sysdweb
vars: vars:
sysdweb_name: squeezelite 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

@ -1 +1,2 @@
http://downloads.slimdevices.com/LogitechMediaServer_v7.9.2/logitechmediaserver_7.9.2_arm.deb #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

@ -15,9 +15,9 @@
cache_valid_time: 7200 cache_valid_time: 7200
state: present state: present
- name: copy squeezeserver package - name: copy squeezeserver package
copy: src=logitechmediaserver_7.9.2_arm.deb dest=/tmp copy: src=logitechmediaserver_8.4.0_arm.deb dest=/tmp
- name: install squeezeserver package - name: install squeezeserver package
apt: deb=/tmp/logitechmediaserver_7.9.2_arm.deb apt: deb=/tmp/logitechmediaserver_8.4.0_arm.deb
- name: Enable sysdweb autostart - name: Enable sysdweb autostart
systemd: name=logitechmediaserver state=started enabled=yes systemd: name=logitechmediaserver state=started enabled=yes
- name: Add to sysdweb - name: Add to sysdweb

View File

@ -9,6 +9,7 @@
pip: pip:
name: sysdweb name: sysdweb
executable: pip3 executable: pip3
extra_args: "--break-system-packages"
- name: sysdweb user - name: sysdweb user
user: user:
name: sysdweb name: sysdweb
@ -33,6 +34,6 @@
title = {{sysdweb_name}} title = {{sysdweb_name}}
unit = {{sysdweb_name}}.service unit = {{sysdweb_name}}.service
- name: Install systemd service file - name: Install systemd service file
copy: src=sysdweb-system.service dest=/lib/systemd/system/ copy: src=sysdweb-system.service dest=/etc/systemd/system/
- name: Enable sysdweb autostart - name: Enable sysdweb autostart
systemd: name=sysdweb-system state=restarted enabled=yes daemon_reload=yes systemd: name=sysdweb-system state=restarted enabled=yes daemon_reload=yes

View File

@ -3,8 +3,9 @@
set -e # exit on error set -e # exit on error
TARGET_FOLDER="./rpi_image" TARGET_FOLDER="./rpi_image"
IMG_FILE_BASENAME="2021-10-30-raspios-bullseye-armhf-lite" IMG_FILE_BASENAME="2023-12-11-raspios-bookworm-armhf-lite"
DOWNLOAD_URL="https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2021-11-08/${IMG_FILE_BASENAME}.zip" #DOWNLOAD_URL="https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2021-11-08/${IMG_FILE_BASENAME}.zip"
DOWNLOAD_URL="https://downloads.raspberrypi.com/raspios_lite_armhf/images/raspios_lite_armhf-2023-12-11/${IMG_FILE_BASENAME}.img.xz"
echo "This script downloads raspian lite, and modifies the image to enable SSH and set hostname" echo "This script downloads raspian lite, and modifies the image to enable SSH and set hostname"
@ -28,11 +29,10 @@ wget ${DOWNLOAD_URL}
wget ${DOWNLOAD_URL}.sha256 wget ${DOWNLOAD_URL}.sha256
echo "Checksum verification" echo "Checksum verification"
sha256sum -c ${IMG_FILE_BASENAME}.zip.sha256 sha256sum -c ${IMG_FILE_BASENAME}.img.xz.sha256
echo "Unpack image" echo "Unpack image"
unzip ${IMG_FILE_BASENAME}.zip unxz ${IMG_FILE_BASENAME}.img.xz
rm ${IMG_FILE_BASENAME}.zip
echo "Mounting image" echo "Mounting image"
@ -81,7 +81,7 @@ losetup -d /dev/loop42
rmdir mounted_image/boot rmdir mounted_image/boot
rmdir mounted_image/system rmdir mounted_image/system
rmdir mounted_image rmdir mounted_image
rm ${IMG_FILE_BASENAME}.zip.sha256 rm ${IMG_FILE_BASENAME}.img.xz.sha256
chmod a+rw ${IMG_FILE_BASENAME}.img . chmod a+rw ${IMG_FILE_BASENAME}.img .
echo "" echo ""