mirror of
https://github.com/alexbelgium/hassio-addons.git
synced 2026-05-31 12:54:04 +02:00
Update
This commit is contained in:
@@ -119,6 +119,6 @@
|
|||||||
"udev": true,
|
"udev": true,
|
||||||
"url": "https://github.com/alexbelgium/hassio-addons/tree/master/battybirdnet-pi",
|
"url": "https://github.com/alexbelgium/hassio-addons/tree/master/battybirdnet-pi",
|
||||||
"usb": true,
|
"usb": true,
|
||||||
"version": "0.6",
|
"version": "0.7",
|
||||||
"video": true
|
"video": true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,93 +1,100 @@
|
|||||||
#!/usr/bin/with-contenv bashio
|
#!/usr/bin/env bash
|
||||||
# shellcheck shell=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"
|
log_red() { echo -e "\033[31m$1\033[0m" }
|
||||||
touch "$HOME"/BirdSongs/StreamData/analyzing_now.txt
|
|
||||||
|
|
||||||
# variables for readability
|
log_yellow() { echo -e "\033[33m$1\033[0m" }
|
||||||
srv="birdnet_recording"
|
|
||||||
analyzing_now="."
|
log_info() { echo -e "\033[34m$1\033[0m" }
|
||||||
counter=10
|
|
||||||
set +u
|
echo "$(log_green "Starting service: throttlerecording")"
|
||||||
# shellcheck disable=SC1091
|
touch "$HOME/BirdSongs/StreamData/analyzing_now.txt"
|
||||||
|
|
||||||
|
# Read configuration
|
||||||
source /config/birdnet.conf 2>/dev/null
|
source /config/birdnet.conf 2>/dev/null
|
||||||
|
|
||||||
# Ensure folder exists
|
# Set constants
|
||||||
|
srv="birdnet_recording"
|
||||||
|
srv2="birdnet_analysis"
|
||||||
ingest_dir="$RECS_DIR/StreamData"
|
ingest_dir="$RECS_DIR/StreamData"
|
||||||
|
counter=10
|
||||||
|
|
||||||
# Check permissions
|
# Ensure directories and permissions
|
||||||
mkdir -p "$ingest_dir"
|
|
||||||
chown -R pi:pi "$ingest_dir"
|
|
||||||
chmod -R 755 "$ingest_dir"
|
|
||||||
ingest_dir="$(readlink -f "$ingest_dir")" || true
|
|
||||||
mkdir -p "$ingest_dir"
|
mkdir -p "$ingest_dir"
|
||||||
chown -R pi:pi "$ingest_dir"
|
chown -R pi:pi "$ingest_dir"
|
||||||
chmod -R 755 "$ingest_dir"
|
chmod -R 755 "$ingest_dir"
|
||||||
|
|
||||||
function apprisealert() {
|
# Function to send notifications using Apprise
|
||||||
# Set failed check so it only runs once
|
apprisealert() {
|
||||||
touch "$HOME"/BirdNET-Pi/failed_servicescheck
|
local notification=""
|
||||||
NOTIFICATION=""
|
local stopped_service="<br><b>Stopped services:</b> "
|
||||||
STOPPEDSERVICE="<br><b>Stopped services:</b> "
|
|
||||||
services=(birdnet_analysis
|
# Check for stopped services
|
||||||
chart_viewer
|
services=(birdnet_analysis chart_viewer spectrogram_viewer icecast2 birdnet_recording birdnet_log birdnet_stats)
|
||||||
spectrogram_viewer
|
for service in "${services[@]}"; do
|
||||||
icecast2
|
if [[ "$(systemctl is-active "$service")" == "inactive" ]]; then
|
||||||
birdnet_recording
|
stopped_service+="$service; "
|
||||||
birdnet_log
|
|
||||||
birdnet_stats)
|
|
||||||
for i in "${services[@]}"; do
|
|
||||||
if [[ "$(sudo systemctl is-active "${i}".service)" == "inactive" ]]; then
|
|
||||||
STOPPEDSERVICE+="${i}; "
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
NOTIFICATION+="$STOPPEDSERVICE"
|
|
||||||
NOTIFICATION+="<br><b>Additional informations</b>: "
|
# Build notification message
|
||||||
NOTIFICATION+="<br><b>Since:</b> ${LASTCHECK:-unknown}"
|
notification+="$stopped_service"
|
||||||
NOTIFICATION+="<br><b>System:</b> ${SITE_NAME:-$(hostname)}"
|
notification+="<br><b>Additional information</b>: "
|
||||||
NOTIFICATION+="<br>Available disk space: $(df -h "$(readlink -f "$HOME/BirdSongs")" | awk 'NR==2 {print $4}')"
|
notification+="<br><b>Since:</b> ${LASTCHECK:-unknown}"
|
||||||
if [ -n "$BIRDNETPI_URL" ]; then
|
notification+="<br><b>System:</b> ${SITE_NAME:-$(hostname)}"
|
||||||
NOTIFICATION+="<br> <a href=\"$BIRDNETPI_URL\">Access your BirdNET-Pi</a>"
|
notification+="<br>Available disk space: $(df -h "$HOME/BirdSongs" | awk 'NR==2 {print $4}')"
|
||||||
fi
|
[[ -n "$BIRDNETPI_URL" ]] && notification+="<br><a href=\"$BIRDNETPI_URL\">Access your BirdNET-Pi</a>"
|
||||||
|
|
||||||
|
# Send notification
|
||||||
TITLE="BirdNET-Analyzer stopped"
|
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
|
while true; do
|
||||||
sleep 61
|
sleep 61
|
||||||
|
|
||||||
# Restart analysis if clogged
|
# Restart analysis if clogged
|
||||||
############################
|
|
||||||
|
|
||||||
if ((counter <= 0)); then
|
if ((counter <= 0)); then
|
||||||
latest="$(cat "$ingest_dir"/analyzing_now.txt)"
|
current_file="$(cat "$ingest_dir/analyzing_now.txt")"
|
||||||
if [[ "$latest" == "$analyzing_now" ]]; then
|
if [[ "$current_file" == "$analyzing_now" ]]; then
|
||||||
echo "$(date) WARNING no change in analyzing_now for 10 iterations, restarting services"
|
log_yellow "$(date) WARNING: no change in analyzing_now for 10 iterations, restarting services"
|
||||||
/."$HOME"/BirdNET-Pi/scripts/restart_services.sh
|
"$HOME/BirdNET-Pi/scripts/restart_services.sh"
|
||||||
fi
|
fi
|
||||||
counter=10
|
counter=10
|
||||||
analyzing_now=$(cat "$ingest_dir"/analyzing_now.txt)
|
analyzing_now="$current_file"
|
||||||
fi
|
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)"
|
log_green "$(date) INFO: $wav_count wav files waiting in $ingest_dir, $srv state is $service_state, $srv2 state is $analysis_state"
|
||||||
state="$(systemctl is-active "$srv")"
|
|
||||||
|
|
||||||
bashio::log.green "$(date) INFO ${wavs} wav files waiting in $ingest_dir, $srv state is $state"
|
# Pause recorder if queue is too large
|
||||||
|
if ((wav_count > 50)); then
|
||||||
if ((wavs > 100)); then
|
log_red "$(date) WARNING: Too many files in queue, pausing $srv and restarting $srv2"
|
||||||
bashio::log.red "$(date) WARNING too many files in queue, pausing $srv"
|
|
||||||
sudo systemctl stop "$srv"
|
sudo systemctl stop "$srv"
|
||||||
sudo systemctl restart birdnet_analysis
|
sudo systemctl restart "$srv2"
|
||||||
if [ -s "$HOME/BirdNET-Pi/apprise.txt" ]; then apprisealert; fi
|
[[ -s "$HOME/BirdNET-Pi/apprise.txt" ]] && apprisealert
|
||||||
elif [[ "$state" != "active" ]]; then
|
elif ((wav_count > 30)); then
|
||||||
bashio::log.yellow "$(date) INFO started $srv service"
|
log_red "$(date) WARNING: Too many files in queue, restarting $srv2"
|
||||||
sudo systemctl start $srv
|
sudo systemctl restart "$srv2"
|
||||||
sudo systemctl restart birdnet_analysis
|
[[ -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
|
fi
|
||||||
|
|
||||||
((counter--))
|
((counter--))
|
||||||
|
|||||||
@@ -2,17 +2,34 @@
|
|||||||
# shellcheck shell=bash
|
# shellcheck shell=bash
|
||||||
|
|
||||||
if [ -d "$HOME"/BirdSongs/StreamData ]; then
|
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
|
# Stop the services in parallel
|
||||||
systemctl stop birdnet_analysis &
|
if systemctl is-active --quiet birdnet_analysis; then
|
||||||
systemctl stop birdnet_recording
|
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
|
# Check if there are files in StreamData and move them to /data/StreamData
|
||||||
mkdir -p /data/StreamData
|
mkdir -p /data/StreamData
|
||||||
if [ "$(ls -A "$HOME"/BirdSongs/StreamData)" ]; then
|
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
|
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
|
fi
|
||||||
|
|||||||
@@ -6,20 +6,19 @@ set -e
|
|||||||
# SET /CONFIG #
|
# 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"
|
echo "... creating default files"
|
||||||
touch /config/include_species_list.txt # Should be null
|
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")
|
||||||
touch /home/pi/BirdNET-Pi/scripts/thisrun.txt
|
for file in "${DEFAULT_FILES[@]}"; do
|
||||||
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/$file" ]; then
|
||||||
if [ ! -f /config/"$files" ]; then
|
echo "" > "/config/$file"
|
||||||
echo "" > /config/"$files"
|
|
||||||
fi
|
fi
|
||||||
done
|
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"
|
BIRDSONGS_FOLDER="/config/BirdSongs"
|
||||||
if bashio::config.has_value "BIRDSONGS_FOLDER"; then
|
if bashio::config.has_value "BIRDSONGS_FOLDER"; then
|
||||||
BIRDSONGS_FOLDER_OPTION="$(bashio::config "BIRDSONGS_FOLDER")"
|
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
|
if [ -d "$BIRDSONGS_FOLDER_OPTION" ] && [ "$(stat -c '%u:%g' "$BIRDSONGS_FOLDER_OPTION")" == "1000:1000" ]; then
|
||||||
BIRDSONGS_FOLDER="$BIRDSONGS_FOLDER_OPTION"
|
BIRDSONGS_FOLDER="$BIRDSONGS_FOLDER_OPTION"
|
||||||
else
|
else
|
||||||
bashio::log.yellow "BIRDSONGS_FOLDER reverted to /config/BirdSongs"
|
bashio::log.warning "BIRDSONGS_FOLDER reverted to /config/BirdSongs"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create BirdSongs folder
|
# Create default folders
|
||||||
echo "... creating default folders ; it is highly recommended to store those on a ssd"
|
echo "... creating default folders; it is highly recommended to store these on an SSD"
|
||||||
mkdir -p "$BIRDSONGS_FOLDER"/By_Date
|
mkdir -p "$BIRDSONGS_FOLDER/By_Date" "$BIRDSONGS_FOLDER/Charts"
|
||||||
mkdir -p "$BIRDSONGS_FOLDER"/Charts
|
|
||||||
|
|
||||||
# If tmpfs is installed, use it
|
# Use tmpfs if installed
|
||||||
if df -T /tmp | grep -q "tmpfs"; then
|
if df -T /tmp | grep -q "tmpfs"; then
|
||||||
echo "... tmpfs detected, using it for StreamData and Processed to reduce disk wear"
|
echo "... tmpfs detected, using it for StreamData and Processed to reduce disk wear"
|
||||||
mkdir -p /tmp/StreamData
|
mkdir -p /tmp/StreamData /tmp/Processed
|
||||||
mkdir -p /tmp/Processed
|
[ -d "$HOME/BirdSongs/StreamData" ] && rm -r "$HOME/BirdSongs/StreamData"
|
||||||
if [ -d "$HOME"/BirdSongs/StreamData ]; then
|
[ -d "$HOME/BirdSongs/Processed" ] && rm -r "$HOME/BirdSongs/Processed"
|
||||||
rm -r "$HOME"/BirdSongs/StreamData
|
sudo -u pi ln -fs /tmp/StreamData "$HOME/BirdSongs/StreamData"
|
||||||
fi
|
sudo -u pi ln -fs /tmp/Processed "$HOME/BirdSongs/Processed"
|
||||||
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
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Permissions for created files and folders
|
# Set permissions for created files and folders
|
||||||
echo "... set permissions to user pi"
|
echo "... setting permissions for user pi"
|
||||||
chown -R pi:pi /config /etc/birdnet "$BIRDSONGS_FOLDER" /tmp
|
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
|
# Backup default birdnet.conf for sanity check
|
||||||
cp "$HOME"/BirdNET-Pi/birdnet.conf "$HOME"/BirdNET-Pi/birdnet.bak
|
cp "$HOME/BirdNET-Pi/birdnet.conf" "$HOME/BirdNET-Pi/birdnet.bak"
|
||||||
|
|
||||||
# Symlink files
|
# Symlink configuration files
|
||||||
echo "... creating symlink"
|
echo "... creating symlinks for configuration files"
|
||||||
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
|
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")
|
||||||
filename="${files##*/}"
|
|
||||||
if [ ! -f /config/"$filename" ]; then
|
for file in "${CONFIG_FILES[@]}"; do
|
||||||
if [ -f "$files" ]; then
|
filename="${file##*/}"
|
||||||
echo "... copying $filename" && sudo -u pi mv "$files" /config/
|
[ ! -f "/config/$filename" ] && touch "/config/$filename"
|
||||||
else
|
[ -e "$file" ] && rm "$file"
|
||||||
touch /config/"$filename"
|
sudo -u pi ln -fs "/config/$filename" "$file"
|
||||||
fi
|
sudo -u pi ln -fs "/config/$filename" "$HOME/BirdNET-Pi/scripts/$filename"
|
||||||
fi
|
sudo -u pi ln -fs "/config/$filename" "/etc/birdnet/$filename"
|
||||||
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"
|
|
||||||
done
|
done
|
||||||
|
|
||||||
# Symlink folders
|
# Symlink BirdSongs folders
|
||||||
for folders in By_Date Charts; do
|
for folder in By_Date Charts; do
|
||||||
echo "... creating symlink for $BIRDSONGS_FOLDER/$folders"
|
echo "... creating symlink for $BIRDSONGS_FOLDER/$folder"
|
||||||
rm -r "$HOME/BirdSongs/Extracted/${folders:?}"
|
[ -d "$HOME/BirdSongs/Extracted/${folder:?}" ] && rm -r "$HOME/BirdSongs/Extracted/$folder"
|
||||||
sudo -u pi ln -fs "$BIRDSONGS_FOLDER"/"$folders" "$HOME/BirdSongs/Extracted/$folders"
|
sudo -u pi ln -fs "$BIRDSONGS_FOLDER/$folder" "$HOME/BirdSongs/Extracted/$folder"
|
||||||
done
|
done
|
||||||
|
|
||||||
# Permissions for created files and folders
|
# Set permissions for newly created files and folders
|
||||||
echo "... check permissions"
|
echo "... checking and setting permissions"
|
||||||
chmod -R 755 /config/*
|
chmod -R 755 /config/*
|
||||||
chmod 777 /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"
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,36 @@
|
|||||||
#!/usr/bin/with-contenv bashio
|
#!/command/with-contenv bashio
|
||||||
# shellcheck shell=bash
|
# shellcheck shell=bash
|
||||||
|
set -e
|
||||||
|
|
||||||
# Check if there are files in "$HOME"/BirdSongs/StreamData and move them to /data/StreamData
|
if [ -d /data/StreamData ]; then
|
||||||
if [ -d /data/StreamData ] && [ "$(ls -A /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
|
# Create the destination directory if it does not exist
|
||||||
if [ "$(ls -A /data/StreamData)" ]; then
|
mkdir -p "$HOME"/BirdSongs/StreamData
|
||||||
mv -v /data/StreamData/* "$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
|
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
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -6,49 +6,55 @@ set -e
|
|||||||
# CHECK BIRDNET.CONF #
|
# CHECK BIRDNET.CONF #
|
||||||
######################
|
######################
|
||||||
|
|
||||||
echo " "
|
bashio::log.info "Checking your birdnet.conf file integrity"
|
||||||
bashio::log.info "Checking your birndet.conf file integrity"
|
|
||||||
|
|
||||||
# Set variables
|
# Set variables
|
||||||
configcurrent="$HOME"/BirdNET-Pi/birdnet.conf
|
configcurrent="$HOME"/BirdNET-Pi/birdnet.conf
|
||||||
configtemplate="$HOME"/BirdNET-Pi/birdnet.bak
|
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
|
# Extract variable names from config template and read each one
|
||||||
grep -o '^[^#=]*=' "$configtemplate" | sed 's/=//' | while read -r var; do
|
grep -o '^[^#=]*=' "$configtemplate" | sed 's/=//' | while read -r var; do
|
||||||
# Check if the variable is in configcurrent, if not, append it
|
# Check if the variable is in configcurrent, if not, append it
|
||||||
if ! grep -q "^$var=" "$configcurrent"; then
|
if ! grep -q "^$var=" "$configcurrent"; then
|
||||||
# At which line was the variable in the initial file
|
bashio::log.warning "...$var was missing from your birdnet.conf file, it was re-added"
|
||||||
bashio::log.yellow "...$var was missing from your birdnet.conf file, it was re-added"
|
|
||||||
grep "^$var=" "$configtemplate" >> "$configcurrent"
|
grep "^$var=" "$configtemplate" >> "$configcurrent"
|
||||||
fi
|
fi
|
||||||
# Check for duplicates
|
# Check for duplicates
|
||||||
if [ "$(grep -c "^$var=" "$configcurrent")" -gt 1 ]; then
|
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"
|
bashio::log.error "Duplicate variable $var found in $configcurrent, all were commented out except for the first one"
|
||||||
awk -v var="$var" '{ if ($0 ~ "^[[:blank:]]*"var && c++ > 0) print "#" $0; else print $0; }' "$configcurrent" > temp && mv temp "$configcurrent"
|
sed -i "0,/^$var=/!s/^$var=/#$var=/" "$configcurrent"
|
||||||
fi
|
fi
|
||||||
done
|
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 #
|
# CHECK PORT #
|
||||||
##############
|
##############
|
||||||
|
|
||||||
if [[ "$(bashio::addon.port "80")" == 3000 ]]; then
|
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"
|
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
|
sleep infinity
|
||||||
fi
|
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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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 <table class=\"settingstable\"><tr><td>" "$HOME"/BirdNET-Pi/scripts/config.php
|
|
||||||
sed -i "/\"success\"/i <h2>Processed folder management </h2>" "$HOME"/BirdNET-Pi/scripts/config.php
|
|
||||||
sed -i "/\"success\"/i <label for=\"processed_size\">Amount of files to keep after analysis :</label>" "$HOME"/BirdNET-Pi/scripts/config.php
|
|
||||||
sed -i "/\"success\"/i <input name=\"processed_size\" type=\"number\" style=\"width:6em;\" max=\"90\" min=\"0\" step=\"1\" value=\"<\?php print(\$config\['PROCESSED_SIZE'\]);?>\"/>" "$HOME"/BirdNET-Pi/scripts/config.php
|
|
||||||
sed -i "/\"success\"/i </td></tr><tr><td>" "$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.<br>" "$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.<br>" "$HOME"/BirdNET-Pi/scripts/config.php
|
|
||||||
sed -i "/\"success\"/i </td></tr></table>" "$HOME"/BirdNET-Pi/scripts/config.php
|
|
||||||
sed -i "/\"success\"/i\ <br>" "$HOME"/BirdNET-Pi/scripts/config.php
|
|
||||||
# Adapt birdnet_analysis.py - move_to_processed
|
|
||||||
sed -i "/log.info('handle_reporting_queue done')/a\ os.remove(files.pop(0))" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/log.info('handle_reporting_queue done')/a\ while len(files) > processed_size:" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/log.info('handle_reporting_queue done')/a\ files.sort(key=os.path.getmtime)" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/log.info('handle_reporting_queue done')/a\ files = glob.glob(os.path.join(processed_dir, '*'))" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/log.info('handle_reporting_queue done')/a\ os.rename(file_name, os.path.join(processed_dir, os.path.basename(file_name)))" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/log.info('handle_reporting_queue done')/a\ processed_dir = os.path.join(get_settings()['RECS_DIR'], 'Processed')" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/log.info('handle_reporting_queue done')/a\def move_to_processed(file_name, processed_size):" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/log.info('handle_reporting_queue done')/a\ " "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
# Adapt birdnet_analysis.py - get_processed_size
|
|
||||||
sed -i "/log.info('handle_reporting_queue done')/a\ return 0" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/log.info('handle_reporting_queue done')/a\ except (ValueError, TypeError):" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/log.info('handle_reporting_queue done')/a\ return processed_size if isinstance(processed_size, int) else 0" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/log.info('handle_reporting_queue done')/a\ processed_size = get_settings().getint('PROCESSED_SIZE')" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/log.info('handle_reporting_queue done')/a\ try:" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/log.info('handle_reporting_queue done')/a\def get_processed_size():" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/log.info('handle_reporting_queue done')/a\ " "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
# Modify calls
|
|
||||||
sed -i "/from subprocess import CalledProcessError/a\import glob" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/from subprocess import CalledProcessError/a\import time" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
# Modify main code
|
|
||||||
sed -i "/os.remove(file.file_name)/i\ processed_size = get_processed_size()" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/os.remove(file.file_name)/i\ if processed_size > 0:" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/os.remove(file.file_name)/i\ move_to_processed(file.file_name, processed_size)" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/os.remove(file.file_name)/i\ else:" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
sed -i "/os.remove(file.file_name)/c\ os.remove(file.file_name)" "$HOME"/BirdNET-Pi/scripts/birdnet_analysis.py
|
|
||||||
fi || true
|
|
||||||
|
|
||||||
echo " "
|
|
||||||
@@ -6,61 +6,81 @@ set -e
|
|||||||
# MODIFY WEBUI #
|
# MODIFY WEBUI #
|
||||||
################
|
################
|
||||||
|
|
||||||
echo " "
|
|
||||||
bashio::log.info "Adapting webui"
|
bashio::log.info "Adapting webui"
|
||||||
|
|
||||||
# Remove services tab
|
# Remove services tab from webui
|
||||||
echo "... removing System Controls from webui as should be used from HA"
|
echo "... removing System Controls from webui as should be used from HA"
|
||||||
sed -i '/>System Controls/d' "$HOME"/BirdNET-Pi/homepage/views.php
|
sed -i '/>System Controls/d' "$HOME/BirdNET-Pi/homepage/views.php"
|
||||||
|
|
||||||
# Remove services tab
|
# Remove Ram drive option from webui
|
||||||
echo "... removing Ram drive from webui as it is handled from HA"
|
echo "... removing Ram drive from webui as it is handled from HA"
|
||||||
sed -i '/Ram drive/{n;s/center"/center" style="display: none;"/;}' "$HOME"/BirdNET-Pi/scripts/service_controls.php
|
sed -i '/Ram drive/{n;s/center"/center" style="display: none;"/;}' "$HOME/BirdNET-Pi/scripts/service_controls.php"
|
||||||
sed -i '/Ram drive/d' "$HOME"/BirdNET-Pi/scripts/service_controls.php
|
sed -i '/Ram drive/d' "$HOME/BirdNET-Pi/scripts/service_controls.php"
|
||||||
|
|
||||||
# Correct services to start as user pi
|
# Correct services to start as user pi
|
||||||
echo "... correct services to start as pi"
|
echo "... updating services to start as user pi"
|
||||||
for file in $(find "$HOME"/BirdNET-Pi/templates/birdnet*.service -print0 | xargs -0 basename -a) livestream.service chart_viewer.service chart_viewer.service spectrogram_viewer.service; do
|
while IFS= read -r file; do
|
||||||
if [[ "$file" != "birdnet_log.service" ]]; then
|
if [[ "$(basename "$file")" != "birdnet_log.service" ]]; then
|
||||||
sed -i "s|ExecStart=|ExecStart=/usr/bin/sudo -u pi |g" "$HOME/BirdNET-Pi/templates/$file"
|
sed -i "s|ExecStart=|ExecStart=/usr/bin/sudo -u pi |g" "$file"
|
||||||
fi
|
fi
|
||||||
done
|
done < <(find "$HOME/BirdNET-Pi/templates/" -name "birdnet*.service" -print)
|
||||||
|
|
||||||
# Send services log to container logs
|
# Send services log to container logs
|
||||||
echo "... send services log to container logs"
|
echo "... redirecting services logs to container logs"
|
||||||
for file in $(find "$HOME"/BirdNET-Pi/templates/birdnet*.service -print0 | xargs -0 basename -a) livestream.service chart_viewer.service chart_viewer.service spectrogram_viewer.service; do
|
while IFS= read -r file; do
|
||||||
sed -i "/Service/a StandardError=append:/proc/1/fd/1" "$HOME/BirdNET-Pi/templates/$file"
|
sed -i "/Service/a StandardError=append:/proc/1/fd/1" "$file"
|
||||||
sed -i "/Service/a StandardOutput=append:/proc/1/fd/1" "$HOME/BirdNET-Pi/templates/$file"
|
sed -i "/Service/a StandardOutput=append:/proc/1/fd/1" "$file"
|
||||||
done
|
done < <(find "$HOME/BirdNET-Pi/templates/" -name "birdnet*.service" -print)
|
||||||
|
|
||||||
# Avoid preselection in include and exclude lists
|
# Avoid preselection in include and exclude lists
|
||||||
echo "... avoid preselecting options in include and exclude lists"
|
echo "... disabling preselecting options in include and exclude lists"
|
||||||
sed -i "s|option selected|option disabled|g" "$HOME"/BirdNET-Pi/scripts/include_list.php
|
sed -i "s|option selected|option disabled|g" "$HOME/BirdNET-Pi/scripts/include_list.php"
|
||||||
sed -i "s|option selected|option disabled|g" "$HOME"/BirdNET-Pi/scripts/exclude_list.php
|
sed -i "s|option selected|option disabled|g" "$HOME/BirdNET-Pi/scripts/exclude_list.php"
|
||||||
|
|
||||||
# Correct log services to show /proc/1/fd/1
|
# Correct log services to show /proc/1/fd/1
|
||||||
echo "... show container logs in /logs"
|
echo "... redirecting birdnet_log service output to /logs"
|
||||||
sed -i "/User=pi/d" "$HOME/BirdNET-Pi/templates/birdnet_log.service"
|
sed -i "/User=pi/d" "$HOME/BirdNET-Pi/templates/birdnet_log.service"
|
||||||
sed -i "s|birdnet_log.sh|cat /proc/1/fd/1|g" "$HOME/BirdNET-Pi/templates/birdnet_log.service"
|
sed -i "s|birdnet_log.sh|cat /proc/1/fd/1|g" "$HOME/BirdNET-Pi/templates/birdnet_log.service"
|
||||||
|
|
||||||
# Make sure config is correctly formatted.
|
# Caddyfile modifications
|
||||||
echo "... caddyfile modifications"
|
echo "... modifying Caddyfile configurations"
|
||||||
#Correct instructions
|
|
||||||
caddy fmt --overwrite /etc/caddy/Caddyfile
|
caddy fmt --overwrite /etc/caddy/Caddyfile
|
||||||
#Change port to leave 80 free for certificate requests
|
#Change port to leave 80 free for certificate requests
|
||||||
sed -i "s|http://|http://:8081|g" /etc/caddy/Caddyfile
|
sed -i "s|http://|http://:8081|g" /etc/caddy/Caddyfile
|
||||||
sed -i "s|http://|http://:8081|g" "$HOME"/BirdNET-Pi/scripts/update_caddyfile.sh
|
sed -i "s|http://|http://:8081|g" "$HOME/BirdNET-Pi/scripts/update_caddyfile.sh"
|
||||||
#Remove default file that blocks 80
|
if [ -f /etc/caddy/Caddyfile.original ]; then
|
||||||
if [ -f /etc/caddy/Caddyfile.original ]; then rm /etc/caddy/Caddyfile.original; fi
|
rm /etc/caddy/Caddyfile.original
|
||||||
|
|
||||||
# Improve webui paths to facilitate ingress
|
|
||||||
echo "... correcting webui paths"
|
|
||||||
sed -i "s|/stats|/stats/|g" "$HOME"/BirdNET-Pi/homepage/views.php
|
|
||||||
sed -i "s|/log|/log/|g" "$HOME"/BirdNET-Pi/homepage/views.php
|
|
||||||
|
|
||||||
# If port 80 is enabled, make sure it is still 80
|
|
||||||
if [ -n "$(bashio::addon.port 80)" ] && [ "$(bashio::addon.port 80)" != 80 ]; then
|
|
||||||
bashio::log.fatal "The port 80 is enabled, but should still be 80 if you want the automatic ssl certificates generation to work"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo " "
|
# Correct webui paths
|
||||||
|
echo "... correcting webui paths"
|
||||||
|
sed -i "s|/stats|/stats/|g" "$HOME/BirdNET-Pi/homepage/views.php"
|
||||||
|
sed -i "s|/log|/log/|g" "$HOME/BirdNET-Pi/homepage/views.php"
|
||||||
|
|
||||||
|
# Check if port 80 is correctly configured
|
||||||
|
if [ -n "$(bashio::addon.port 80)" ] && [ "$(bashio::addon.port 80)" != 80 ]; then
|
||||||
|
bashio::log.fatal "The port 80 is enabled, but should still be 80 if you want automatic SSL certificates generation to work."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Correct systemctl path
|
||||||
|
echo "... updating systemctl path"
|
||||||
|
mv /helpers/systemctl3.py /bin/systemctl
|
||||||
|
chmod a+x /bin/systemctl
|
||||||
|
|
||||||
|
# Correct timedatectl path
|
||||||
|
echo "updating timedatectl path"
|
||||||
|
mv /helpers/timedatectl /usr/bin/timedatectl
|
||||||
|
chown pi:pi /usr/bin/timedatectl
|
||||||
|
chmod a+x /usr/bin/timedatectl
|
||||||
|
|
||||||
|
# Correct timezone showing in config.php
|
||||||
|
sed -i -e '/<option disabled selected>/s/selected//' \
|
||||||
|
-e '/\$current_timezone = trim(shell_exec("timedatectl show --value --property=Timezone"));/d' \
|
||||||
|
-e "/\$date = new DateTime('now');/i \$current_timezone = trim(shell_exec(\"timedatectl show --value --property=Timezone\"));" \
|
||||||
|
-e "/\$date = new DateTime('now');/i date_default_timezone_set(\$current_timezone);" "$HOME/BirdNET-Pi/scripts/config.php"
|
||||||
|
|
||||||
|
# Correct language labels according to birdnet.conf
|
||||||
|
echo "... adapting labels according to birdnet.conf"
|
||||||
|
export "$(grep "^DATABASE_LANG" /config/birdnet.conf)" || bashio::log.warning "DATABASE_LANG not found in configuration. Using default labels."
|
||||||
|
bashio::log.info "Setting language to $DATABASE_LANG"
|
||||||
|
"$HOME/BirdNET-Pi/scripts/install_language_label_nm.sh" -l "$DATABASE_LANG" &>/dev/null || bashio::log.warning "Failed to update language labels"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/with-contenv bashio
|
#!/command/with-contenv bashio
|
||||||
# shellcheck shell=bash
|
# shellcheck shell=bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -6,32 +6,55 @@ set -e
|
|||||||
# NGINX SETTING #
|
# NGINX SETTING #
|
||||||
#################
|
#################
|
||||||
|
|
||||||
declare ingress_interface
|
|
||||||
declare ingress_port
|
|
||||||
declare ingress_entry
|
|
||||||
|
|
||||||
# Variables
|
# Variables
|
||||||
ingress_port=$(bashio::addon.ingress_port)
|
ingress_port=$(bashio::addon.ingress_port)
|
||||||
ingress_interface=$(bashio::addon.ip_address)
|
ingress_interface=$(bashio::addon.ip_address)
|
||||||
ingress_entry=$(bashio::addon.ingress_entry)
|
ingress_entry=$(bashio::addon.ingress_entry)
|
||||||
|
|
||||||
# Quits if ingress not active
|
# Quits if ingress is not active
|
||||||
if [ -z "$ingress_entry" ]; then exit 0; fi
|
if [ -z "$ingress_entry" ]; then
|
||||||
|
bashio::log.warning "Ingress entry is not set, exiting configuration."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
echo " "
|
|
||||||
bashio::log.info "Adapting for ingress"
|
bashio::log.info "Adapting for ingress"
|
||||||
echo "... setting up nginx"
|
echo "... setting up nginx"
|
||||||
sed -i "s/%%port%%/${ingress_port}/g" /etc/nginx/servers/ingress.conf
|
|
||||||
sed -i "s/%%interface%%/${ingress_interface}/g" /etc/nginx/servers/ingress.conf
|
# Check if the NGINX configuration file exists
|
||||||
sed -i "s|%%ingress_entry%%|${ingress_entry}|g" /etc/nginx/servers/ingress.conf
|
nginx_conf="/etc/nginx/servers/ingress.conf"
|
||||||
|
if [ -f "$nginx_conf" ]; then
|
||||||
|
sed -i "s/%%port%%/${ingress_port}/g" "$nginx_conf"
|
||||||
|
sed -i "s/%%interface%%/${ingress_interface}/g" "$nginx_conf"
|
||||||
|
sed -i "s|%%ingress_entry%%|${ingress_entry}|g" "$nginx_conf"
|
||||||
|
else
|
||||||
|
bashio::log.error "NGINX configuration file not found: $nginx_conf"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo "... ensuring restricted area access"
|
echo "... ensuring restricted area access"
|
||||||
echo "${ingress_entry}" > /ingress_url
|
echo "${ingress_entry}" > /ingress_url
|
||||||
sed -i "/function is_authenticated/a if (strpos(\$_SERVER['HTTP_REFERER'], '/api/hassio_ingress') !== false && strpos(\$_SERVER['HTTP_REFERER'], trim(file_get_contents('/ingress_url'))) !== false) { \$ret = true; return \$ret; }" "$HOME"/BirdNET-Pi/scripts/common.php
|
|
||||||
|
|
||||||
echo "... adapt Caddyfile for ingress"
|
# Modify PHP file safely
|
||||||
|
php_file="$HOME/BirdNET-Pi/scripts/common.php"
|
||||||
|
if [ -f "$php_file" ]; then
|
||||||
|
sed -i "/function is_authenticated/a if (strpos(\$_SERVER['HTTP_REFERER'], '/api/hassio_ingress') !== false && strpos(\$_SERVER['HTTP_REFERER'], trim(file_get_contents('/ingress_url'))) !== false) { \$ret = true; return \$ret; }" "$php_file"
|
||||||
|
else
|
||||||
|
bashio::log.error "PHP file not found: $php_file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "... adapting Caddyfile for ingress"
|
||||||
chmod +x /helpers/caddy_ingress.sh
|
chmod +x /helpers/caddy_ingress.sh
|
||||||
/./helpers/caddy_ingress.sh
|
|
||||||
sed -i "/sudo caddy fmt --overwrite/i /./helpers/caddy_ingress.sh" "$HOME"/BirdNET-Pi/scripts/update_caddyfile.sh
|
|
||||||
|
|
||||||
echo " "
|
# Correct script execution
|
||||||
|
/helpers/caddy_ingress.sh
|
||||||
|
|
||||||
|
# Update the Caddyfile if update script exists
|
||||||
|
caddy_update_script="$HOME/BirdNET-Pi/scripts/update_caddyfile.sh"
|
||||||
|
if [ -f "$caddy_update_script" ]; then
|
||||||
|
sed -i "/sudo caddy fmt --overwrite/i /helpers/caddy_ingress.sh" "$caddy_update_script"
|
||||||
|
else
|
||||||
|
bashio::log.error "Caddy update script not found: $caddy_update_script"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/with-contenv bashio
|
#!/command/with-contenv bashio
|
||||||
# shellcheck shell=bash
|
# shellcheck shell=bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -7,14 +7,33 @@ set -e
|
|||||||
###############
|
###############
|
||||||
|
|
||||||
if bashio::config.true 'ssl'; then
|
if bashio::config.true 'ssl'; then
|
||||||
bashio::log.info "Ssl is enabled using addon options, setting up nginx"
|
bashio::log.info "SSL is enabled using addon options, setting up NGINX and Caddy."
|
||||||
|
|
||||||
|
# Check required SSL configurations
|
||||||
bashio::config.require.ssl
|
bashio::config.require.ssl
|
||||||
certfile=$(bashio::config 'certfile')
|
certfile=$(bashio::config 'certfile')
|
||||||
keyfile=$(bashio::config 'keyfile')
|
keyfile=$(bashio::config 'keyfile')
|
||||||
sed -i "2a\ tls /ssl/${certfile} /ssl/${keyfile}" /etc/caddy/Caddyfile
|
|
||||||
sed -i "s|http://:8081|https://:8081|g" /etc/caddy/Caddyfile
|
# Ensure Caddyfile exists before modifying
|
||||||
sed -i "s|http://:8081|https://:8081|g" "$HOME"/BirdNET-Pi/scripts/update_caddyfile.sh
|
caddyfile="/etc/caddy/Caddyfile"
|
||||||
sed -i "/https:/a tls /ssl/${certfile} /ssl/${keyfile}" "$HOME"/BirdNET-Pi/scripts/update_caddyfile.sh
|
if [ -f "$caddyfile" ]; then
|
||||||
|
sed -i "2a\ tls /ssl/${certfile} /ssl/${keyfile}" "$caddyfile"
|
||||||
|
sed -i "s|http://:8081|https://:8081|g" "$caddyfile"
|
||||||
|
else
|
||||||
|
bashio::log.error "Caddyfile not found at $caddyfile, skipping SSL configuration."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ensure update_caddyfile.sh exists before modifying
|
||||||
|
update_script="$HOME/BirdNET-Pi/scripts/update_caddyfile.sh"
|
||||||
|
if [ -f "$update_script" ]; then
|
||||||
|
sed -i "s|http://:8081|https://:8081|g" "$update_script"
|
||||||
|
if ! grep -q "tls /ssl/${certfile} /ssl/${keyfile}" "$update_script"; then
|
||||||
|
sed -i "/https:/a\ tls /ssl/${certfile} /ssl/${keyfile}" "$update_script"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
bashio::log.error "Update script not found: $update_script, skipping SSL setup for update."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo " "
|
|
||||||
|
|||||||
@@ -6,67 +6,58 @@ set -e
|
|||||||
# SET SYSTEM #
|
# SET SYSTEM #
|
||||||
##############
|
##############
|
||||||
|
|
||||||
echo " "
|
|
||||||
bashio::log.info "Setting password for the user pi"
|
bashio::log.info "Setting password for the user pi"
|
||||||
echo "pi:$(bashio::config "pi_password")" | sudo chpasswd
|
echo "pi:$(bashio::config "pi_password")" | chpasswd
|
||||||
echo "... done"
|
bashio::log.info "Password set successfully for user pi."
|
||||||
|
|
||||||
echo " "
|
bashio::log.info "Setting timezone :"
|
||||||
bashio::log.info "Starting system services"
|
|
||||||
|
|
||||||
# Set TZ
|
# Use timezone defined in add-on options if available
|
||||||
if bashio::config.has_value 'TZ'; then
|
if bashio::config.has_value 'TZ'; then
|
||||||
TIMEZONE=$(bashio::config 'TZ')
|
TZ_VALUE="$(bashio::config 'TZ')"
|
||||||
echo "... setting timezone to $TIMEZONE"
|
if timedatectl set-timezone "$TZ_VALUE"; then
|
||||||
ln -snf /usr/share/zoneinfo/"$TIMEZONE" /etc/localtime
|
echo "... timezone set to $TZ_VALUE as defined in add-on options (BirdNET config ignored)."
|
||||||
echo "$TIMEZONE" >/etc/timezone
|
else
|
||||||
fi || (bashio::log.fatal "Error : $TIMEZONE not found. Here is a list of valid timezones : https://manpages.ubuntu.com/manpages/focal/man3/DateTime::TimeZone::Catalog.3pm.html")
|
bashio::log.warning "Couldn't set timezone to $TZ_VALUE. Refer to the list of valid timezones: https://manpages.ubuntu.com/manpages/focal/man3/DateTime::TimeZone::Catalog.3pm.html"
|
||||||
|
timedatectl set-ntp true &>/dev/null
|
||||||
# Correcting systemctl
|
fi
|
||||||
echo "... correcting systemctl"
|
# Use BirdNET-defined timezone if no add-on option is provided
|
||||||
mv /helpers/systemctl3.py /bin/systemctl
|
elif [ -f /data/timezone ]; then
|
||||||
chmod a+x /bin/systemctl
|
BIRDN_CONFIG_TZ="$(cat /data/timezone)"
|
||||||
|
timedatectl set-ntp false &>/dev/null
|
||||||
# Correcting systemctl
|
if timedatectl set-timezone "$BIRDN_CONFIG_TZ"; then
|
||||||
echo "... correcting datetimectl"
|
echo "... set to $BIRDN_CONFIG_TZ as defined in BirdNET config."
|
||||||
mv /helpers/timedatectl /usr/bin/timedatectl
|
else
|
||||||
chmod a+x /usr/bin/timedatectl
|
bashio::log.warning "Couldn't set timezone to $BIRDN_CONFIG_TZ. Reverting to automatic timezone."
|
||||||
|
timedatectl set-ntp true &>/dev/null
|
||||||
# Correct language labels
|
fi
|
||||||
export "$(grep "^DATABASE_LANG" /config/birdnet.conf)"
|
# Fallback to automatic timezone if no manual settings are found
|
||||||
# Saving default of en
|
else
|
||||||
cp "$HOME"/BirdNET-Pi/model/labels.txt "$HOME"/BirdNET-Pi/model/labels.bak
|
if timedatectl set-ntp true &>/dev/null; then
|
||||||
# Adapt to new language
|
bashio::log.info "... automatic timezone enabled."
|
||||||
echo "... adapting labels according to birdnet.conf file to $DATABASE_LANG"
|
else
|
||||||
/."$HOME"/BirdNET-Pi/scripts/install_language_label_nm.sh -l "$DATABASE_LANG"
|
bashio::log.fatal "Couldn't set automatic timezone! Please set a manual one from the options."
|
||||||
|
fi
|
||||||
echo "... starting cron"
|
|
||||||
systemctl start cron
|
|
||||||
|
|
||||||
# Starting dbus
|
|
||||||
echo "... starting dbus"
|
|
||||||
service dbus start
|
|
||||||
|
|
||||||
# Starting journald
|
|
||||||
# echo "... starting journald"
|
|
||||||
# systemctl start systemd-journald
|
|
||||||
|
|
||||||
# Starting services
|
|
||||||
echo ""
|
|
||||||
bashio::log.info "Starting BirdNET-Pi services"
|
|
||||||
chmod +x "$HOME"/BirdNET-Pi/scripts/restart_services.sh
|
|
||||||
"$HOME"/BirdNET-Pi/scripts/restart_services.sh
|
|
||||||
|
|
||||||
if bashio::config.true LIVESTREAM_BOOT_ENABLED; then
|
|
||||||
echo "... starting livestream"
|
|
||||||
sudo systemctl enable icecast2
|
|
||||||
sudo systemctl start icecast2.service
|
|
||||||
sudo systemctl enable --now livestream.service
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Correct the phpsysinfo for the correct gotty service
|
bashio::log.info "Starting system services"
|
||||||
gottyservice="$(pgrep -l "gotty" | awk '{print $NF}' | head -n 1)"
|
|
||||||
echo "... using $gottyservice in phpsysinfo"
|
|
||||||
sed -i "s/,gotty,/,${gottyservice:-gotty},/g" "$HOME"/BirdNET-Pi/templates/phpsysinfo.ini
|
|
||||||
|
|
||||||
echo " "
|
bashio::log.info "Starting cron service"
|
||||||
|
systemctl start cron >/dev/null
|
||||||
|
|
||||||
|
bashio::log.info "Starting dbus service"
|
||||||
|
service dbus start >/dev/null
|
||||||
|
|
||||||
|
bashio::log.info "Starting BirdNET-Pi services"
|
||||||
|
chmod +x "$HOME/BirdNET-Pi/scripts/restart_services.sh" >/dev/null
|
||||||
|
"$HOME/BirdNET-Pi/scripts/restart_services.sh" >/dev/null
|
||||||
|
|
||||||
|
# Start livestream services if enabled in configuration
|
||||||
|
if bashio::config.true LIVESTREAM_BOOT_ENABLED; then
|
||||||
|
echo "... starting livestream services"
|
||||||
|
systemctl enable icecast2 >/dev/null
|
||||||
|
systemctl start icecast2.service >/dev/null
|
||||||
|
systemctl enable --now livestream.service >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
bashio::log.info "Setup complete."
|
||||||
|
|||||||
@@ -1803,7 +1803,7 @@ class Systemctl:
|
|||||||
if self._now:
|
if self._now:
|
||||||
basics = self.list_service_unit_basics()
|
basics = self.list_service_unit_basics()
|
||||||
result = [(name, sysv + " " + filename) for name, sysv, filename in basics]
|
result = [(name, sysv + " " + filename) for name, sysv, filename in basics]
|
||||||
elif self._only_type:
|
elif self._only_type:
|
||||||
if "target" in self._only_type:
|
if "target" in self._only_type:
|
||||||
result = self.list_target_unit_files()
|
result = self.list_target_unit_files()
|
||||||
if "service" in self._only_type:
|
if "service" in self._only_type:
|
||||||
@@ -5933,9 +5933,9 @@ class Systemctl:
|
|||||||
content = prefix+b": "+line+b"\n"
|
content = prefix+b": "+line+b"\n"
|
||||||
try:
|
try:
|
||||||
os.write(stdout, content)
|
os.write(stdout, content)
|
||||||
try:
|
try:
|
||||||
os.fsync(stdout)
|
os.fsync(stdout)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
printed += 1
|
printed += 1
|
||||||
except BlockingIOError:
|
except BlockingIOError:
|
||||||
|
|||||||
@@ -1,47 +1,99 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Function to show the current timezone, with two alternative methods
|
# Function to show the current timezone using two alternative methods
|
||||||
show_timezone() {
|
show_timezone() {
|
||||||
# Check if the /etc/timezone file exists
|
if [ -f /data/timezone ]; then
|
||||||
if [ -f /etc/timezone ]; then
|
cat /data/timezone
|
||||||
timezone=$(cat /etc/timezone)
|
elif [ -f /etc/timezone ]; then
|
||||||
|
cat /etc/timezone
|
||||||
elif [ -f /etc/localtime ]; then
|
elif [ -f /etc/localtime ]; then
|
||||||
timezone=$(readlink /etc/localtime)
|
readlink /etc/localtime | sed 's|/usr/share/zoneinfo/||'
|
||||||
timezone=${timezone/\/usr\/share\/zoneinfo\//}
|
|
||||||
else
|
else
|
||||||
timezone="Cannot determine timezone."
|
echo "Cannot determine timezone."
|
||||||
fi
|
fi
|
||||||
echo "$timezone"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to set the timezone
|
# Function to set the timezone
|
||||||
set_timezone() {
|
set_timezone() {
|
||||||
new_timezone="$1"
|
local new_timezone="$1"
|
||||||
echo "$new_timezone" | sudo tee /etc/timezone >/dev/null
|
if [ ! -f "/usr/share/zoneinfo/$new_timezone" ]; then
|
||||||
sudo ln -sf /usr/share/zoneinfo/"$new_timezone" /etc/localtime
|
echo "Invalid timezone: $new_timezone"
|
||||||
if [ -f /etc/environment ]; then sudo sed -i "/TZ/c\TZ=$new_timezone" /etc/environment; fi
|
return 1
|
||||||
if [ -d /var/run/s6/container_environment ]; then echo "$new_timezone" | sudo tee /var/run/s6/container_environment/TZ > /dev/null; fi
|
fi
|
||||||
echo "$new_timezone"
|
|
||||||
|
echo "$new_timezone" > /data/timezone
|
||||||
|
echo "$new_timezone" > /etc/timezone
|
||||||
|
ln -sf "/usr/share/zoneinfo/$new_timezone" /etc/localtime
|
||||||
|
|
||||||
|
# Update /etc/environment if it exists
|
||||||
|
if [ -f /etc/environment ]; then
|
||||||
|
sed -i "/^TZ=/c\TZ=$new_timezone" /etc/environment
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update s6 container environment if it exists
|
||||||
|
if [ -d /var/run/s6/container_environment ]; then
|
||||||
|
echo "$new_timezone" > /var/run/s6/container_environment/TZ
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Timezone set to: $new_timezone"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Main script
|
# Function to enable or disable NTP
|
||||||
|
set_ntp() {
|
||||||
|
case "$1" in
|
||||||
|
"false")
|
||||||
|
systemctl stop systemd-timesyncd
|
||||||
|
systemctl disable systemd-timesyncd
|
||||||
|
echo "NTP disabled"
|
||||||
|
;;
|
||||||
|
"true")
|
||||||
|
systemctl start systemd-timesyncd
|
||||||
|
systemctl enable systemd-timesyncd
|
||||||
|
|
||||||
|
# Remove the /data/timezone file when NTP is enabled
|
||||||
|
if [ -f /data/timezone ]; then
|
||||||
|
rm -f /data/timezone
|
||||||
|
echo "Timezone configuration file /data/timezone deleted."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "NTP enabled"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid argument for set-ntp. Use 'false' or 'true'."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to show detailed time settings
|
||||||
|
show_time_details() {
|
||||||
|
local local_time
|
||||||
|
local utc_time
|
||||||
|
local time_zone
|
||||||
|
local ntp_status="no"
|
||||||
|
local ntp_service="inactive"
|
||||||
|
|
||||||
|
local_time="$(date)"
|
||||||
|
utc_time="$(date -u)"
|
||||||
|
time_zone="$(show_timezone)"
|
||||||
|
|
||||||
|
# Check if NTP is used
|
||||||
|
if systemctl is-active --quiet systemd-timesyncd; then
|
||||||
|
ntp_status="yes"
|
||||||
|
ntp_service="active"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Print the information
|
||||||
|
echo "Local time: $local_time"
|
||||||
|
echo "Universal time: $utc_time"
|
||||||
|
echo "Time zone: $time_zone"
|
||||||
|
echo "Network time on: $ntp_status"
|
||||||
|
echo "NTP service: $ntp_service"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main script logic
|
||||||
case "$1" in
|
case "$1" in
|
||||||
"set-ntp")
|
"set-ntp")
|
||||||
case "$2" in
|
set_ntp "$2"
|
||||||
"false")
|
|
||||||
sudo systemctl stop systemd-timesyncd
|
|
||||||
sudo systemctl disable systemd-timesyncd
|
|
||||||
echo "NTP disabled"
|
|
||||||
;;
|
|
||||||
"true")
|
|
||||||
sudo systemctl start systemd-timesyncd
|
|
||||||
sudo systemctl enable systemd-timesyncd
|
|
||||||
echo "NTP enabled"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Invalid argument for set-ntp. Use 'false' or 'true'."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
;;
|
||||||
"show")
|
"show")
|
||||||
show_timezone
|
show_timezone
|
||||||
@@ -50,23 +102,6 @@ case "$1" in
|
|||||||
set_timezone "$2"
|
set_timezone "$2"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# Get values
|
show_time_details
|
||||||
local_time="$(date)"
|
|
||||||
utc_time="$(date -u)"
|
|
||||||
time_zone="$(show_timezone)"
|
|
||||||
# Check if NTP is used
|
|
||||||
if sudo systemctl status systemd-timesyncd | grep -q " active"; then
|
|
||||||
ntp_status="yes"
|
|
||||||
ntp_service="active"
|
|
||||||
else
|
|
||||||
ntp_status="no"
|
|
||||||
ntp_service="inactive"
|
|
||||||
fi
|
|
||||||
# Print the information
|
|
||||||
echo "Local time: $local_time"
|
|
||||||
echo "Universal time: $utc_time"
|
|
||||||
echo "Time zone: $time_zone"
|
|
||||||
echo "Network time on: $ntp_status"
|
|
||||||
echo "NTP service: $ntp_service"
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
Reference in New Issue
Block a user