RPIB (Raspberry Pi Backup Script for the home folder)


#!/bin/sh

datum=$(date +%d_%m_%y)
source=$(hostname)

# Create local share point
mkdir -p ~/RPI_Backups

# Mount the remote backup folder
sudo mount -t cifs -o rw,guest,vers=3.0 //myserver.local/myshare/myfolder ~/RPI_Backups

# Create a subfolder for this host
sudo mkdir -p ~/RPI_Backups/$source

# Create the backup with tar, excluding the backup folder itself
sudo tar --warning=no-file-changed \
--exclude=/home/pi/RPI_Backups \
-czvf /home/pi/RPI_Backups/$source/home_backup_$datum.tar.gz /home/pi

# Unmount the remote share
sudo umount ~/RPI_Backups

quotes-rss (Videos from RSS-Feeds)

Der Anstoss für dieses RPiOS-Projekt kam von Adafruit Quotes, das ist mehr ein Demo-Projekt für diverse Apps und Geräte. Eine deutsche Variante musste her, und auch ein bisschen strukturierter, da ich Zitat und Autor getrennt haben wollte, um gestaltungstechnisch mehr Möglichkeiten zu haben. Und ich wollte Video_looper verwenden, um die Videos automatisch abzuspielen.
Mein Feed liegt hier:http://cargologo.com/feed/quotes/data_rss.xml. Und er lässt sich auch in einen RSS-Viewer einfügen, wie NetNewsWire oder Vienna.
Das Skript lädt den Feed runter, wählt einen Eintrag zufällig aus und erstellt ein Video (anhand eines Hintergrund-Videos und einer Schrift, siehe Assets-Folder). Das Hintergrund-Video (input.mp4) bestimmt die Länge und die Bild-Grösse der erstellten Video-Datei und es könnte auch Bild-Elemente beinhalten. Meine Testumgebung hier ist das ArgonPod-Video-Case mit RPi Zero 2, der ganz gut kleine FFMPEG-Aufgaben erledigen kann, im Gegensatz zum RPi Zero 1. Die Bildschirmgrösse und die Videobildgrösse hier ist 640×480, durch entsprechende Einstellungen bei FFMPEG kann man auch HD-Videos für andere Ausgabegeräte erstellen.
Extension: mit dem Command-Argument ./quotes-rss latest kann man den letzten Eintrag forciert anzeigen lassen.
BTW: jeder andere Feed, der title- und description-entries enthält, geht natürlich auch.


#!/bin/bash
# Usage: ./quotes-rss.sh [latest]

# Home Dir
cd /home/pi/quotes-rss/

# Delete old file
#rm ./data_rss.xml* 2> /dev/null

# Download the latest quotes file
wget http://cargologo.com/feed/quotes/data_rss.xml

# Clean up old videos in video_looper Master Dir
#rm /home/pi/video/*_output.mp4 2> /dev/null

# -- Variables
newstimescreen=$(date '+%A %H-%M')
newstimefile=$(date '+%H%M%S')
modificationtime=$(stat ./data_rss.xml | grep "Modify" | sed 's/Modify:/XML Last Modified/g' | cut -c 1-29 | sed 's/:/\\:/g')

# -- Extraction
xml_file="data_rss.xml"
temp_file=$(mktemp)

# Extract quotes and authors using awk
awk '
BEGIN { RS=""; FS="\n" }
// {
title=""; description=""
for(i=1; i<=NF; i++) { if ($i ~ //) {<br /> sub(".*<title>[ \t]*", "", $i)<br /> sub("[ \t]*.*", "", $i)
title=$i
}
if ($i ~ //) {
sub(".*[ \t]*", "", $i)
sub("[ \t]*
.*", "", $i)
gsub("", "", $i)
description=$i }
}
if (title && description) {
print title "|" description >> "'"$temp_file"'"
last_title = title
last_author = description
}
}
END {
if (last_title && last_author) {
print last_title "|" last_author > "'"$temp_file"'.latest"
}
}
' "$xml_file"

# Verify that temp_file is populated
num_items=$(wc -l < "$temp_file") if [ "$num_items" -eq 0 ]; then echo "No items found with both title and description." rm "$temp_file" exit 1 fi # Choose latest or random quote if [[ "$1" == "latest" ]]; then echo "Showing latest entry..." latest_item=$(cat "$temp_file.latest") random_item=$latest_item else # Load lines from temp_file into an array mapfile -t items < "$temp_file" rm "$temp_file" # Select a random item random_index=$((RANDOM % num_items)) random_item=${items[$random_index]} fi # Split title and description quote=$(echo "$random_item" | cut -d'|' -f1) author=$(echo "$random_item" | cut -d'|' -f2) # Format text with line breaks (2 line breaks between title & author) This is ! formatted_text=$(echo -e "$quote\n\n$author" | fold -s -w 30) # Escape special characters and preserve newlines for ffmpeg ! This is ! # this creates \u0027 formatted_text_escaped=$(echo "$formatted_text" | sed "s/'/\\\u0027/g; s/:/\\\\:/g; s/\n/\\\x0A/g") # create video with ffmpeg ffmpeg -i ./Assets/input.mp4 -vf \ "drawtext=text='${formatted_text_escaped}':fontfile='./Assets/NotoSans_Condensed-Black.ttf':fontcolor=white:fontsize=42:x=10:y=20:box=1:boxcolor=black@0.5:boxborderw=15, \ drawtext=text='${modificationtime}':fontfile='./Assets/NotoSans_Condensed-Black.ttf':fontcolor=yellow:fontsize=30:x=10:y=420" \ -codec:a copy "${newstimefile}_output.mp4" # Debug Output echo "Formatted Text: $formatted_text_escaped" # echo "Modification Time: $modificationtime" # Move file to video folder mv *_output.mp4 /home/pi/video/

Files: Download quotes-rss and Assets

Airplay-Sender: Owntone

Es gibt Hunderte Anleitungen für RPi OS, um einen AirPlay-Receiver einzurichten, oft ist die Funktionalität schon Teil des Systems (Volumio, KODI). Aber die eigentlich praktischere Variante, nämlich Audio über AirPlay zu einem vorhandenen und meist auch teuren Audiosystem zu senden, wird sehr wenig besprochen.
Owntone ist ein DAAP-MediaServer, der sich elegant über die Apple Remote-App steuern lässt.
Installationsanleitung hier: https://forums.raspberrypi.com/viewtopic.php?t=49928

In meinem Fall soll die Remote-App auf meinem Handy die Radiostreams auf dem „Owntone-Device“ steuern, ohne selbst mit irgendwelchen Streams belästigt zu werden. Dafür muss ein Pairing mit dem Service durchgeführt werden.

Meine Stationen liegen alle in einzelnen M3U-Files, der Vorteil ist ein Touch-Eintrag pro Station. Man kann sie auch in eine Datei legen, aber dann muss man über die Remote-App erst in die Datei selber (e.g radios.m3u) und dann dort die Station auswählen.

Die Ausgabe wird über das Setting-Menü in Owntone eingestellt, hier kann man final seine Speaker auswählen. Btw: Volumio unterstützt ebenfalls externe Speaker, aber für dieses Feature muss man bezahlen.

Raspiaudio+ V2

Das DAC V2 (orange) von Raspiaudio wird nicht mehr vertrieben, stattdessen gibt es jetzt die Variante V3 (blau). Die Installation ist gleich wie bei V2, siehe Forum, in meinem Fall will ich das Videolooper-Setup dokumentieren.
Hier die Auszüge aus der /boot/video_looper.ini, hw_device ist nicht nötig, aber sound = alsa muss eingeschaltet sein.


# ALSA hardware device to use for sound output. This consists of the card
# number and subdevice number separated by a comma, e.g. '1,0'. Run
# 'aplay -l' to list available devices. If empty, the default output device is
# used.
hw_device =
#hw_device = 1,0
...
# Sound output for omxplayer, either hdmi, local, both or alsa. When set to
# hdmi the video sound will be played on the HDMI output, and when set to local
# the sound will be played on the analog audio output. A value of both will
# play sound on both HDMI and the analog output. A value of alsa will play
# sound through ALSA, using the device specified in the [alsa] section above.
# The both value is the default.
#sound = both
#sound = hdmi
#sound = local
sound = alsa

In der /boot/config.txt ist nur der hifiberry-Zusatz wichtig und Onboard-Audio aus.


# Enable audio (loads snd_bcm2835)
# dtparam=audio=on

# dac
dtoverlay=hifiberry-dac

Damit ist Audio über den Miniklinken-Ausgang eingeschaltet.

IKEA-Videoframe (KODI)

Ein KODI-Server lungert schon seit Jahren bei mir rum, aber es war mal Zeit für was Aufregendes. Bei IKEA findet man Praktisches und Schönes, ein Bilderrahmen lässt sich unauffällig in ein anderes Bild-Ensemble integrieren.
Die Elektronik muss klein und vor allem ohne grosse thermische Belastung auskommen, die aktuellen SSD-Preise (hier 29 Eur für 500 GB) lassen das zu und man kann endlich die alten mechanischen HDs rauswerfen.
Softwareseitig kommt LibreELEC Version 10 für RPi 3 zum Einsatz, die anderen Varianten, Version 11 und 12 für RPi 3 funktionierten nicht auf Anhieb, und das war auch Teil des Projektes, nämlich so schnell wie möglich Out-of-the-Box loslegen zu können. Das System auf dem RPi und die Daten auf der externen SSD sind getrennt benutzbar.
Die LibreELEC-Einrichtung erfordert den WLAN-Zugang, Hostname und SMB-Service-Einstellung, das dauert eine Minute, die angeschlossene Festplatte wird als externe Quelle mit der Formatierung MS-DOS (Dateigrössen-Limitierung 4 GB) erkannt.

Als Client für die Inhalte auf einer AppleTV-StreamingBox kommt Infuse zum Einsatz, die Anmeldung erfolgt über die Option „Anonymer Login“ und dort wird die Festplatte als „Favorit“, hier „Video500“, definiert. Danach sind alle Inhalte darüber verfügbar.

Unter macOS kann man eine konstante Datenrate von ca. 10 MB/s erreichen, das wäre auch das Maximum für die RPi-Hardware, also in einer Stunde könnte man 39 GB transferieren.
Alles in allem ein sehr nützliches und vor allem zuverlässiges Gerät, ähnliche Konfigurationen benutze ich schon mehrere Jahre ohne Ausfälle. Die Gesamtkosten betragen bei heutigem Stand 75 Euro plus Mini-SD-Karte und Stromversorgung, das ist nicht zuviel für eine elegante und langlebige Lösung.

BOM:

IKEA Vaestanhed Bilderrahmen

Intenso SSD 500 GB

SATA-USB-Adapter

Raspberry Pi 3A+

Update: anderer (getesteter) Client wäre VLC (AndroidTV/AppleTV).

Player „Universal“ (Audio/Video)

Complete Image (with Button on Pin 11 and 9):
http://rootfriend.com/videolooper-masterimage

Manual (Audio):

1. Connect Speaker or Head-Phones at the Audio-Connector
2. The Loop will start automatically after Power-On (Audio-Files need to be MP4 or M4A)
3. Re-Start the Audio-Loop with the Button on the Front

Manual: (Video)

1. Connect Screen at the HDMI-Connector
2. The Loop will start automatically after Power-On (Video-Files need to be MP4)
3. Re-Start the Video-Loop with the Button on the Front

Undervoltage-LED, external

Über dmesg kann man den „Undervoltage“-Status auslesen und an eine externe LED anzeigen lassen. Das macht Sinn bei Custom Cases, bei der die Onboard-LED nicht zu sehen ist. Ausserdem kann man seinen eigenen „Alert Mode“ definieren: blinken, leuchten, blinken-leuchten, flimmern, flackern. Testen kann man das mit diversen Netzteilen und/oder Stromversorgung über Computer-USB, die in der Regel zu gering definiert ist, um einen Raspberry Pi zu betreiben. Liegt natürlich auch am jeweiligen Modell. Achtung: die Schreibweise von „Undervoltage detected!“ ändert sich auch mal entsprechend der Raspberry-Pi-OS-Versionen, z.B. „Under-voltage detected“, dieser String muss natürlich passen.


#!/bin/bash
while [ $loop 1 ] ; do
dmesg | grep -iC 3 "Undervoltage detected!"
if [ $? != 0 ]
then
    echo "normal voltage" &>/dev/null
else
    sh /home/pi/LED/voltage-led
    echo "under voltage" &>/dev/null
fi
sleep 1
done
sleep 0
done