diff --git a/battybirdnet-pi/config.json b/battybirdnet-pi/config.json
index 17fdd9800..9fe5dc9f9 100644
--- a/battybirdnet-pi/config.json
+++ b/battybirdnet-pi/config.json
@@ -119,6 +119,6 @@
"udev": true,
"url": "https://github.com/alexbelgium/hassio-addons/tree/master/battybirdnet-pi",
"usb": true,
- "version": "0.6",
+ "version": "0.7",
"video": true
}
diff --git a/battybirdnet-pi/rootfs/custom-services.d/30-monitoring.sh b/battybirdnet-pi/rootfs/custom-services.d/30-monitoring.sh
index 3d90d004a..19f72b544 100755
--- a/battybirdnet-pi/rootfs/custom-services.d/30-monitoring.sh
+++ b/battybirdnet-pi/rootfs/custom-services.d/30-monitoring.sh
@@ -1,93 +1,100 @@
-#!/usr/bin/with-contenv bashio
+#!/usr/bin/env bash
# shellcheck shell=bash
+# Adapted from https://github.com/mcguirepr89/BirdNET-Pi/issues/393#issuecomment-1166445710
-sleep infinity
+# Define logging functions
+log_green() { echo -e "\033[32m$1\033[0m" }
-echo "Starting service: throttlerecording"
-touch "$HOME"/BirdSongs/StreamData/analyzing_now.txt
+log_red() { echo -e "\033[31m$1\033[0m" }
-# variables for readability
-srv="birdnet_recording"
-analyzing_now="."
-counter=10
-set +u
-# shellcheck disable=SC1091
+log_yellow() { echo -e "\033[33m$1\033[0m" }
+
+log_info() { echo -e "\033[34m$1\033[0m" }
+
+echo "$(log_green "Starting service: throttlerecording")"
+touch "$HOME/BirdSongs/StreamData/analyzing_now.txt"
+
+# Read configuration
source /config/birdnet.conf 2>/dev/null
-# Ensure folder exists
+# Set constants
+srv="birdnet_recording"
+srv2="birdnet_analysis"
ingest_dir="$RECS_DIR/StreamData"
+counter=10
-# Check permissions
-mkdir -p "$ingest_dir"
-chown -R pi:pi "$ingest_dir"
-chmod -R 755 "$ingest_dir"
-ingest_dir="$(readlink -f "$ingest_dir")" || true
+# Ensure directories and permissions
mkdir -p "$ingest_dir"
chown -R pi:pi "$ingest_dir"
chmod -R 755 "$ingest_dir"
-function apprisealert() {
- # Set failed check so it only runs once
- touch "$HOME"/BirdNET-Pi/failed_servicescheck
- NOTIFICATION=""
- STOPPEDSERVICE="
Stopped services: "
- services=(birdnet_analysis
- chart_viewer
- spectrogram_viewer
- icecast2
- birdnet_recording
- birdnet_log
- birdnet_stats)
- for i in "${services[@]}"; do
- if [[ "$(sudo systemctl is-active "${i}".service)" == "inactive" ]]; then
- STOPPEDSERVICE+="${i}; "
+# Function to send notifications using Apprise
+apprisealert() {
+ local notification=""
+ local stopped_service="
Stopped services: "
+
+ # Check for stopped services
+ services=(birdnet_analysis chart_viewer spectrogram_viewer icecast2 birdnet_recording birdnet_log birdnet_stats)
+ for service in "${services[@]}"; do
+ if [[ "$(systemctl is-active "$service")" == "inactive" ]]; then
+ stopped_service+="$service; "
fi
done
- NOTIFICATION+="$STOPPEDSERVICE"
- NOTIFICATION+="
Additional informations: "
- NOTIFICATION+="
Since: ${LASTCHECK:-unknown}"
- NOTIFICATION+="
System: ${SITE_NAME:-$(hostname)}"
- NOTIFICATION+="
Available disk space: $(df -h "$(readlink -f "$HOME/BirdSongs")" | awk 'NR==2 {print $4}')"
- if [ -n "$BIRDNETPI_URL" ]; then
- NOTIFICATION+="
Access your BirdNET-Pi"
- fi
+
+ # Build notification message
+ notification+="$stopped_service"
+ notification+="
Additional information: "
+ notification+="
Since: ${LASTCHECK:-unknown}"
+ notification+="
System: ${SITE_NAME:-$(hostname)}"
+ notification+="
Available disk space: $(df -h "$HOME/BirdSongs" | awk 'NR==2 {print $4}')"
+ [[ -n "$BIRDNETPI_URL" ]] && notification+="
Access your BirdNET-Pi"
+
+ # Send notification
TITLE="BirdNET-Analyzer stopped"
- "$HOME"/BirdNET-Pi/birdnet/bin/apprise -vv -t "$TITLE" -b "${NOTIFICATION}" --input-format=html --config="$HOME/BirdNET-Pi/apprise.txt"
+ "$HOME/BirdNET-Pi/birdnet/bin/apprise" -vv -t "$TITLE" -b "$notification" --input-format=html --config="$HOME/BirdNET-Pi/apprise.txt"
}
+# Main loop
while true; do
sleep 61
# Restart analysis if clogged
- ############################
-
if ((counter <= 0)); then
- latest="$(cat "$ingest_dir"/analyzing_now.txt)"
- if [[ "$latest" == "$analyzing_now" ]]; then
- echo "$(date) WARNING no change in analyzing_now for 10 iterations, restarting services"
- /."$HOME"/BirdNET-Pi/scripts/restart_services.sh
+ current_file="$(cat "$ingest_dir/analyzing_now.txt")"
+ if [[ "$current_file" == "$analyzing_now" ]]; then
+ log_yellow "$(date) WARNING: no change in analyzing_now for 10 iterations, restarting services"
+ "$HOME/BirdNET-Pi/scripts/restart_services.sh"
fi
counter=10
- analyzing_now=$(cat "$ingest_dir"/analyzing_now.txt)
+ analyzing_now="$current_file"
fi
- # Pause recorder to catch-up
- ############################
+ # Check recorder state and queue length
+ wav_count=$(find "$ingest_dir" -maxdepth 1 -name '*.wav' | wc -l)
+ service_state=$(systemctl is-active "$srv")
+ analysis_state=$(systemctl is-active "$srv2")
- wavs="$(find "$ingest_dir" -maxdepth 1 -name '*.wav' | wc -l)"
- state="$(systemctl is-active "$srv")"
+ log_green "$(date) INFO: $wav_count wav files waiting in $ingest_dir, $srv state is $service_state, $srv2 state is $analysis_state"
- bashio::log.green "$(date) INFO ${wavs} wav files waiting in $ingest_dir, $srv state is $state"
-
- if ((wavs > 100)); then
- bashio::log.red "$(date) WARNING too many files in queue, pausing $srv"
+ # Pause recorder if queue is too large
+ if ((wav_count > 50)); then
+ log_red "$(date) WARNING: Too many files in queue, pausing $srv and restarting $srv2"
sudo systemctl stop "$srv"
- sudo systemctl restart birdnet_analysis
- if [ -s "$HOME/BirdNET-Pi/apprise.txt" ]; then apprisealert; fi
- elif [[ "$state" != "active" ]]; then
- bashio::log.yellow "$(date) INFO started $srv service"
- sudo systemctl start $srv
- sudo systemctl restart birdnet_analysis
+ sudo systemctl restart "$srv2"
+ [[ -s "$HOME/BirdNET-Pi/apprise.txt" ]] && apprisealert
+ elif ((wav_count > 30)); then
+ log_red "$(date) WARNING: Too many files in queue, restarting $srv2"
+ sudo systemctl restart "$srv2"
+ [[ -s "$HOME/BirdNET-Pi/apprise.txt" ]] && apprisealert
+ else
+ if [[ "$service_state" != "active" ]]; then
+ log_yellow "$(date) INFO: Restarting $srv service"
+ sudo systemctl restart "$srv"
+ fi
+ if [[ "$analysis_state" != "active" ]]; then
+ log_yellow "$(date) INFO: Restarting $srv2 service"
+ sudo systemctl restart "$srv2"
+ fi
fi
((counter--))
diff --git a/battybirdnet-pi/rootfs/etc/cont-finish.d/savestreamdata.sh b/battybirdnet-pi/rootfs/etc/cont-finish.d/savestreamdata.sh
index 215b7f9fd..de9eaae80 100755
--- a/battybirdnet-pi/rootfs/etc/cont-finish.d/savestreamdata.sh
+++ b/battybirdnet-pi/rootfs/etc/cont-finish.d/savestreamdata.sh
@@ -2,17 +2,34 @@
# shellcheck shell=bash
if [ -d "$HOME"/BirdSongs/StreamData ]; then
- bashio::log.fatal "Container stopping, saving temporary files"
+ bashio::log.fatal "Container stopping, saving temporary files."
# Stop the services in parallel
- systemctl stop birdnet_analysis &
- systemctl stop birdnet_recording
+ if systemctl is-active --quiet birdnet_analysis; then
+ bashio::log.info "Stopping birdnet_analysis service."
+ systemctl stop birdnet_analysis &
+ fi
+
+ if systemctl is-active --quiet birdnet_recording; then
+ bashio::log.info "Stopping birdnet_recording service."
+ systemctl stop birdnet_recording &
+ fi
+
+ # Wait for both services to stop
+ wait
# Check if there are files in StreamData and move them to /data/StreamData
mkdir -p /data/StreamData
if [ "$(ls -A "$HOME"/BirdSongs/StreamData)" ]; then
- mv -v "$HOME"/BirdSongs/StreamData/* /data/StreamData/
+ if mv -v "$HOME"/BirdSongs/StreamData/* /data/StreamData/; then
+ bashio::log.info "Files successfully moved to /data/StreamData."
+ else
+ bashio::log.error "Failed to move files to /data/StreamData."
+ exit 1
+ fi
fi
- bashio::log.fatal "... files safe, allowing container to stop"
+ bashio::log.info "... files safe, allowing container to stop."
+else
+ bashio::log.info "No StreamData directory to process."
fi
diff --git a/battybirdnet-pi/rootfs/etc/cont-init.d/01-structure.sh b/battybirdnet-pi/rootfs/etc/cont-init.d/01-structure.sh
index 1496113b0..46e86e191 100755
--- a/battybirdnet-pi/rootfs/etc/cont-init.d/01-structure.sh
+++ b/battybirdnet-pi/rootfs/etc/cont-init.d/01-structure.sh
@@ -6,20 +6,19 @@ set -e
# SET /CONFIG #
###############
-echo " "
-bashio::log.info "Ensuring the file structure is correct :"
+bashio::log.info "Ensuring the file structure is correct:"
-# Define structure
+# Create default configuration files if not present
echo "... creating default files"
-touch /config/include_species_list.txt # Should be null
-touch /home/pi/BirdNET-Pi/scripts/thisrun.txt
-for files in apprise.txt exclude_species_list.txt IdentifiedSoFar.txt disk_check_exclude.txt confirmed_species_list.txt blacklisted_images.txt whitelist_species_list.txt; do
- if [ ! -f /config/"$files" ]; then
- echo "" > /config/"$files"
+DEFAULT_FILES=("apprise.txt" "exclude_species_list.txt" "IdentifiedSoFar.txt" "disk_check_exclude.txt" "confirmed_species_list.txt" "blacklisted_images.txt" "whitelist_species_list.txt")
+for file in "${DEFAULT_FILES[@]}"; do
+ if [ ! -f "/config/$file" ]; then
+ echo "" > "/config/$file"
fi
done
+touch /config/include_species_list.txt # Ensure this is always created
-# Get BirdSongs folder locations
+# Set BirdSongs folder location from configuration if specified
BIRDSONGS_FOLDER="/config/BirdSongs"
if bashio::config.has_value "BIRDSONGS_FOLDER"; then
BIRDSONGS_FOLDER_OPTION="$(bashio::config "BIRDSONGS_FOLDER")"
@@ -29,65 +28,61 @@ if bashio::config.has_value "BIRDSONGS_FOLDER"; then
if [ -d "$BIRDSONGS_FOLDER_OPTION" ] && [ "$(stat -c '%u:%g' "$BIRDSONGS_FOLDER_OPTION")" == "1000:1000" ]; then
BIRDSONGS_FOLDER="$BIRDSONGS_FOLDER_OPTION"
else
- bashio::log.yellow "BIRDSONGS_FOLDER reverted to /config/BirdSongs"
+ bashio::log.warning "BIRDSONGS_FOLDER reverted to /config/BirdSongs"
fi
fi
-# Create BirdSongs folder
-echo "... creating default folders ; it is highly recommended to store those on a ssd"
-mkdir -p "$BIRDSONGS_FOLDER"/By_Date
-mkdir -p "$BIRDSONGS_FOLDER"/Charts
+# Create default folders
+echo "... creating default folders; it is highly recommended to store these on an SSD"
+mkdir -p "$BIRDSONGS_FOLDER/By_Date" "$BIRDSONGS_FOLDER/Charts"
-# If tmpfs is installed, use it
+# Use tmpfs if installed
if df -T /tmp | grep -q "tmpfs"; then
echo "... tmpfs detected, using it for StreamData and Processed to reduce disk wear"
- mkdir -p /tmp/StreamData
- mkdir -p /tmp/Processed
- if [ -d "$HOME"/BirdSongs/StreamData ]; then
- rm -r "$HOME"/BirdSongs/StreamData
- fi
- if [ -d "$HOME"/BirdSongs/Processed ]; then
- rm -r "$HOME"/BirdSongs/Processed
- fi
- sudo -u pi ln -fs /tmp/StreamData "$HOME"/BirdSongs/StreamData
- sudo -u pi ln -fs /tmp/Processed "$HOME"/BirdSongs/Processed
+ mkdir -p /tmp/StreamData /tmp/Processed
+ [ -d "$HOME/BirdSongs/StreamData" ] && rm -r "$HOME/BirdSongs/StreamData"
+ [ -d "$HOME/BirdSongs/Processed" ] && rm -r "$HOME/BirdSongs/Processed"
+ sudo -u pi ln -fs /tmp/StreamData "$HOME/BirdSongs/StreamData"
+ sudo -u pi ln -fs /tmp/Processed "$HOME/BirdSongs/Processed"
fi
-# Permissions for created files and folders
-echo "... set permissions to user pi"
+# Set permissions for created files and folders
+echo "... setting permissions for user pi"
chown -R pi:pi /config /etc/birdnet "$BIRDSONGS_FOLDER" /tmp
-chmod -R 755 /config /config /etc/birdnet "$BIRDSONGS_FOLDER" /tmp
+chmod -R 755 /config /etc/birdnet "$BIRDSONGS_FOLDER" /tmp
-# Save default birdnet.conf to perform sanity check
-cp "$HOME"/BirdNET-Pi/birdnet.conf "$HOME"/BirdNET-Pi/birdnet.bak
+# Backup default birdnet.conf for sanity check
+cp "$HOME/BirdNET-Pi/birdnet.conf" "$HOME/BirdNET-Pi/birdnet.bak"
-# Symlink files
-echo "... creating symlink"
-for files in "$HOME/BirdNET-Pi/birdnet.conf" "$HOME/BirdNET-Pi/scripts/whitelist_species_list.txt" "$HOME/BirdNET-Pi/blacklisted_images.txt" "$HOME/BirdNET-Pi/scripts/birds.db" "$HOME/BirdNET-Pi/BirdDB.txt" "$HOME/BirdNET-Pi/scripts/disk_check_exclude.txt" "$HOME/BirdNET-Pi/apprise.txt" "$HOME/BirdNET-Pi/exclude_species_list.txt" "$HOME/BirdNET-Pi/include_species_list.txt" "$HOME/BirdNET-Pi/IdentifiedSoFar.txt" "$HOME/BirdNET-Pi/scripts/confirmed_species_list.txt"; do
- filename="${files##*/}"
- if [ ! -f /config/"$filename" ]; then
- if [ -f "$files" ]; then
- echo "... copying $filename" && sudo -u pi mv "$files" /config/
- else
- touch /config/"$filename"
- fi
- fi
- if [ -e "$files" ]; then rm "$files"; fi
- sudo -u pi ln -fs /config/"$filename" "$HOME/BirdNET-Pi/$filename" || bashio::log.fatal "Symlink creation failed for $filename"
- sudo -u pi ln -fs /config/"$filename" "$HOME/BirdNET-Pi/scripts/$filename" || bashio::log.fatal "Symlink creation failed for $filename"
- sudo -u pi ln -fs /config/"$filename" /etc/birdnet/"$filename" || bashio::log.fatal "Symlink creation failed for $filename"
+# Symlink configuration files
+echo "... creating symlinks for configuration files"
+CONFIG_FILES=("$HOME/BirdNET-Pi/birdnet.conf" "$HOME/BirdNET-Pi/scripts/whitelist_species_list.txt" "$HOME/BirdNET-Pi/blacklisted_images.txt" "$HOME/BirdNET-Pi/scripts/birds.db" "$HOME/BirdNET-Pi/BirdDB.txt" "$HOME/BirdNET-Pi/scripts/disk_check_exclude.txt" "$HOME/BirdNET-Pi/apprise.txt" "$HOME/BirdNET-Pi/exclude_species_list.txt" "$HOME/BirdNET-Pi/include_species_list.txt" "$HOME/BirdNET-Pi/IdentifiedSoFar.txt" "$HOME/BirdNET-Pi/scripts/confirmed_species_list.txt")
+
+for file in "${CONFIG_FILES[@]}"; do
+ filename="${file##*/}"
+ [ ! -f "/config/$filename" ] && touch "/config/$filename"
+ [ -e "$file" ] && rm "$file"
+ sudo -u pi ln -fs "/config/$filename" "$file"
+ sudo -u pi ln -fs "/config/$filename" "$HOME/BirdNET-Pi/scripts/$filename"
+ sudo -u pi ln -fs "/config/$filename" "/etc/birdnet/$filename"
done
-# Symlink folders
-for folders in By_Date Charts; do
- echo "... creating symlink for $BIRDSONGS_FOLDER/$folders"
- rm -r "$HOME/BirdSongs/Extracted/${folders:?}"
- sudo -u pi ln -fs "$BIRDSONGS_FOLDER"/"$folders" "$HOME/BirdSongs/Extracted/$folders"
+# Symlink BirdSongs folders
+for folder in By_Date Charts; do
+ echo "... creating symlink for $BIRDSONGS_FOLDER/$folder"
+ [ -d "$HOME/BirdSongs/Extracted/${folder:?}" ] && rm -r "$HOME/BirdSongs/Extracted/$folder"
+ sudo -u pi ln -fs "$BIRDSONGS_FOLDER/$folder" "$HOME/BirdSongs/Extracted/$folder"
done
-# Permissions for created files and folders
-echo "... check permissions"
+# Set permissions for newly created files and folders
+echo "... checking and setting permissions"
chmod -R 755 /config/*
chmod 777 /config
-echo " "
+# Create Matplotlib configuration directory
+echo "... setting up Matplotlabdir"
+MPLCONFIGDIR="${MPLCONFIGDIR:-$HOME/.config/matplotlib}"
+mkdir -p "$MPLCONFIGDIR"
+chown pi:pi "$MPLCONFIGDIR"
+chmod 777 "$MPLCONFIGDIR"
+
diff --git a/battybirdnet-pi/rootfs/etc/cont-init.d/02-restorestreamdata.sh b/battybirdnet-pi/rootfs/etc/cont-init.d/02-restorestreamdata.sh
index 61fca2bc6..8ab4ae674 100755
--- a/battybirdnet-pi/rootfs/etc/cont-init.d/02-restorestreamdata.sh
+++ b/battybirdnet-pi/rootfs/etc/cont-init.d/02-restorestreamdata.sh
@@ -1,24 +1,36 @@
-#!/usr/bin/with-contenv bashio
+#!/command/with-contenv bashio
# shellcheck shell=bash
+set -e
-# Check if there are files in "$HOME"/BirdSongs/StreamData and move them to /data/StreamData
-if [ -d /data/StreamData ] && [ "$(ls -A /data/StreamData/)" ]; then
+if [ -d /data/StreamData ]; then
+ bashio::log.fatal "Container was stopped while files were still being analyzed."
- bashio::log.warning "Container was stopped while files were still being analysed, restoring them"
+ # Check if there are .wav files in /data/StreamData
+ if find /data/StreamData -type f -name "*.wav" | grep -q .; then
+ bashio::log.warning "Restoring .wav files from /data/StreamData to $HOME/BirdSongs/StreamData."
- # Copy files
- if [ "$(ls -A /data/StreamData)" ]; then
- mv -v /data/StreamData/* "$HOME"/BirdSongs/StreamData/
+ # Create the destination directory if it does not exist
+ mkdir -p "$HOME"/BirdSongs/StreamData
+
+ # Count the number of .wav files to be moved
+ file_count=$(find /data/StreamData -type f -name "*.wav" | wc -l)
+ echo "... found $file_count .wav files to restore."
+
+ # Move the .wav files using `mv` to avoid double log entries
+ mv -v /data/StreamData/*.wav "$HOME"/BirdSongs/StreamData/
+
+ # Update permissions only if files were moved successfully
+ if [ "$file_count" -gt 0 ]; then
+ chown -R pi:pi "$HOME"/BirdSongs/StreamData
+ fi
+
+ echo "... $file_count files restored successfully."
+ else
+ echo "... no .wav files found to restore."
fi
- echo "... done"
- echo ""
-
- # Setting permissions
- chown -R pi:pi "$HOME"/BirdSongs
- chmod -R 755 "$HOME"/BirdSongs
-
- # Cleaning folder
- rm -r /data/StreamData
+ # Clean up the source folder if it is empty
+ if [ -z "$(ls -A /data/StreamData)" ]; then
+ rm -r /data/StreamData
+ fi
fi
-
diff --git a/battybirdnet-pi/rootfs/etc/cont-init.d/31-checks.sh b/battybirdnet-pi/rootfs/etc/cont-init.d/31-checks.sh
index 47ffa5b77..48b727e3e 100755
--- a/battybirdnet-pi/rootfs/etc/cont-init.d/31-checks.sh
+++ b/battybirdnet-pi/rootfs/etc/cont-init.d/31-checks.sh
@@ -6,49 +6,55 @@ set -e
# CHECK BIRDNET.CONF #
######################
-echo " "
-bashio::log.info "Checking your birndet.conf file integrity"
+bashio::log.info "Checking your birdnet.conf file integrity"
# Set variables
configcurrent="$HOME"/BirdNET-Pi/birdnet.conf
configtemplate="$HOME"/BirdNET-Pi/birdnet.bak
+# Ensure both files exist before proceeding
+if [ ! -f "$configcurrent" ] || [ ! -f "$configtemplate" ]; then
+ bashio::log.fatal "Missing required birdnet.conf or birdnet.bak file. Please ensure both are present."
+ exit 1
+fi
+
# Extract variable names from config template and read each one
grep -o '^[^#=]*=' "$configtemplate" | sed 's/=//' | while read -r var; do
# Check if the variable is in configcurrent, if not, append it
if ! grep -q "^$var=" "$configcurrent"; then
- # At which line was the variable in the initial file
- bashio::log.yellow "...$var was missing from your birdnet.conf file, it was re-added"
+ bashio::log.warning "...$var was missing from your birdnet.conf file, it was re-added"
grep "^$var=" "$configtemplate" >> "$configcurrent"
fi
# Check for duplicates
if [ "$(grep -c "^$var=" "$configcurrent")" -gt 1 ]; then
- bashio::log.error "Duplicate variable $var found in $configcurrent, all were commented out expect for the first one"
- awk -v var="$var" '{ if ($0 ~ "^[[:blank:]]*"var && c++ > 0) print "#" $0; else print $0; }' "$configcurrent" > temp && mv temp "$configcurrent"
+ bashio::log.error "Duplicate variable $var found in $configcurrent, all were commented out except for the first one"
+ sed -i "0,/^$var=/!s/^$var=/#$var=/" "$configcurrent"
fi
done
-################
-# CHECK AMIXER #
-################
-
-# If default capture is set at 0%, increase it to 50%
-# current_volume="$(amixer sget Capture | grep -oP '\[\d+%]' | tr -d '[]%' | head -1)" 2>/dev/null || true
-# current_volume="${current_volume:-100}"
-
-# Set the default microphone volume to 50% if it's currently at 0%
-# if [[ "$current_volume" -eq 0 ]]; then
-# amixer sset Capture 70%
-# bashio::log.warning "Microphone was off, volume set to 70%."
-# fi
-
##############
# CHECK PORT #
##############
if [[ "$(bashio::addon.port "80")" == 3000 ]]; then
- bashio::log.fatal "This is crazy but your port is set to 3000 and streamlit doesn't accept this port! You need to change it from the addon options and restart. Thanks"
- sleep infinity
+ bashio::log.fatal "This is crazy but your port is set to 3000 and streamlit doesn't accept this port! You need to change it from the addon options and restart. Thanks"
+ sleep infinity
fi
-echo " "
+##################
+# PERFORM UPDATE #
+##################
+
+bashio::log.info "Performing potential updates"
+
+# Adapt update_birdnet_snippets
+sed -i "s|systemctl list-unit-files|false \&\& echo|g" "$HOME"/BirdNET-Pi/scripts/update_birdnet_snippets.sh
+sed -i "/systemctl /d" "$HOME"/BirdNET-Pi/scripts/update_birdnet_snippets.sh
+sed -i "/find /d" "$HOME"/BirdNET-Pi/scripts/update_birdnet_snippets.sh
+sed -i "/set -x/d" "$HOME"/BirdNET-Pi/scripts/update_birdnet_snippets.sh
+sed -i "/restart_services/d" "$HOME"/BirdNET-Pi/scripts/update_birdnet_snippets.sh
+sed -i "s|/etc/birdnet/birdnet.conf|/config/birdnet.conf|g" "$HOME"/BirdNET-Pi/scripts/update_birdnet_snippets.sh
+
+# Execute update_birdnet_snippets
+"$HOME"/BirdNET-Pi/scripts/update_birdnet_snippets.sh
+
diff --git a/battybirdnet-pi/rootfs/etc/cont-init.d/33-mqtt.sh b/battybirdnet-pi/rootfs/etc/cont-init.d/33-mqtt.sh
deleted file mode 100755
index ed1585c99..000000000
--- a/battybirdnet-pi/rootfs/etc/cont-init.d/33-mqtt.sh
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/with-contenv bashio
-# shellcheck shell=bash
-set -e
-
-# Function to perform common setup steps
-common_steps () {
- # Attempt to connect to the MQTT broker
- TOPIC="birdnet"
- if mosquitto_pub -h "$MQTT_HOST" -p "$MQTT_PORT" -t "$TOPIC" -m "test" -u "$MQTT_USER" -P "$MQTT_PASS" -q 1 -d --will-topic "$TOPIC" --will-payload "Disconnected" --will-qos 1 --will-retain > /dev/null 2>&1; then
- # Adapt script with MQTT settings
- sed -i "s|%%mqtt_server%%|$MQTT_HOST|g" /helpers/birdnet_to_mqtt.py
- sed -i "s|%%mqtt_port%%|$MQTT_PORT|g" /helpers/birdnet_to_mqtt.py
- sed -i "s|%%mqtt_user%%|$MQTT_USER|g" /helpers/birdnet_to_mqtt.py
- sed -i "s|%%mqtt_pass%%|$MQTT_PASS|g" /helpers/birdnet_to_mqtt.py
-
- # Copy script to the appropriate directory
- cp /helpers/birdnet_to_mqtt.py "$HOME"/BirdNET-Pi/scripts/utils/birdnet_to_mqtt.py
- chown pi:pi "$HOME"/BirdNET-Pi/scripts/utils/birdnet_to_mqtt.py
- chmod +x "$HOME"/BirdNET-Pi/scripts/utils/birdnet_to_mqtt.py
-
- # Add hooks to the main analysis script
- sed -i "/load_global_model, run_analysis/a from utils.birdnet_to_mqtt import automatic_mqtt_publish" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
- sed -i '/write_to_db(/a\ automatic_mqtt_publish(file, detection, os.path.basename(detection.file_name_extr))' "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
- else
- bashio::log.fatal "MQTT connection failed, it will not be configured. Error message :"
- mosquitto_pub -h "$MQTT_HOST" -p "$MQTT_PORT" -t "$TOPIC" -m "test" -u "$MQTT_USER" -P "$MQTT_PASS" -q 1 -d --will-topic "$TOPIC" --will-payload "Disconnected" --will-qos 1 --will-retain
- fi
-}
-
-# Check if MQTT service is available and not disabled
-if bashio::services.available 'mqtt' && ! bashio::config.true 'MQTT_DISABLED'; then
- bashio::log.green "---"
- bashio::log.blue "MQTT addon is active on your system! BirdNET-Pi is now automatically configured to send its output to MQTT"
- bashio::log.blue "MQTT user : $(bashio::services "mqtt" "username")"
- bashio::log.blue "MQTT password : $(bashio::services "mqtt" "password")"
- bashio::log.blue "MQTT broker : tcp://$(bashio::services "mqtt" "host"):$(bashio::services "mqtt" "port")"
- bashio::log.green "---"
- bashio::log.blue "Data will be posted to the topic : 'birdnet'"
- bashio::log.blue "Json data : {'Date', 'Time', 'ScientificName', 'CommonName', 'Confidence', 'SpeciesCode', 'ClipName', 'url'}"
- bashio::log.blue "---"
-
- # Apply MQTT settings
- MQTT_HOST="$(bashio::services "mqtt" "host")"
- MQTT_PORT="$(bashio::services "mqtt" "port")"
- MQTT_USER="$(bashio::services "mqtt" "username")"
- MQTT_PASS="$(bashio::services "mqtt" "password")"
-
- # Perform common setup steps
- common_steps
-
-# Check if manual MQTT configuration is provided
-elif bashio::config.has_value "MQTT_HOST_manual" && bashio::config.has_value "MQTT_PORT_manual"; then
- bashio::log.green "---"
- bashio::log.blue "MQTT is manually configured in the addon options"
- bashio::log.blue "BirdNET-Pi is now automatically configured to send its output to MQTT"
- bashio::log.green "---"
- bashio::log.blue "Data will be posted to the topic : 'birdnet'"
- bashio::log.blue "Json data : {'Date', 'Time', 'ScientificName', 'CommonName', 'Confidence', 'SpeciesCode', 'ClipName', 'url'}"
- bashio::log.blue "---"
-
- # Apply manual MQTT settings
- MQTT_HOST="$(bashio::config "MQTT_HOST_manual")"
- MQTT_PORT="$(bashio::config "MQTT_PORT_manual")"
- MQTT_USER="$(bashio::config "MQTT_USER_manual")"
- MQTT_PASS="$(bashio::config "MQTT_PASSWORD_manual")"
-
- # Perform common setup steps
- common_steps
-
-fi
diff --git a/battybirdnet-pi/rootfs/etc/cont-init.d/71-newfeatures.sh b/battybirdnet-pi/rootfs/etc/cont-init.d/71-newfeatures.sh
deleted file mode 100755
index b4fbae83a..000000000
--- a/battybirdnet-pi/rootfs/etc/cont-init.d/71-newfeatures.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/command/with-contenv bashio
-# shellcheck shell=bash
-set -e
-
-################
-# ADD FEATURES #
-################
-
-echo " "
-bashio::log.info "Adding optional features"
-
-# Denoiser
-#if bashio::config.true "DENOISER_ANALYSIS_ENABLED"; then
-# sed -i "s|ar 48000|ar 48000 -af \"arnndn=m=sample.rnnn\"|g" "$HOME"/BirdNET-Pi/scripts/birdnet_recording.sh
-# sed -i "s|ar 48000|ar 48000 -af afftdn=nr=30:nt=w:om=o|g" "$HOME"/BirdNET-Pi/scripts/birdnet_recording.sh
-#fi
-
-# Enable the Processed folder
-#############################
-
-if bashio::config.true "PROCESSED_FOLDER_ENABLED" && ! grep -q "processed_size" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py; then
- echo "... Enabling the Processed folder : the last 15 wav files will be stored there"
- # Adapt config.php
- sed -i "/GET\[\"info_site\"\]/a\ \$processed_size = \$_GET\[\"processed_size\"\];" "$HOME"/BirdNET-Pi/scripts/config.php
- sed -i "/\$contents = file_get_contents/a\ \$contents = preg_replace\(\"/PROCESSED_SIZE=\.\*/\", \"PROCESSED_SIZE=\$processed_size\", \$contents\);" "$HOME"/BirdNET-Pi/scripts/config.php
- sed -i "/\"success\"/i
" "$HOME"/BirdNET-Pi/scripts/config.php
- sed -i "/\"success\"/i Processed folder management" "$HOME"/BirdNET-Pi/scripts/config.php - sed -i "/\"success\"/i " "$HOME"/BirdNET-Pi/scripts/config.php - sed -i "/\"success\"/i \"/>" "$HOME"/BirdNET-Pi/scripts/config.php - sed -i "/\"success\"/i |
| " "$HOME"/BirdNET-Pi/scripts/config.php
- sed -i "/\"success\"/i Processed is the directory where the formerly 'Analyzed' files are moved after extractions, mostly for troubleshooting purposes. " "$HOME"/BirdNET-Pi/scripts/config.php - sed -i "/\"success\"/i This value defines the maximum amount of files that are kept before replacement with new files. " "$HOME"/BirdNET-Pi/scripts/config.php - sed -i "/\"success\"/i |