Merge branch 'main' into Configurable-Service-Logging-Options

This commit is contained in:
Jared
2023-04-19 21:36:30 +10:00
committed by GitHub
15 changed files with 134 additions and 2094 deletions
+10
View File
@@ -50,6 +50,16 @@ if (file_exists('./scripts/thisrun.txt')) {
} elseif (file_exists('./scripts/firstrun.ini')) {
$config = parse_ini_file('./scripts/firstrun.ini');
}
if ($config["LATITUDE"] == "0.000" && $config["LONGITUDE"] == "0.000") {
echo "<center style='color:red'><b>WARNING: Your latitude and longitude are not set properly. Please do so now in Tools -> Settings.</center></b>";
}
elseif ($config["LATITUDE"] == "0.000") {
echo "<center style='color:red'><b>WARNING: Your latitude is not set properly. Please do so now in Tools -> Settings.</center></b>";
}
elseif ($config["LONGITUDE"] == "0.000") {
echo "<center style='color:red'><b>WARNING: Your longitude is not set properly. Please do so now in Tools -> Settings.</center></b>";
}
?>
<link rel="stylesheet" href="style.css?v=<?php echo date ('n.d.y', filemtime('style.css')); ?>">
<style>
+1
View File
@@ -14,3 +14,4 @@ apprise==1.2.1
paho-mqtt
pytest==7.1.2
pytest-mock==3.7.0
suntime
-16
View File
@@ -1,16 +0,0 @@
#!/bin/bash
#List audio devices and find input device name
input_device=$(LANG=C pacmd list-sources | grep name: | grep input | awk -F'<|>' '{print $2}')
#Add echo-cancel module code to the end of the file
echo ".ifexists module-echo-cancel.so
load-module module-echo-cancel source_master=$input_device aec_method=webrtc source_name=echocancel sink_name=echocancel1
set-default-source echocancel
set-default-sink echocancel1
.endif" | sudo tee -a /etc/pulse/default.pa >/dev/null
#Reload pulseaudio
pulseaudio -k
echo "Echo cancellation setup is complete."
-997
View File
@@ -1,997 +0,0 @@
#!/usr/bin/env -S sudo -E sh
# Altered from raspi-config tool below
# https://github.com/RPi-Distro/birdnet-pi-config
#
# See LICENSE file for copyright and license details
# Copyright (c) 2012 Alex Bradbury <asb@asbradbury.org>
set -x
birdnetpi_dir=/home/pi/BirdNET-Pi
birders_config=${birdnetpi_dir}/Birders_Guide_Installer_Configuration.txt
branch=forms
INTERACTIVE=True
ASK_TO_REBOOT=0
BLACKLIST=/etc/modprobe.d/raspi-blacklist.conf
CONFIG=/boot/config.txt
USER=${SUDO_USER:-$(who -m | awk '{ print $1 }')}
is_pi () {
ARCH=$(dpkg --print-architecture)
if [ "$ARCH" = "armhf" ] || [ "$ARCH" = "arm64" ] ; then
return 0
else
return 1
fi
}
if is_pi ; then
CMDLINE=/boot/cmdline.txt
else
CMDLINE=/proc/cmdline
fi
is_pione() {
if grep -q "^Revision\s*:\s*00[0-9a-fA-F][0-9a-fA-F]$" /proc/cpuinfo; then
return 0
elif grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]0[0-36][0-9a-fA-F]$" /proc/cpuinfo ; then
return 0
else
return 1
fi
}
is_pitwo() {
grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]04[0-9a-fA-F]$" /proc/cpuinfo
return $?
}
is_pizero() {
grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]0[9cC][0-9a-fA-F]$" /proc/cpuinfo
return $?
}
is_pifour() {
grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F]3[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$" /proc/cpuinfo
return $?
}
get_pi_type() {
if is_pione; then
echo 1
elif is_pitwo; then
echo 2
else
echo 0
fi
}
is_live() {
grep -q "boot=live" $CMDLINE
return $?
}
is_ssh() {
if pstree -p | egrep --quiet --extended-regexp ".*sshd.*\($$\)"; then
return 0
else
return 1
fi
}
is_fkms() {
if grep -s -q okay /proc/device-tree/soc/v3d@7ec00000/status \
/proc/device-tree/soc/firmwarekms@7e600000/status \
/proc/device-tree/v3dbus/v3d@7ec04000/status; then
return 0
else
return 1
fi
}
is_pulseaudio() {
PS=$(ps ax)
echo "$PS" | grep -q pulseaudio
return $?
}
has_analog() {
if [ $(get_leds) -eq -1 ] ; then
return 0
else
return 1
fi
}
is_installed() {
if [ "$(dpkg -l "$1" 2> /dev/null | tail -n 1 | cut -d ' ' -f 1)" != "ii" ]; then
return 1
else
return 0
fi
}
deb_ver () {
ver=`cat /etc/debian_version | cut -d . -f 1`
echo $ver
}
calc_wt_size() {
# NOTE: it's tempting to redirect stderr to /dev/null, so supress error
# output from tput. However in this case, tput detects neither stdout or
# stderr is a tty and so only gives default 80, 24 values
WT_HEIGHT=18
WT_WIDTH=$(tput cols)
if [ -z "$WT_WIDTH" ] || [ "$WT_WIDTH" -lt 60 ]; then
WT_WIDTH=80
fi
if [ "$WT_WIDTH" -gt 178 ]; then
WT_WIDTH=120
fi
WT_MENU_HEIGHT=$(($WT_HEIGHT-7))
}
do_change_pass() {
whiptail --msgbox "You will now be asked to enter a new password for the $USER user" 20 60 1
passwd $USER &&
whiptail --msgbox "Password changed successfully" 20 60 1
}
do_configure_keyboard() {
printf "Reloading keymap. This may take a short while\n"
if [ "$INTERACTIVE" = True ]; then
dpkg-reconfigure keyboard-configuration
else
local KEYMAP="$1"
sed -i /etc/default/keyboard -e "s/^XKBLAYOUT.*/XKBLAYOUT=\"$KEYMAP\"/"
dpkg-reconfigure -f noninteractive keyboard-configuration
fi
invoke-rc.d keyboard-setup start
setsid sh -c 'exec setupcon -k --force <> /dev/tty1 >&0 2>&1'
udevadm trigger --subsystem-match=input --action=change
return 0
}
do_change_locale() {
dpkg-reconfigure locales && \
ASK_TO_REBOOT=2 && return 0
}
do_change_timezone() {
dpkg-reconfigure tzdata && \
return 0
}
get_wifi_country() {
CODE=${1:-0}
IFACE="$(list_wlan_interfaces | head -n 1)"
if [ -z "$IFACE" ]; then
whiptail --msgbox "No wireless interface found" 20 60
return 1
fi
if ! wpa_cli -i "$IFACE" status > /dev/null 2>&1; then
whiptail --msgbox "Could not communicate with wpa_supplicant" 20 60
return 1
fi
wpa_cli -i "$IFACE" save_config > /dev/null 2>&1
COUNTRY="$(wpa_cli -i "$IFACE" get country)"
if [ "$COUNTRY" = "FAIL" ]; then
return 1
fi
if [ $CODE = 0 ]; then
echo "$COUNTRY"
fi
return 0
}
do_wifi_country() {
IFACE="$(list_wlan_interfaces | head -n 1)"
if [ -z "$IFACE" ]; then
whiptail --msgbox "No wireless interface found" 20 60
return 1
fi
if ! wpa_cli -i "$IFACE" status > /dev/null 2>&1; then
whiptail --msgbox "Could not communicate with wpa_supplicant" 20 60
return 1
fi
oIFS="$IFS"
value=$(cat /usr/share/zoneinfo/iso3166.tab | tail -n +26 | tr '\t' '/' | tr '\n' '/')
IFS="/"
COUNTRY=$(whiptail --menu "Select the country in which the Pi is to be used" 20 60 10 ${value} 3>&1 1>&2 2>&3)
if [ $? -eq 0 ];then
wpa_cli -i "$IFACE" set country "$COUNTRY"
wpa_cli -i "$IFACE" save_config > /dev/null 2>&1
if iw reg set "$COUNTRY" 2> /dev/null; then
ASK_TO_REBOOT=1
fi
if hash rfkill 2> /dev/null; then
rfkill unblock wifi
if is_pi ; then
for filename in /var/lib/systemd/rfkill/*:wlan ; do
echo 0 > $filename
done
fi
fi
whiptail --msgbox "Wireless LAN country set to $COUNTRY" 20 60 1
fi
IFS=$oIFS
}
get_labels_lang() {
oIFS="$IFS"
value=$(cat ${birdnetpi_dir}/model/labels_lang.txt | tr ',' ' ' | tr '\n' ' ')
IFS=" "
get_lang=$(whiptail --menu "Select the file that corresponds to your language" 20 60 10 ${value} 3>&1 1>&2 2>&3)
labels_lang=$(awk -F, "/$get_lang/{print \$2}" ${birdnetpi_dir}/model/labels_lang.txt)
if [ $? -eq 0 ];then
whiptail --msgbox "Your installation will now use $labels_lang" 20 60 1
mv ${birdnetpi_dir}/model/labels.txt ${birdnetpi_dir}/model/labels.txt.old
unzip ${birdnetpi_dir}/model/labels_l18n.zip ${labels_lang} -d ${birdnetpi_dir}/model
mv ${birdnetpi_dir}/model/${labels_lang} ${birdnetpi_dir}/model/labels.txt
fi
IFS=$oIFS
}
get_ssh() {
if service ssh status | grep -q inactive; then
echo 1
else
echo 0
fi
}
do_ssh() {
if [ -e /var/log/regen_ssh_keys.log ] && ! grep -q "^finished" /var/log/regen_ssh_keys.log; then
whiptail --msgbox "Initial ssh key generation still running. Please wait and try again." 20 60 2
return 1
fi
DEFAULT=--defaultno
if [ $(get_ssh) -eq 0 ]; then
DEFAULT=
fi
whiptail --yesno \
"Would you like the SSH server to be enabled?\n\nCaution: Default and weak passwords are a security risk when SSH is enabled!" $DEFAULT 20 60 2
RET=$?
if [ $RET -eq 0 ]; then
ssh-keygen -A &&
update-rc.d ssh enable &&
invoke-rc.d ssh start &&
STATUS=enabled
elif [ $RET -eq 1 ]; then
update-rc.d ssh disable &&
invoke-rc.d ssh stop &&
STATUS=disabled
else
return $RET
fi
whiptail --msgbox "The SSH server is $STATUS" 20 60 1
}
get_vnc() {
if systemctl status vncserver-x11-serviced.service | grep -q -w active; then
echo 0
else
echo 1
fi
}
do_config_zram() {
if [ -e /etc/udev/rules.d/99-zram.rules ]; then
## get current swap allocation from /etc/udev/rules.d/99-zram.rules
size="$(awk -F\" '{print $4}' /etc/udev/rules.d/99-zram.rules)"
else
size="4G"
fi
new_size=$(whiptail --inputbox "How much memory (G) should the zRAM swap partition have? Choose 1G, 2G, or 4G - 4G recommended" \
19 70 -- "$size" 3>&1 1>&2 2>&3)
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_install_zram() {
echo "Configuring zram.service"
touch /etc/modules-load.d/zram.conf
echo 'zram' > /etc/modules-load.d/zram.conf
touch /etc/modprobe.d/zram.conf
echo 'options zram num_devices=1' > /etc/modprobe.d/zram.conf
touch /etc/udev/rules.d/99-zram.rules
echo "KERNEL==\"zram0\", ATTR{disksize}=\"${new_size}\",TAG+=\"systemd\"" \
> /etc/udev/rules.d/99-zram.rules
touch /etc/systemd/system/zram.service
echo "Installing zram.service"
cat << EOF > /etc/systemd/system/zram.service
[Unit]
Description=Swap with zram
After=multi-user.target
[Service]
Type=oneshot
RemainAfterExit=true
ExecStartPre=/sbin/mkswap /dev/zram0
ExecStart=/sbin/swapon /dev/zram0
ExecStop=/sbin/swapoff /dev/zram0
[Install]
WantedBy=multi-user.target
EOF
systemctl enable zram
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_zram_menu() {
whiptail --yesno "Would like to enable the zram swapping kernel module?" --defaultno 20 60 2
RET=$?
if [ $RET -eq 0 ]; then
do_config_zram
do_install_zram
STATUS=enabled
elif [ $RET -eq 1 ]; then
if [ -e /etc/udev/rules.d/99-zram.rules ];then
systemctl disable --now zram
fi
STATUS=disabled
fi
whiptail --msgbox "ZRAM swapping is $STATUS" 20 60 1
return $RET
}
do_vnc() {
DEFAULT=--defaultno
if [ $(get_vnc) -eq 0 ]; then
DEFAULT=
fi
whiptail --yesno "Would you like the VNC Server to be enabled?" $DEFAULT 20 60 2
RET=$?
if [ $RET -eq 0 ]; then
if is_installed realvnc-vnc-server || apt-get install realvnc-vnc-server; then
systemctl enable vncserver-x11-serviced.service &&
systemctl start vncserver-x11-serviced.service &&
STATUS=enabled
else
return 1
fi
elif [ $RET -eq 1 ]; then
if is_installed realvnc-vnc-server; then
systemctl disable vncserver-x11-serviced.service
systemctl stop vncserver-x11-serviced.service
fi
STATUS=disabled
else
return $RET
fi
whiptail --msgbox "The VNC Server is $STATUS" 20 60 1
}
do_audio() {
if is_pulseaudio ; then
oIFS="$IFS"
list=$(sudo -u $SUDO_USER XDG_RUNTIME_DIR=/run/user/$SUDO_UID pacmd list-sources | grep -B1 -e 'alsa.card_name' -e 'name.*input' | grep -A4 index | sed -e s/*//g | sed s/^[' '\\t]*//g | grep -e index -e card_name | sed s/'index: '//g | sed s/'alsa.card_name = '//g | sed s/\"//g | tr '\n' '\/')
if ! [ -z "$list" ] ; then
IFS="/"
AUDIO_IN=$(whiptail --menu "Choose the audio input" 20 60 10 ${list} 3>&1 1>&2 2>&3)
return 0
else
whiptail --msgbox "No internal audio devices found" 20 60 1
return 1
fi
if [ $? -eq 0 ]; then
sudo -u $SUDO_USER XDG_RUNTIME_DIR=/run/user/$SUDO_UID pactl set-default-source "$AUDIO_IN"
fi
IFS=$oIFS
fi
sudo -u $SUDO_USER pulseaudio -k
}
list_wlan_interfaces() {
for dir in /sys/class/net/*/wireless; do
if [ -d "$dir" ]; then
basename "$(dirname "$dir")"
fi
done
}
do_wifi_ssid_passphrase() {
RET=0
IFACE_LIST="$(list_wlan_interfaces)"
IFACE="$(echo "$IFACE_LIST" | head -n 1)"
if [ -z "$IFACE" ]; then
whiptail --msgbox "No wireless interface found" 20 60
return 1
fi
if ! wpa_cli -i "$IFACE" status > /dev/null 2>&1; then
whiptail --msgbox "Could not communicate with wpa_supplicant" 20 60
return 1
fi
if [ -z "$(get_wifi_country)" ]; then
do_wifi_country
fi
SSID="$1"
while [ -z "$SSID" ] ; do
SSID=$(whiptail --inputbox "Please enter SSID" 20 60 3>&1 1>&2 2>&3)
if [ $? -ne 0 ]; then
return 0
elif [ -z "$SSID" ]; then
whiptail --msgbox "SSID cannot be empty. Please try again." 20 60
fi
done
PASSPHRASE="$2"
PASSPHRASE=$(whiptail --passwordbox "Please enter passphrase. Leave it empty if none." 20 60 3>&1 1>&2 2>&3)
if [ $? -ne 0 ]; then
return 0
else
return 1
fi
# Escape special characters for embedding in regex below
local ssid="$(echo "$SSID" \
| sed 's;\\;\\\\;g' \
| sed -e 's;\.;\\\.;g' \
-e 's;\*;\\\*;g' \
-e 's;\+;\\\+;g' \
-e 's;\?;\\\?;g' \
-e 's;\^;\\\^;g' \
-e 's;\$;\\\$;g' \
-e 's;\/;\\\/;g' \
-e 's;\[;\\\[;g' \
-e 's;\];\\\];g' \
-e 's;{;\\{;g' \
-e 's;};\\};g' \
-e 's;(;\\(;g' \
-e 's;);\\);g' \
-e 's;";\\\\\";g')"
wpa_cli -i "$IFACE" list_networks \
| tail -n +2 | cut -f -2 | grep -P "\t$ssid$" | cut -f1 \
| while read ID; do
wpa_cli -i "$IFACE" remove_network "$ID" > /dev/null 2>&1
done
ID="$(wpa_cli -i "$IFACE" add_network)"
wpa_cli -i "$IFACE" set_network "$ID" ssid "\"$SSID\"" 2>&1 | grep -q "OK"
RET=$((RET + $?))
if [ -z "$PASSPHRASE" ]; then
wpa_cli -i "$IFACE" set_network "$ID" key_mgmt NONE 2>&1 | grep -q "OK"
RET=$((RET + $?))
else
wpa_cli -i "$IFACE" set_network "$ID" psk "\"$PASSPHRASE\"" 2>&1 | grep -q "OK"
RET=$((RET + $?))
fi
if [ $RET -eq 0 ]; then
wpa_cli -i "$IFACE" enable_network "$ID" > /dev/null 2>&1
else
wpa_cli -i "$IFACE" remove_network "$ID" > /dev/null 2>&1
whiptail --msgbox "Failed to set SSID or passphrase" 20 60
fi
wpa_cli -i "$IFACE" save_config > /dev/null 2>&1
echo "$IFACE_LIST" | while read IFACE; do
wpa_cli -i "$IFACE" reconfigure > /dev/null 2>&1
done
return $RET
}
do_reget_birdnetpi_urls() {
birdnetpi_url=$(whiptail --inputbox "Put your domain here. Example: \"https://birdnetpi.pmcgui.xyz\"." \
19 70 -- "https://" 3>&1 1>&2 2>&3) extractionlog_url=$(whiptail --inputbox "Put your domain here. Example: \"https://extractionlog.pmcgui.xyz\"." 19 70 -- "https://" 3>&1 1>&2 2>&3) birdnetlog_url=$(whiptail --inputbox "Put your domain here. Example: \"https://birdnetlog.pmcgui.xyz\"." 19 70 -- "https://" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
else
return 1
fi
}
do_reget_db_pwd() {
db_pwd=$(whiptail --inputbox "Please set the password the 'birder' user will use to access the database." \
19 70 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_reget_birdweather_id() {
birdweather_id=$(whiptail --inputbox "Input your BirdWeather ID" \
19 70 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_reget_caddy_pwd() {
caddy_pwd=$(whiptail --inputbox "Please set the password for the web interface." \
19 70 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_reget_lon() {
lon="$(curl -s4 ifconfig.co/json | awk '/lon/ {print $2}' | tr -d ',')"
new_lon=$(whiptail --inputbox "Please set the longitude where recordings will take place." \
19 70 -- "$lon" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_reget_lat() {
lat="$(curl -s4 ifconfig.co/json | awk '/lat/ {print $2}' | tr -d ',')"
new_lat=$(whiptail --inputbox "Please set the latitude where recordings will take place." \
19 70 -- "$lat" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_confidence() {
confidence="$(awk -F= '/CONFIDENCE=/ {print $2}' ${birdnetpi_dir}/birdnet.conf)"
new_confidence=$(whiptail --inputbox "Please set the minimum confidence score BirdNET-Lite should use." \
19 70 -- "$confidence" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_overlap() {
overlap="$(awk -F= '/OVERLAP=/ {print $2}' ${birdnetpi_dir}/birdnet.conf)"
new_overlap=$(whiptail --inputbox "Please set the overlap BirdNET-Lite should use." \
19 70 -- "$overlap" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_sensitivity() {
sensitivity="$(awk -F= '/SENSITIVITY=/ {print $2}' ${birdnetpi_dir}/birdnet.conf)"
new_sensitivity=$(whiptail --inputbox "Please set the simoid sensitivty BirdNET-Lite should use." \
19 70 -- "$sensitivity" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_birdnetlog_url() {
birdnetlog_url=$(whiptail --inputbox "Put your domain here. Example: \"https://birdnetlog.pmcgui.xyz\"." \
19 70 -- "https://" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_extractionlog_url() {
extractionlog_url=$(whiptail --inputbox "Put your domain here. Example: \"https://extractionlog.pmcgui.xyz\"." \
19 70 -- "https://" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_birdnetpi_url() {
birdnetpi_url=$(whiptail --inputbox "Put your domain here. Example: \"https://birdnetpi.pmcgui.xyz\"." \
19 70 -- "https://" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_birdweather_id() {
birdweather_id=$(whiptail --inputbox "Input your BirdWeather ID" \
19 70 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_db_pwd() {
db_pwd=$(whiptail --inputbox "Please set the password the 'birder' user will use to access the database." \
19 70 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_ice_pwd() {
ice_pwd=$(whiptail --inputbox "Please set the password for the live stream." \
19 70 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_caddy_pwd() {
caddy_pwd=$(whiptail --inputbox "Please set the password for the web interface." \
19 70 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_lon() {
lon="$(curl -s4 ifconfig.co/json | awk '/lon/ {print $2}' | tr -d ',')"
new_lon=$(whiptail --inputbox "Please set the longitude where recordings will take place." \
19 70 -- "$lon" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_lat() {
lat="$(curl -s4 ifconfig.co/json | awk '/lat/ {print $2}' | tr -d ',')"
new_lat=$(whiptail --inputbox "Please set the latitude where recordings will take place." \
19 70 -- "$lat" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_update_os() {
apt update && apt -y full-upgrade && \
ASK_TO_REBOOT=1
}
do_update_birdnet() {
sudo -E -upi ${birdnetpi_dir}/scripts/update_birdnet.sh
}
do_install_birdnet() {
sudo -E -upi ${birdnetpi_dir}/Birders_Guide_Installer.sh && \
ASK_TO_REBOOT=1
}
insist_on_reboot() {
if [ $ASK_TO_REBOOT -eq 2 ]; then
whiptail --yesno "You really should reboot. Do that now?" 20 60 2
if [ $? -eq 0 ]; then # yes
sync
reboot
fi
fi
}
do_finish() {
if [ $ASK_TO_REBOOT -eq 1 ]; then
whiptail --yesno "Would you like to reboot now?" 20 60 2
if [ $? -eq 0 ]; then # yes
sync
reboot
fi
elif [ $ASK_TO_REBOOT -eq 2 ]; then
whiptail --yesno "You really should reboot. Do that now?" 20 60 2
if [ $? -eq 0 ]; then # yes
sync
reboot
fi
fi
exit 0
}
# Everything else needs to be run as root
if [ $(id -u) -ne 0 ]; then
printf "Script must be run as root. Try 'sudo birdnet-pi-config'\n"
exit 1
fi
do_advanced_reconfig_menu() {
MENU=9
while [ $MENU -eq 9 ];do
if is_pi ; then
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnet-pi-config)" --menu "BirdNET-Pi Configuration Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
"Sensitivity" "Set the sigmoid sensitivity" \
"Confidence" "Set the minimum confidence score required for a detection" \
"Overlap" "Set the analysis overlap in seconds" \
"BirdNET-Pi URLs" "Set the URLs your installation should use" \
3>&1 1>&2 2>&3)
else
exit
fi
RET=$?
if [ $RET -eq 1 ]; then
return 0
MENU=0
elif [ $RET -eq 0 ]; then
case "$FUN" in
Sens*) do_get_sensitivity;;
Confi*) do_get_confidence;;
Overlap*) do_get_overlap;;
Bird*) do_reget_birdnetpi_urls;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
fi
done
}
do_interface_menu() {
MENU=6
while [ $MENU -eq 6 ];do
if is_pi ; then
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnet-pi-config)" --menu "Interfacing Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
"SSH" "Enable/disable remote command line access using SSH" \
"VNC" "Enable/disable graphical remote access using RealVNC" \
3>&1 1>&2 2>&3)
else
exit
fi
RET=$?
if [ $RET -eq 1 ]; then
return 0
MENU=0
elif [ $RET -eq 0 ]; then
case "$FUN" in
SSH*) do_ssh ;;
VNC*) do_vnc ;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
fi
done
}
do_advanced_config_menu() {
MENU=5
while [ $MENU -eq 5 ];do
if is_pi ; then
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnet-pi-config)" --menu "BirdNET-Pi Configuration Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
"Sensitivity" "Set the sigmoid sensitivity" \
"Confidence" "Set the minimum confidence score required for a detection" \
"Overlap" "Set the analysis overlap in seconds" \
"BirdNET-Pi URLs" "Set the URLs your installation should use" \
3>&1 1>&2 2>&3)
else
exit
fi
RET=$?
if [ $RET -eq 1 ]; then
return 0
MENU=0
elif [ $RET -eq 0 ]; then
case "$FUN" in
Sens*) do_get_sensitivity;;
Confi*) do_get_confidence;;
Overlap*) do_get_overlap;;
Bird*) do_get_birdnetpi_url; do_get_birdnetlog_url; do_get_extractionlog_url;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
fi
done
}
do_system_menu() {
MENU=4
while [ $MENU -eq 4 ];do
if is_pi ; then
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnet-pi-config)" --menu "System Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
"Password" "Change password for the '$USER' user" \
"Audio" "Select audio device you'd like BirdNET-Pi to use" \
"Wireless LAN" "Enter SSID and passphrase" \
"Update the OS" "Update the underlying operating system" \
"Interface Options" "Enable/Disable SSH and VNC" \
"Configure zRAM" "Enable/Disable zRAM" \
"Timezone" "Configure time zone" \
"Keyboard" "Set keyboard layout to match your keyboard" \
"WLAN Country" "Set legal wireless channels for your country" \
3>&1 1>&2 2>&3)
else
exit
fi
RET=$?
if [ $RET -eq 1 ]; then
return 0
MENU=0
elif [ $RET -eq 0 ]; then
case "$FUN" in
Password*) do_change_pass ;;
Audio*) do_audio ;;
Wireless*) do_wifi_ssid_passphrase ;;
Update*) do_update_os ;;
Interface*) do_interface_menu ;;
Configure*) do_zram_menu ;;
Time*) do_change_timezone; insist_on_reboot ;;
Key*) do_configure_keyboard ;;
WLAN*) do_wifi_country ;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
fi
done
}
do_reconfig_birdnet_menu() {
MENU=3
while [ $MENU -eq 3 ];do
if is_pi ; then
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnet-pi-config)" --menu "BirdNET-Pi Re-configuration Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
"Latitude " "Set the latitude your system should use" \
"Longitude" "Set the longitude your system should use" \
"Caddy Password" "Set the web interface password" \
"Database Password" "Set the password BirdNET-Pi will use to access the DB" \
"BirdWeather ID" "Input your BirdWeather ID if you have one" \
"Advanced Settings" "Sensitivity, Overlap, Confidence, URLs" \
3>&1 1>&2 2>&3)
else
exit
fi
RET=$?
if [ $RET -eq 1 ]; then
return 0
MENU=0
elif [ $RET -eq 0 ]; then
case "$FUN" in
Lat*) do_reget_lat;;
Lon*) do_reget_lon;;
Cad*) do_reget_caddy_pwd;;
Data*) do_reget_db_pwd;;
Bird*) do_reget_birdweather_id;;
Advanced*) do_advanced_reconfig_menu;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
fi
done
}
do_config_birdnet_menu() {
MENU=2
while [ $MENU -eq 2 ];do
if is_pi ; then
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnet-pi-config)" --menu "BirdNET-Pi Configuration Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
"Latitude " "Set the latitude your system should use" \
"Longitude" "Set the longitude your system should use" \
"Caddy Password" "Set the web interface password" \
"IceCast2 Password" "Set the IceCast2 password" \
"Database Password" "Set the password BirdNET-Pi will use to access the DB" \
"BirdWeather ID" "Input your BirdWeather ID if you have one" \
"Set Custom URLS" "Designate custom URLs for the web services if you've set that up" \
3>&1 1>&2 2>&3)
else
exit
fi
RET=$?
if [ $RET -eq 1 ]; then
return 0
MENU=0
elif [ $RET -eq 0 ]; then
case "$FUN" in
Lat*) do_get_lat;;
Lon*) do_get_lon;;
Cad*) do_get_caddy_pwd;;
Ice*) do_get_ice_pwd;;
Data*) do_get_db_pwd;;
Bird*) do_get_birdweather_id;;
Set*) do_get_birdnetpi_url; do_get_birdnetlog_url; do_get_extractionlog_url;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
fi
done
}
do_internationalisation_menu() {
MENU=1
while [ $MENU -eq 1 ];do
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnet-pi-config)" --menu "Localisation Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
"System Locale" "Configure the system language and regional settings" \
"labels.txt" "Set the language to use for species detection" \
"Time Zone" "Set the Time Zone" \
3>&1 1>&2 2>&3)
RET=$?
if [ $RET -eq 1 ]; then
return 0
MENU=0
elif [ $RET -eq 0 ]; then
case "$FUN" in
System*) do_change_locale;;
label*) get_labels_lang;;
Time*) do_change_timezone;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
fi
done
}
#
# Interactive use loop
#
[ -e $CONFIG ] || touch $CONFIG
calc_wt_size
while [ "$USER" = "root" ] || [ -z "$USER" ]; do
if ! USER=$(whiptail --inputbox "birdnet-pi-config could not determine the default user.\\n\\nWhat user should these settings apply to?" 20 60 pi 3>&1 1>&2 2>&3); then
return 0
fi
done
while true; do
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnet-pi-config)" --backtitle "$(cat /proc/device-tree/model)" --menu "Setup Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Finish --ok-button Select \
"Step 1" "Configure language and timezone" \
"Step 2" "Configure BirdNET-Pi before installation" \
"Step 3" "Install BirdNET-Pi" \
"Step 4" "Reconfigure BirdNET-Pi AFTER installation" \
"Step 5" "Update BirdNET-Pi (run this if you changed URLs)" \
"System Options" "Configure system settings" \
3>&1 1>&2 2>&3)
RET=$?
if [ $RET -eq 1 ]; then
do_finish
elif [ $RET -eq 0 ]; then
case "$FUN" in
*1) do_internationalisation_menu ;;
*2) do_config_birdnet_menu ;;
*3) do_install_birdnet;;
*4) do_reconfig_birdnet_menu ;;
*5) do_update_birdnet;;
Sys*) do_system_menu ;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
fi
done
-997
View File
@@ -1,997 +0,0 @@
#!/usr/bin/env -S sudo -E sh
# Altered from raspi-config tool below
# https://github.com/RPi-Distro/birdnet-pi-config
#
# See LICENSE file for copyright and license details
# Copyright (c) 2012 Alex Bradbury <asb@asbradbury.org>
set -x
birdnetpi_dir=/home/pi/BirdNET-Pi
birders_config=${birdnetpi_dir}/Birders_Guide_Installer_Configuration.txt
branch=forms
INTERACTIVE=True
ASK_TO_REBOOT=0
BLACKLIST=/etc/modprobe.d/raspi-blacklist.conf
CONFIG=/boot/config.txt
USER=${SUDO_USER:-$(who -m | awk '{ print $1 }')}
is_pi () {
ARCH=$(dpkg --print-architecture)
if [ "$ARCH" = "armhf" ] || [ "$ARCH" = "arm64" ] ; then
return 0
else
return 1
fi
}
if is_pi ; then
CMDLINE=/boot/cmdline.txt
else
CMDLINE=/proc/cmdline
fi
is_pione() {
if grep -q "^Revision\s*:\s*00[0-9a-fA-F][0-9a-fA-F]$" /proc/cpuinfo; then
return 0
elif grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]0[0-36][0-9a-fA-F]$" /proc/cpuinfo ; then
return 0
else
return 1
fi
}
is_pitwo() {
grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]04[0-9a-fA-F]$" /proc/cpuinfo
return $?
}
is_pizero() {
grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]0[9cC][0-9a-fA-F]$" /proc/cpuinfo
return $?
}
is_pifour() {
grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F]3[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$" /proc/cpuinfo
return $?
}
get_pi_type() {
if is_pione; then
echo 1
elif is_pitwo; then
echo 2
else
echo 0
fi
}
is_live() {
grep -q "boot=live" $CMDLINE
return $?
}
is_ssh() {
if pstree -p | egrep --quiet --extended-regexp ".*sshd.*\($$\)"; then
return 0
else
return 1
fi
}
is_fkms() {
if grep -s -q okay /proc/device-tree/soc/v3d@7ec00000/status \
/proc/device-tree/soc/firmwarekms@7e600000/status \
/proc/device-tree/v3dbus/v3d@7ec04000/status; then
return 0
else
return 1
fi
}
is_pulseaudio() {
PS=$(ps ax)
echo "$PS" | grep -q pulseaudio
return $?
}
has_analog() {
if [ $(get_leds) -eq -1 ] ; then
return 0
else
return 1
fi
}
is_installed() {
if [ "$(dpkg -l "$1" 2> /dev/null | tail -n 1 | cut -d ' ' -f 1)" != "ii" ]; then
return 1
else
return 0
fi
}
deb_ver () {
ver=`cat /etc/debian_version | cut -d . -f 1`
echo $ver
}
calc_wt_size() {
# NOTE: it's tempting to redirect stderr to /dev/null, so supress error
# output from tput. However in this case, tput detects neither stdout or
# stderr is a tty and so only gives default 80, 24 values
WT_HEIGHT=18
WT_WIDTH=$(tput cols)
if [ -z "$WT_WIDTH" ] || [ "$WT_WIDTH" -lt 60 ]; then
WT_WIDTH=80
fi
if [ "$WT_WIDTH" -gt 178 ]; then
WT_WIDTH=120
fi
WT_MENU_HEIGHT=$(($WT_HEIGHT-7))
}
do_change_pass() {
whiptail --msgbox "You will now be asked to enter a new password for the $USER user" 20 60 1
passwd $USER &&
whiptail --msgbox "Password changed successfully" 20 60 1
}
do_configure_keyboard() {
printf "Reloading keymap. This may take a short while\n"
if [ "$INTERACTIVE" = True ]; then
dpkg-reconfigure keyboard-configuration
else
local KEYMAP="$1"
sed -i /etc/default/keyboard -e "s/^XKBLAYOUT.*/XKBLAYOUT=\"$KEYMAP\"/"
dpkg-reconfigure -f noninteractive keyboard-configuration
fi
invoke-rc.d keyboard-setup start
setsid sh -c 'exec setupcon -k --force <> /dev/tty1 >&0 2>&1'
udevadm trigger --subsystem-match=input --action=change
return 0
}
do_change_locale() {
dpkg-reconfigure locales && \
ASK_TO_REBOOT=2 && return 0
}
do_change_timezone() {
dpkg-reconfigure tzdata && \
return 0
}
get_wifi_country() {
CODE=${1:-0}
IFACE="$(list_wlan_interfaces | head -n 1)"
if [ -z "$IFACE" ]; then
whiptail --msgbox "No wireless interface found" 20 60
return 1
fi
if ! wpa_cli -i "$IFACE" status > /dev/null 2>&1; then
whiptail --msgbox "Could not communicate with wpa_supplicant" 20 60
return 1
fi
wpa_cli -i "$IFACE" save_config > /dev/null 2>&1
COUNTRY="$(wpa_cli -i "$IFACE" get country)"
if [ "$COUNTRY" = "FAIL" ]; then
return 1
fi
if [ $CODE = 0 ]; then
echo "$COUNTRY"
fi
return 0
}
do_wifi_country() {
IFACE="$(list_wlan_interfaces | head -n 1)"
if [ -z "$IFACE" ]; then
whiptail --msgbox "No wireless interface found" 20 60
return 1
fi
if ! wpa_cli -i "$IFACE" status > /dev/null 2>&1; then
whiptail --msgbox "Could not communicate with wpa_supplicant" 20 60
return 1
fi
oIFS="$IFS"
value=$(cat /usr/share/zoneinfo/iso3166.tab | tail -n +26 | tr '\t' '/' | tr '\n' '/')
IFS="/"
COUNTRY=$(whiptail --menu "Select the country in which the Pi is to be used" 20 60 10 ${value} 3>&1 1>&2 2>&3)
if [ $? -eq 0 ];then
wpa_cli -i "$IFACE" set country "$COUNTRY"
wpa_cli -i "$IFACE" save_config > /dev/null 2>&1
if iw reg set "$COUNTRY" 2> /dev/null; then
ASK_TO_REBOOT=1
fi
if hash rfkill 2> /dev/null; then
rfkill unblock wifi
if is_pi ; then
for filename in /var/lib/systemd/rfkill/*:wlan ; do
echo 0 > $filename
done
fi
fi
whiptail --msgbox "Wireless LAN country set to $COUNTRY" 20 60 1
fi
IFS=$oIFS
}
get_labels_lang() {
oIFS="$IFS"
value=$(cat ${birdnetpi_dir}/model/labels_lang.txt | tr ',' ' ' | tr '\n' ' ')
IFS=" "
get_lang=$(whiptail --menu "Select the file that corresponds to your language" 20 60 10 ${value} 3>&1 1>&2 2>&3)
labels_lang=$(awk -F, "/$get_lang/{print \$2}" ${birdnetpi_dir}/model/labels_lang.txt)
if [ $? -eq 0 ];then
whiptail --msgbox "Your installation will now use $labels_lang" 20 60 1
mv ${birdnetpi_dir}/model/labels.txt ${birdnetpi_dir}/model/labels.txt.old
unzip ${birdnetpi_dir}/model/labels_l18n.zip ${labels_lang} -d ${birdnetpi_dir}/model
mv ${birdnetpi_dir}/model/${labels_lang} ${birdnetpi_dir}/model/labels.txt
fi
IFS=$oIFS
}
get_ssh() {
if service ssh status | grep -q inactive; then
echo 1
else
echo 0
fi
}
do_ssh() {
if [ -e /var/log/regen_ssh_keys.log ] && ! grep -q "^finished" /var/log/regen_ssh_keys.log; then
whiptail --msgbox "Initial ssh key generation still running. Please wait and try again." 20 60 2
return 1
fi
DEFAULT=--defaultno
if [ $(get_ssh) -eq 0 ]; then
DEFAULT=
fi
whiptail --yesno \
"Would you like the SSH server to be enabled?\n\nCaution: Default and weak passwords are a security risk when SSH is enabled!" $DEFAULT 20 60 2
RET=$?
if [ $RET -eq 0 ]; then
ssh-keygen -A &&
update-rc.d ssh enable &&
invoke-rc.d ssh start &&
STATUS=enabled
elif [ $RET -eq 1 ]; then
update-rc.d ssh disable &&
invoke-rc.d ssh stop &&
STATUS=disabled
else
return $RET
fi
whiptail --msgbox "The SSH server is $STATUS" 20 60 1
}
get_vnc() {
if systemctl status vncserver-x11-serviced.service | grep -q -w active; then
echo 0
else
echo 1
fi
}
do_config_zram() {
if [ -e /etc/udev/rules.d/99-zram.rules ]; then
## get current swap allocation from /etc/udev/rules.d/99-zram.rules
size="$(awk -F\" '{print $4}' /etc/udev/rules.d/99-zram.rules)"
else
size="4G"
fi
new_size=$(whiptail --inputbox "How much memory (G) should the zRAM swap partition have? Choose 1G, 2G, or 4G - 4G recommended" \
19 70 -- "$size" 3>&1 1>&2 2>&3)
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_install_zram() {
echo "Configuring zram.service"
touch /etc/modules-load.d/zram.conf
echo 'zram' > /etc/modules-load.d/zram.conf
touch /etc/modprobe.d/zram.conf
echo 'options zram num_devices=1' > /etc/modprobe.d/zram.conf
touch /etc/udev/rules.d/99-zram.rules
echo "KERNEL==\"zram0\", ATTR{disksize}=\"${new_size}\",TAG+=\"systemd\"" \
> /etc/udev/rules.d/99-zram.rules
touch /etc/systemd/system/zram.service
echo "Installing zram.service"
cat << EOF > /etc/systemd/system/zram.service
[Unit]
Description=Swap with zram
After=multi-user.target
[Service]
Type=oneshot
RemainAfterExit=true
ExecStartPre=/sbin/mkswap /dev/zram0
ExecStart=/sbin/swapon /dev/zram0
ExecStop=/sbin/swapoff /dev/zram0
[Install]
WantedBy=multi-user.target
EOF
systemctl enable zram
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_zram_menu() {
whiptail --yesno "Would like to enable the zram swapping kernel module?" --defaultno 20 60 2
RET=$?
if [ $RET -eq 0 ]; then
do_config_zram
do_install_zram
STATUS=enabled
elif [ $RET -eq 1 ]; then
if [ -e /etc/udev/rules.d/99-zram.rules ];then
systemctl disable --now zram
fi
STATUS=disabled
fi
whiptail --msgbox "ZRAM swapping is $STATUS" 20 60 1
return $RET
}
do_vnc() {
DEFAULT=--defaultno
if [ $(get_vnc) -eq 0 ]; then
DEFAULT=
fi
whiptail --yesno "Would you like the VNC Server to be enabled?" $DEFAULT 20 60 2
RET=$?
if [ $RET -eq 0 ]; then
if is_installed realvnc-vnc-server || apt-get install realvnc-vnc-server; then
systemctl enable vncserver-x11-serviced.service &&
systemctl start vncserver-x11-serviced.service &&
STATUS=enabled
else
return 1
fi
elif [ $RET -eq 1 ]; then
if is_installed realvnc-vnc-server; then
systemctl disable vncserver-x11-serviced.service
systemctl stop vncserver-x11-serviced.service
fi
STATUS=disabled
else
return $RET
fi
whiptail --msgbox "The VNC Server is $STATUS" 20 60 1
}
do_audio() {
if is_pulseaudio ; then
oIFS="$IFS"
list=$(sudo -u $SUDO_USER XDG_RUNTIME_DIR=/run/user/$SUDO_UID pacmd list-sources | grep -B1 -e 'alsa.card_name' -e 'name.*input' | grep -A4 index | sed -e s/*//g | sed s/^[' '\\t]*//g | grep -e index -e card_name | sed s/'index: '//g | sed s/'alsa.card_name = '//g | sed s/\"//g | tr '\n' '\/')
if ! [ -z "$list" ] ; then
IFS="/"
AUDIO_IN=$(whiptail --menu "Choose the audio input" 20 60 10 ${list} 3>&1 1>&2 2>&3)
return 0
else
whiptail --msgbox "No internal audio devices found" 20 60 1
return 1
fi
if [ $? -eq 0 ]; then
sudo -u $SUDO_USER XDG_RUNTIME_DIR=/run/user/$SUDO_UID pactl set-default-source "$AUDIO_IN"
fi
IFS=$oIFS
fi
sudo -u $SUDO_USER pulseaudio -k
}
list_wlan_interfaces() {
for dir in /sys/class/net/*/wireless; do
if [ -d "$dir" ]; then
basename "$(dirname "$dir")"
fi
done
}
do_wifi_ssid_passphrase() {
RET=0
IFACE_LIST="$(list_wlan_interfaces)"
IFACE="$(echo "$IFACE_LIST" | head -n 1)"
if [ -z "$IFACE" ]; then
whiptail --msgbox "No wireless interface found" 20 60
return 1
fi
if ! wpa_cli -i "$IFACE" status > /dev/null 2>&1; then
whiptail --msgbox "Could not communicate with wpa_supplicant" 20 60
return 1
fi
if [ -z "$(get_wifi_country)" ]; then
do_wifi_country
fi
SSID="$1"
while [ -z "$SSID" ] ; do
SSID=$(whiptail --inputbox "Please enter SSID" 20 60 3>&1 1>&2 2>&3)
if [ $? -ne 0 ]; then
return 0
elif [ -z "$SSID" ]; then
whiptail --msgbox "SSID cannot be empty. Please try again." 20 60
fi
done
PASSPHRASE="$2"
PASSPHRASE=$(whiptail --passwordbox "Please enter passphrase. Leave it empty if none." 20 60 3>&1 1>&2 2>&3)
if [ $? -ne 0 ]; then
return 0
else
return 1
fi
# Escape special characters for embedding in regex below
local ssid="$(echo "$SSID" \
| sed 's;\\;\\\\;g' \
| sed -e 's;\.;\\\.;g' \
-e 's;\*;\\\*;g' \
-e 's;\+;\\\+;g' \
-e 's;\?;\\\?;g' \
-e 's;\^;\\\^;g' \
-e 's;\$;\\\$;g' \
-e 's;\/;\\\/;g' \
-e 's;\[;\\\[;g' \
-e 's;\];\\\];g' \
-e 's;{;\\{;g' \
-e 's;};\\};g' \
-e 's;(;\\(;g' \
-e 's;);\\);g' \
-e 's;";\\\\\";g')"
wpa_cli -i "$IFACE" list_networks \
| tail -n +2 | cut -f -2 | grep -P "\t$ssid$" | cut -f1 \
| while read ID; do
wpa_cli -i "$IFACE" remove_network "$ID" > /dev/null 2>&1
done
ID="$(wpa_cli -i "$IFACE" add_network)"
wpa_cli -i "$IFACE" set_network "$ID" ssid "\"$SSID\"" 2>&1 | grep -q "OK"
RET=$((RET + $?))
if [ -z "$PASSPHRASE" ]; then
wpa_cli -i "$IFACE" set_network "$ID" key_mgmt NONE 2>&1 | grep -q "OK"
RET=$((RET + $?))
else
wpa_cli -i "$IFACE" set_network "$ID" psk "\"$PASSPHRASE\"" 2>&1 | grep -q "OK"
RET=$((RET + $?))
fi
if [ $RET -eq 0 ]; then
wpa_cli -i "$IFACE" enable_network "$ID" > /dev/null 2>&1
else
wpa_cli -i "$IFACE" remove_network "$ID" > /dev/null 2>&1
whiptail --msgbox "Failed to set SSID or passphrase" 20 60
fi
wpa_cli -i "$IFACE" save_config > /dev/null 2>&1
echo "$IFACE_LIST" | while read IFACE; do
wpa_cli -i "$IFACE" reconfigure > /dev/null 2>&1
done
return $RET
}
do_reget_birdnetpi_urls() {
birdnetpi_url=$(whiptail --inputbox "Put your domain here. Example: \"https://birdnetpi.pmcgui.xyz\"." \
19 70 -- "https://" 3>&1 1>&2 2>&3) extractionlog_url=$(whiptail --inputbox "Put your domain here. Example: \"https://extractionlog.pmcgui.xyz\"." 19 70 -- "https://" 3>&1 1>&2 2>&3) birdnetlog_url=$(whiptail --inputbox "Put your domain here. Example: \"https://birdnetlog.pmcgui.xyz\"." 19 70 -- "https://" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
else
return 1
fi
}
do_reget_db_pwd() {
db_pwd=$(whiptail --inputbox "Please set the password the 'birder' user will use to access the database." \
19 70 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_reget_birdweather_id() {
birdweather_id=$(whiptail --inputbox "Input your BirdWeather ID" \
19 70 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_reget_caddy_pwd() {
caddy_pwd=$(whiptail --inputbox "Please set the password for the web interface." \
19 70 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_reget_lon() {
lon="$(curl -s4 ifconfig.co/json | awk '/lon/ {print $2}' | tr -d ',')"
new_lon=$(whiptail --inputbox "Please set the longitude where recordings will take place." \
19 70 -- "$lon" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_reget_lat() {
lat="$(curl -s4 ifconfig.co/json | awk '/lat/ {print $2}' | tr -d ',')"
new_lat=$(whiptail --inputbox "Please set the latitude where recordings will take place." \
19 70 -- "$lat" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_confidence() {
confidence="$(awk -F= '/CONFIDENCE=/ {print $2}' ${birdnetpi_dir}/birdnet.conf)"
new_confidence=$(whiptail --inputbox "Please set the minimum confidence score BirdNET-Lite should use." \
19 70 -- "$confidence" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_overlap() {
overlap="$(awk -F= '/OVERLAP=/ {print $2}' ${birdnetpi_dir}/birdnet.conf)"
new_overlap=$(whiptail --inputbox "Please set the overlap BirdNET-Lite should use." \
19 70 -- "$overlap" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_sensitivity() {
sensitivity="$(awk -F= '/SENSITIVITY=/ {print $2}' ${birdnetpi_dir}/birdnet.conf)"
new_sensitivity=$(whiptail --inputbox "Please set the simoid sensitivty BirdNET-Lite should use." \
19 70 -- "$sensitivity" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/rewrite_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_birdnetlog_url() {
birdnetlog_url=$(whiptail --inputbox "Put your domain here. Example: \"https://birdnetlog.pmcgui.xyz\"." \
19 70 -- "https://" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_extractionlog_url() {
extractionlog_url=$(whiptail --inputbox "Put your domain here. Example: \"https://extractionlog.pmcgui.xyz\"." \
19 70 -- "https://" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_birdnetpi_url() {
birdnetpi_url=$(whiptail --inputbox "Put your domain here. Example: \"https://birdnetpi.pmcgui.xyz\"." \
19 70 -- "https://" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_birdweather_id() {
birdweather_id=$(whiptail --inputbox "Input your BirdWeather ID" \
19 70 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_db_pwd() {
db_pwd=$(whiptail --inputbox "Please set the password the 'birder' user will use to access the database." \
19 70 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_ice_pwd() {
ice_pwd=$(whiptail --inputbox "Please set the password for the live stream." \
19 70 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_caddy_pwd() {
caddy_pwd=$(whiptail --inputbox "Please set the password for the web interface." \
19 70 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_lon() {
lon="$(curl -s4 ifconfig.co/json | awk '/lon/ {print $2}' | tr -d ',')"
new_lon=$(whiptail --inputbox "Please set the longitude where recordings will take place." \
19 70 -- "$lon" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_get_lat() {
lat="$(curl -s4 ifconfig.co/json | awk '/lat/ {print $2}' | tr -d ',')"
new_lat=$(whiptail --inputbox "Please set the latitude where recordings will take place." \
19 70 -- "$lat" 3>&1 1>&2 2>&3) ${birdnetpi_dir}/scripts/write_config.sh
if [ $? -eq 0 ];then
return 0
ASK_TO_REBOOT=2
else
return 1
fi
}
do_update_os() {
apt update && apt -y full-upgrade && \
ASK_TO_REBOOT=1
}
do_update_birdnet() {
sudo -E -upi ${birdnetpi_dir}/scripts/update_birdnet.sh
}
do_install_birdnet() {
sudo -E -upi ${birdnetpi_dir}/Birders_Guide_Installer.sh && \
ASK_TO_REBOOT=1
}
insist_on_reboot() {
if [ $ASK_TO_REBOOT -eq 2 ]; then
whiptail --yesno "You really should reboot. Do that now?" 20 60 2
if [ $? -eq 0 ]; then # yes
sync
reboot
fi
fi
}
do_finish() {
if [ $ASK_TO_REBOOT -eq 1 ]; then
whiptail --yesno "Would you like to reboot now?" 20 60 2
if [ $? -eq 0 ]; then # yes
sync
reboot
fi
elif [ $ASK_TO_REBOOT -eq 2 ]; then
whiptail --yesno "You really should reboot. Do that now?" 20 60 2
if [ $? -eq 0 ]; then # yes
sync
reboot
fi
fi
exit 0
}
# Everything else needs to be run as root
if [ $(id -u) -ne 0 ]; then
printf "Script must be run as root. Try 'sudo birdnet-pi-config'\n"
exit 1
fi
do_advanced_reconfig_menu() {
MENU=9
while [ $MENU -eq 9 ];do
if is_pi ; then
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnet-pi-config)" --menu "BirdNET-Pi Configuration Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
"Sensitivity" "Set the sigmoid sensitivity" \
"Confidence" "Set the minimum confidence score required for a detection" \
"Overlap" "Set the analysis overlap in seconds" \
"BirdNET-Pi URLs" "Set the URLs your installation should use" \
3>&1 1>&2 2>&3)
else
exit
fi
RET=$?
if [ $RET -eq 1 ]; then
return 0
MENU=0
elif [ $RET -eq 0 ]; then
case "$FUN" in
Sens*) do_get_sensitivity;;
Confi*) do_get_confidence;;
Overlap*) do_get_overlap;;
Bird*) do_reget_birdnetpi_urls;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
fi
done
}
do_interface_menu() {
MENU=6
while [ $MENU -eq 6 ];do
if is_pi ; then
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnet-pi-config)" --menu "Interfacing Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
"SSH" "Enable/disable remote command line access using SSH" \
"VNC" "Enable/disable graphical remote access using RealVNC" \
3>&1 1>&2 2>&3)
else
exit
fi
RET=$?
if [ $RET -eq 1 ]; then
return 0
MENU=0
elif [ $RET -eq 0 ]; then
case "$FUN" in
SSH*) do_ssh ;;
VNC*) do_vnc ;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
fi
done
}
do_advanced_config_menu() {
MENU=5
while [ $MENU -eq 5 ];do
if is_pi ; then
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnet-pi-config)" --menu "BirdNET-Pi Configuration Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
"Sensitivity" "Set the sigmoid sensitivity" \
"Confidence" "Set the minimum confidence score required for a detection" \
"Overlap" "Set the analysis overlap in seconds" \
"BirdNET-Pi URLs" "Set the URLs your installation should use" \
3>&1 1>&2 2>&3)
else
exit
fi
RET=$?
if [ $RET -eq 1 ]; then
return 0
MENU=0
elif [ $RET -eq 0 ]; then
case "$FUN" in
Sens*) do_get_sensitivity;;
Confi*) do_get_confidence;;
Overlap*) do_get_overlap;;
Bird*) do_get_birdnetpi_url; do_get_birdnetlog_url; do_get_extractionlog_url;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
fi
done
}
do_system_menu() {
MENU=4
while [ $MENU -eq 4 ];do
if is_pi ; then
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnet-pi-config)" --menu "System Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
"Password" "Change password for the '$USER' user" \
"Audio" "Select audio device you'd like BirdNET-Pi to use" \
"Wireless LAN" "Enter SSID and passphrase" \
"Update the OS" "Update the underlying operating system" \
"Interface Options" "Enable/Disable SSH and VNC" \
"Configure zRAM" "Enable/Disable zRAM" \
"Timezone" "Configure time zone" \
"Keyboard" "Set keyboard layout to match your keyboard" \
"WLAN Country" "Set legal wireless channels for your country" \
3>&1 1>&2 2>&3)
else
exit
fi
RET=$?
if [ $RET -eq 1 ]; then
return 0
MENU=0
elif [ $RET -eq 0 ]; then
case "$FUN" in
Password*) do_change_pass ;;
Audio*) do_audio ;;
Wireless*) do_wifi_ssid_passphrase ;;
Update*) do_update_os ;;
Interface*) do_interface_menu ;;
Configure*) do_zram_menu ;;
Time*) do_change_timezone; insist_on_reboot ;;
Key*) do_configure_keyboard ;;
WLAN*) do_wifi_country ;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
fi
done
}
do_reconfig_birdnet_menu() {
MENU=3
while [ $MENU -eq 3 ];do
if is_pi ; then
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnet-pi-config)" --menu "BirdNET-Pi Re-configuration Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
"Latitude " "Set the latitude your system should use" \
"Longitude" "Set the longitude your system should use" \
"Caddy Password" "Set the web interface password" \
"Database Password" "Set the password BirdNET-Pi will use to access the DB" \
"BirdWeather ID" "Input your BirdWeather ID if you have one" \
"Advanced Settings" "Sensitivity, Overlap, Confidence, URLs" \
3>&1 1>&2 2>&3)
else
exit
fi
RET=$?
if [ $RET -eq 1 ]; then
return 0
MENU=0
elif [ $RET -eq 0 ]; then
case "$FUN" in
Lat*) do_reget_lat;;
Lon*) do_reget_lon;;
Cad*) do_reget_caddy_pwd;;
Data*) do_reget_db_pwd;;
Bird*) do_reget_birdweather_id;;
Advanced*) do_advanced_reconfig_menu;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
fi
done
}
do_config_birdnet_menu() {
MENU=2
while [ $MENU -eq 2 ];do
if is_pi ; then
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnet-pi-config)" --menu "BirdNET-Pi Configuration Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
"Latitude " "Set the latitude your system should use" \
"Longitude" "Set the longitude your system should use" \
"Caddy Password" "Set the web interface password" \
"IceCast2 Password" "Set the IceCast2 password" \
"Database Password" "Set the password BirdNET-Pi will use to access the DB" \
"BirdWeather ID" "Input your BirdWeather ID if you have one" \
"Set Custom URLS" "Designate custom URLs for the web services if you've set that up" \
3>&1 1>&2 2>&3)
else
exit
fi
RET=$?
if [ $RET -eq 1 ]; then
return 0
MENU=0
elif [ $RET -eq 0 ]; then
case "$FUN" in
Lat*) do_get_lat;;
Lon*) do_get_lon;;
Cad*) do_get_caddy_pwd;;
Ice*) do_get_ice_pwd;;
Data*) do_get_db_pwd;;
Bird*) do_get_birdweather_id;;
Set*) do_get_birdnetpi_url; do_get_birdnetlog_url; do_get_extractionlog_url;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
fi
done
}
do_internationalisation_menu() {
MENU=1
while [ $MENU -eq 1 ];do
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnet-pi-config)" --menu "Localisation Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
"System Locale" "Configure the system language and regional settings" \
"labels.txt" "Set the language to use for species detection" \
"Time Zone" "Set the Time Zone" \
3>&1 1>&2 2>&3)
RET=$?
if [ $RET -eq 1 ]; then
return 0
MENU=0
elif [ $RET -eq 0 ]; then
case "$FUN" in
System*) do_change_locale;;
label*) get_labels_lang;;
Time*) do_change_timezone;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
fi
done
}
#
# Interactive use loop
#
[ -e $CONFIG ] || touch $CONFIG
calc_wt_size
while [ "$USER" = "root" ] || [ -z "$USER" ]; do
if ! USER=$(whiptail --inputbox "birdnet-pi-config could not determine the default user.\\n\\nWhat user should these settings apply to?" 20 60 pi 3>&1 1>&2 2>&3); then
return 0
fi
done
while true; do
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnet-pi-config)" --backtitle "$(cat /proc/device-tree/model)" --menu "Setup Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Finish --ok-button Select \
"Step 1" "Configure language and timezone" \
"Step 2" "Configure BirdNET-Pi before installation" \
"Step 3" "Install BirdNET-Pi" \
"Step 4" "Reconfigure BirdNET-Pi AFTER installation" \
"Step 5" "Update BirdNET-Pi (run this if you changed URLs)" \
"System Options" "Configure system settings" \
3>&1 1>&2 2>&3)
RET=$?
if [ $RET -eq 1 ]; then
do_finish
elif [ $RET -eq 0 ]; then
case "$FUN" in
*1) do_internationalisation_menu ;;
*2) do_config_birdnet_menu ;;
*3) do_install_birdnet;;
*4) do_reconfig_birdnet_menu ;;
*5) do_update_birdnet;;
Sys*) do_system_menu ;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
fi
done
+3 -4
View File
@@ -34,10 +34,9 @@ if [ ! -z $RTSP_STREAM ];then
do
# Map id used to map input to output (first stream being 0), this is 0 based in ffmpeg so decrement our counter (which is more human readable) by 1
MAP_ID=$((RTSP_STREAMS_STARTED_COUNT-1))
# Build up the parameters to process the RSTP stream, including mapping for the output, because some streams may have more than one audio stream within it, get the first stream
#ffmpeg does this by default when there is only 1 steam, but if there are more than 1 then it doesn't know which one we want
FFMPEG_PARAMS+="-vn -thread_queue_size 512 -i ${i} -map ${MAP_ID} -t ${RECORDING_LENGTH} -acodec pcm_s16le -ac 2 -ar 48000 file:${RECS_DIR}/StreamData/$(date "+%F")-birdnet-RTSP_${RTSP_STREAMS_STARTED_COUNT}-$(date "+%H:%M:%S").wav "
# Increment counter for the next round
# Build up the parameters to process the RSTP stream, including mapping for the output
FFMPEG_PARAMS+="-vn -thread_queue_size 512 -i ${i} -map ${MAP_ID}:a:0 -t ${RECORDING_LENGTH} -acodec pcm_s16le -ac 2 -ar 48000 file:${RECS_DIR}/StreamData/$(date "+%F")-birdnet-RTSP_${RTSP_STREAMS_STARTED_COUNT}-$(date "+%H:%M:%S").wav "
# Increment counter
((RTSP_STREAMS_STARTED_COUNT += 1))
done
+2 -2
View File
@@ -472,7 +472,7 @@ function runProcess() {
<dl>
<dt>BirdNET_6K_GLOBAL_MODEL (2020)</dt><br>
<dd id="ddnewline">This is the BirdNET-Lite model, with bird sound recognition for more than 6,000 species worldwide. This is the default option and will generally work very for people in most of the world.</dd>
<br>
<br>
<dt>BirdNET_GLOBAL_3K_V2.2_Model_FP16 (2022)</dt><br>
<dd id="ddnewline">This is the BirdNET-Analyzer model, a newer work-in-progress project with aims to improve on the BirdNET-Lite model. Currently it only supports about 3,500 species worldwide, meaning for some regions (North America, Europe, Australia) it will usually outperform the BirdNET-Lite model, but for other regions it will be worse.</dd><br>
<dt>[ In-depth technical write-up on the models <a target="_blank" href="https://github.com/mcguirepr89/BirdNET-Pi/wiki/BirdNET-Pi:-some-theory-on-classification-&-some-practical-hints">here</a> ]</dt>
@@ -544,7 +544,7 @@ https://discordapp.com/api/webhooks/{WebhookID}/{WebhookToken}
<input type="checkbox" name="apprise_notify_each_detection" <?php if($config['APPRISE_NOTIFY_EACH_DETECTION'] == 1 && filesize($home."/BirdNET-Pi/apprise.txt") != 0) { echo "checked"; };?> >
<label for="apprise_weekly_report">Notify each new detection</label><br>
<input type="checkbox" name="apprise_weekly_report" <?php if($config['APPRISE_WEEKLY_REPORT'] == 1 && filesize($home."/BirdNET-Pi/apprise.txt") != 0) { echo "checked"; };?> >
<label for="apprise_weekly_report">Send weekly report</label><br>
<label for="apprise_weekly_report">Send <a href="views.php?view=Weekly%20Report"> weekly report</a></label><br>
<hr>
<label for="minimum_time_limit">Minimum time between notifications of the same species (sec):</label>
View File
-20
View File
@@ -1,20 +0,0 @@
#!/bin/bash
# Set variables
db_path=~/BirdNET-Pi/scripts/birds.db
dir_path=~/BirdSongs/Extracted/By_Date
# Calculate the average count of detections for each species
avg_counts=$(sqlite3 $db_path "SELECT Com_Name || '|' || AVG(count) FROM (SELECT Com_Name, COUNT(*) as count FROM detections GROUP BY Com_Name) GROUP BY Com_Name ORDER BY AVG(count)")
# Get the species that are in the bottom 10% of this distribution by count
bottom_10=$(echo "$avg_counts" | awk -F'|' -v n="$(echo "$avg_counts" | wc -l)" 'NR <= n * 0.1 {print $1}')
# Remove all directories from $dir_path that aren't in the bottom 10% rarest
find $dir_path -type d | while read dir; do
dir_name=$(basename "$dir")
if ! echo "$bottom_10" | grep -q "$dir_name"; then
#rm -r "$dir"
echo "REMOVING: $dir"
fi
done
+1 -1
View File
@@ -224,7 +224,7 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" && isse
}
}
if($iterations == 0) {
if($todaycount > 0) {
if($todaycount['COUNT(*)'] > 0) {
echo "<h3>Your system is currently processing a backlog of audio. This can take several hours before normal functionality of your BirdNET-Pi resumes.</h3>";
} else {
echo "<h3>No Detections For Today.</h3>";
+102 -1
View File
@@ -11,6 +11,8 @@ import sqlite3
from sqlite3 import Connection
import plotly.express as px
from sklearn.preprocessing import normalize
from suntime import Sun
from datetime import datetime
pio.templates.default = "plotly_white"
@@ -167,6 +169,68 @@ top_N_species = (df5.value_counts()[:top_N])
font_size = 15
def sunrise_sunset_scatter(num_days_to_display):
latitude = df['Lat'][0]
longitude = df['Lon'][0]
sun = Sun(latitude, longitude)
sunrise_list = []
sunset_list = []
sunrise_week_list = []
sunset_week_list = []
sunrise_text_list = []
sunset_text_list = []
now = datetime.now()
for past_day in range(num_days_to_display):
d = timedelta(days=num_days_to_display - past_day - 1)
current_date = now - d
# current_date = datetime.fromisocalendar(2022, week + 1, 5)
# time_zone = datetime.now()
sun_rise = sun.get_local_sunrise_time(current_date)
sun_dusk = sun.get_local_sunset_time(current_date)
sun_rise_time = float(sun_rise.hour) + float(sun_rise.minute) / 60.0
sun_dusk_time = float(sun_dusk.hour) + float(sun_dusk.minute) / 60.0
temp_time = str(sun_rise)[-14:-9] + " Sunrise"
sunrise_text_list.append(temp_time)
temp_time = str(sun_dusk)[-14:-9] + " Sunset"
sunset_text_list.append(temp_time)
sunrise_list.append(sun_rise_time)
sunset_list.append(sun_dusk_time)
sunrise_week_list.append(past_day)
sunset_week_list.append(past_day)
sunrise_week_list.append(None)
sunrise_list.append(None)
sunrise_text_list.append(None)
sun_list = sunrise_list.extend(sunset_list)
sun_week_list = sunrise_week_list.extend(sunset_week_list)
sunrise_text_list.extend(sunset_text_list)
return sunrise_week_list, sunrise_list, sunrise_text_list
def hms_to_dec(t):
# (h, m, s) = t.split(':')
h = t.hour
m = t.minute / 60
s = t.second / 3600
result = h + m + s
return result
def hms_to_str(t):
# (h, m, s) = t.split(':')
h = t.hour
m = t.minute
# s = t.second / 3600
# result = h + m + s
return "%02d:%02d" % (h, m)
if daily is False:
if resample_time != '1D':
@@ -363,8 +427,11 @@ if daily is False:
df4.index = [df4.index.date, df4.index.time]
day_hour_freq = df4.unstack().fillna(0)
saved_time_labels = [hms_to_str(h) for h in day_hour_freq.columns.tolist()]
fig_dec_y = [hms_to_dec(h) for h in day_hour_freq.columns.tolist()]
fig_x = [d.strftime('%d-%m-%Y') for d in day_hour_freq.index.tolist()]
fig_y = [h.strftime('%H:%M') for h in day_hour_freq.columns.tolist()]
day_hour_freq.columns = fig_dec_y
fig_z = day_hour_freq.values.transpose()
# fig_heatmap = go.Figure(data=go.Heatmap(x=fig_x,y=fig_y,z=fig_z))
@@ -373,7 +440,41 @@ if daily is False:
# yaxis={'categoryorder':'total ascending'})
color_pals = px.colors.named_colorscales()
selected_pal = st.sidebar.selectbox('Select Color Pallet for Daily Detections', color_pals)
fig.add_trace(go.Heatmap(x=fig_x, y=fig_y, z=fig_z, autocolorscale=False, colorscale=selected_pal), row=1, col=1)
heatmap = go.Heatmap(
# x=fig_x, y=fig_y,
x=fig_x,
y=day_hour_freq.columns,
z=fig_z, # heat.values,
showscale=False,
# text=labels,
texttemplate="%{text}", autocolorscale=False, colorscale=selected_pal
)
num_days_to_display = len(fig_x)
sunrise_week_list, sunrise_list, sunrise_text_list = sunrise_sunset_scatter(num_days_to_display)
daysback_range = fig_x
daysback_range.append(None)
daysback_range.extend(daysback_range)
daysback_range = daysback_range[:-1]
sunrise_sunset = go.Scatter(x=daysback_range,
y=sunrise_list,
mode='lines',
hoverinfo='text',
text=sunrise_text_list,
line_color='orange', line_width=1, name=' ')
fig = go.Figure(data=[heatmap, sunrise_sunset])
number_of_y_ticks = 12
y_downscale_factor = int(len(saved_time_labels) / number_of_y_ticks)
fig.update_layout(
yaxis=dict(
tickmode = 'array',
tickvals = day_hour_freq.columns[::y_downscale_factor],
ticktext = saved_time_labels[::y_downscale_factor],
nticks = 6
)
)
st.plotly_chart(fig, use_container_width=True) # , config=config)
else:
fig = make_subplots(
Executable → Regular
+3
View File
@@ -9,6 +9,9 @@ for service in "${services[@]}"; do
echo ""
done
echo "========= Syslog snippet =========="
tail -n 100 /var/log/syslog
# 2. Mounted file systems
echo "========== Mounted File Systems =========="
df -h
-38
View File
@@ -1,38 +0,0 @@
#!/bin/bash
# Connect to the database and extract the data
sqlite3 birds.db <<EOF | while IFS='|' read -r id mean_volume recorded_at; do
.mode csv
.headers off
SELECT id, mean_volume, strftime('%Y-%m-%d %H:00:00', recorded_at) AS hour
FROM volume;
done | {
# Initialize variables for the first hour
current_hour=""
total_volume=0
count=0
# Loop through each row of data
while IFS='|' read -r id mean_volume hour; do
if [[ "$hour" != "$current_hour" ]]; then
# If we've moved on to a new hour, output the previous hour's data
if [[ "$current_hour" != "" ]]; then
echo "$id|$((total_volume/count))|$current_hour"
fi
# Reset the variables for the new hour
current_hour="$hour"
total_volume="$mean_volume"
count=1
else
# If we're still in the same hour, add to the total and count
total_volume="$((total_volume + mean_volume))"
count="$((count + 1))"
fi
done
# Output the final hour's data
echo "$id|$((total_volume/count))|$current_hour"
}
EOF
-16
View File
@@ -1,16 +0,0 @@
#!/bin/bash
# Loop through each entry in birds.db
sqlite3 ~/BirdNET-Pi/scripts/birds.db "SELECT DISTINCT Sci_Name FROM detections" | while read -r row; do
# Get Sci_Name from current row
sci_name=$(echo "$row" | cut -d '|' -f 3)
# Look up ComName for Sci_Name
com_name=$(grep -iE "$sci_name.*" ~/BirdNET-Pi/model/labels.txt | cut -d '_' -f 2-)
if [[ -n "$com_name" ]]; then
# Update Com_Name in birds.db
sqlite3 ~/BirdNET-Pi/scripts/birds.db "UPDATE detections SET Com_Name='$com_name' WHERE Sci_Name='$sci_name'"
echo "SETTING "$com_name" WHERE sciname="$sci_name"\n"
fi
done
+12 -2
View File
@@ -9,12 +9,16 @@ my_dir=$HOME/BirdNET-Pi/scripts
# Sets proper permissions and ownership
#sudo -E chown -R $USER:$USER $HOME/*
#sudo chmod -R g+wr $HOME/*
find $HOME/Bird* -type f ! -perm -g+wr -exec chmod g+wr {} + 2>/dev/null
find $HOME/Bird* -not -user $USER -execdir sudo -E chown $USER:$USER {} \+
find $HOME/Bird* -not -user $USER -execdir sudo chmod g+wr {} \+
chmod 666 ~/BirdNET-Pi/scripts/*.txt
chmod 666 ~/BirdNET-Pi/*.txt
find $HOME/BirdNET-Pi -path "$HOME/BirdNET-Pi/birdnet" -prune -o -type f ! -perm /o=w -exec chmod a+w {} \;
# remove world-writable perms
chmod -R o-w ~/BirdNET-Pi/templates/*
# Create blank sitename as it's optional. First time install will use $HOSTNAME.
if ! grep SITE_NAME /etc/birdnet/birdnet.conf &>/dev/null;then
sudo -u$USER echo "SITE_NAME=\"\"" >> /etc/birdnet/birdnet.conf
@@ -191,7 +195,13 @@ if ! grep RTSP_STREAM_TO_LIVESTREAM /etc/birdnet/birdnet.conf &>/dev/null;then
sudo -u$USER echo "RTSP_STREAM_TO_LIVESTREAM=\"0\"" >> /etc/birdnet/birdnet.conf
fi
# For new Advanced Setting Logging level options,
suntime_installation_status=$(~/BirdNET-Pi/birdnet/bin/python3 -c 'import pkgutil; print("installed" if pkgutil.find_loader("suntime") else "not installed")')
if [[ "$suntime_installation_status" = "not installed" ]];then
$HOME/BirdNET-Pi/birdnet/bin/pip3 install -U pip
$HOME/BirdNET-Pi/birdnet/bin/pip3 install suntime
# For new Advanced Setting Logging level options
if ! grep LogLevel_BirdnetRecordingService /etc/birdnet/birdnet.conf &>/dev/null;then
sudo -u$USER echo "LogLevel_BirdnetRecordingService=\"error\"" >> /etc/birdnet/birdnet.conf
fi