Merge branch 'main' into Configurable-Service-Logging-Options
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -14,3 +14,4 @@ apprise==1.2.1
|
||||
paho-mqtt
|
||||
pytest==7.1.2
|
||||
pytest-mock==3.7.0
|
||||
suntime
|
||||
@@ -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."
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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>
|
||||
|
||||
Executable → Regular
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user