From 46dd8a464c360e78afb0dc5ad2b064b310f3fc0f Mon Sep 17 00:00:00 2001 From: chickadeebird <125906370+chickadeebird@users.noreply.github.com> Date: Fri, 24 Feb 2023 13:01:52 -0500 Subject: [PATCH 01/11] Update plotly_streamlit.py --- scripts/plotly_streamlit.py | 103 +++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/scripts/plotly_streamlit.py b/scripts/plotly_streamlit.py index fe8fa08..8e78784 100755 --- a/scripts/plotly_streamlit.py +++ b/scripts/plotly_streamlit.py @@ -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" @@ -168,6 +170,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': @@ -364,8 +428,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)) @@ -374,7 +441,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( From e0244edd7dd556f078c223e4c20b50ff5ed8287d Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Wed, 12 Apr 2023 18:31:40 -0400 Subject: [PATCH 02/11] Revert "perms" This reverts commit 21beea2f2d9c8d7bbf71b25556536bdd55a10599. --- scripts/automatic.sh | 16 - scripts/birdnet-pi-config.sh | 997 --------------------------- scripts/birdnet-pi.config.sh | 997 --------------------------- scripts/install_language_label_nm.sh | 0 scripts/median.sh | 20 - scripts/print_diagnostic_info.sh | 0 scripts/testvol.sh | 38 - scripts/testy.sh | 16 - 8 files changed, 2084 deletions(-) delete mode 100755 scripts/automatic.sh delete mode 100755 scripts/birdnet-pi-config.sh delete mode 100755 scripts/birdnet-pi.config.sh mode change 100755 => 100644 scripts/install_language_label_nm.sh delete mode 100755 scripts/median.sh mode change 100755 => 100644 scripts/print_diagnostic_info.sh delete mode 100755 scripts/testvol.sh delete mode 100755 scripts/testy.sh diff --git a/scripts/automatic.sh b/scripts/automatic.sh deleted file mode 100755 index c3e9f9b..0000000 --- a/scripts/automatic.sh +++ /dev/null @@ -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." diff --git a/scripts/birdnet-pi-config.sh b/scripts/birdnet-pi-config.sh deleted file mode 100755 index f037783..0000000 --- a/scripts/birdnet-pi-config.sh +++ /dev/null @@ -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 -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 diff --git a/scripts/birdnet-pi.config.sh b/scripts/birdnet-pi.config.sh deleted file mode 100755 index f037783..0000000 --- a/scripts/birdnet-pi.config.sh +++ /dev/null @@ -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 -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 diff --git a/scripts/install_language_label_nm.sh b/scripts/install_language_label_nm.sh old mode 100755 new mode 100644 diff --git a/scripts/median.sh b/scripts/median.sh deleted file mode 100755 index 90e40a9..0000000 --- a/scripts/median.sh +++ /dev/null @@ -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 diff --git a/scripts/print_diagnostic_info.sh b/scripts/print_diagnostic_info.sh old mode 100755 new mode 100644 diff --git a/scripts/testvol.sh b/scripts/testvol.sh deleted file mode 100755 index 889fa52..0000000 --- a/scripts/testvol.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -# Connect to the database and extract the data -sqlite3 birds.db < Date: Wed, 12 Apr 2023 18:33:24 -0400 Subject: [PATCH 03/11] perms --- scripts/update_birdnet_snippets.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/update_birdnet_snippets.sh b/scripts/update_birdnet_snippets.sh index 1d03b0b..179f052 100755 --- a/scripts/update_birdnet_snippets.sh +++ b/scripts/update_birdnet_snippets.sh @@ -9,8 +9,8 @@ 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* -execdir sudo chmod g+wr {} \+ 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 {} \; From c87d507b0b50a01cbf3e91891fe14e05fe70d9a0 Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Wed, 12 Apr 2023 22:00:47 -0400 Subject: [PATCH 04/11] allow user to view Weekly Report page --- scripts/config.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/config.php b/scripts/config.php index fb5c79d..042a866 100644 --- a/scripts/config.php +++ b/scripts/config.php @@ -472,7 +472,7 @@ function runProcess() {
BirdNET_6K_GLOBAL_MODEL (2020)

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.
-
+
BirdNET_GLOBAL_3K_V2.2_Model_FP16 (2022)

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.

[ In-depth technical write-up on the models here ]
@@ -544,7 +544,7 @@ https://discordapp.com/api/webhooks/{WebhookID}/{WebhookToken} >
> -
+

From b37b5ab78176f8ade2db64e5c118a051e9154013 Mon Sep 17 00:00:00 2001 From: jaredb7 Date: Thu, 13 Apr 2023 22:16:25 +1000 Subject: [PATCH 05/11] Make ffmpeg record the first audio stream for RTSP Small fix for now to handle of RTSP streams that may contain more than 1 audio stream within them, we just tell ffmpeg to use the first audio stream for the recording. A future enhancement to this is to allow the user to to set what audio stream to just in case there is a scenario where the first one doesn't work for some reason. --- scripts/birdnet_recording.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/birdnet_recording.sh b/scripts/birdnet_recording.sh index 9f98379..744aa0c 100755 --- a/scripts/birdnet_recording.sh +++ b/scripts/birdnet_recording.sh @@ -29,7 +29,7 @@ if [ ! -z $RTSP_STREAM ];then # Map id used to map input to output, this is 0 based in ffmpeg decrement MAP_ID=$((RTSP_STREAMS_STARTED_COUNT-1)) # 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} -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 " + 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 From 2be0b394ee64078e94abfb37a5feb2a1f1a8c9a7 Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Fri, 14 Apr 2023 16:26:14 -0400 Subject: [PATCH 06/11] fixy --- scripts/update_birdnet_snippets.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/update_birdnet_snippets.sh b/scripts/update_birdnet_snippets.sh index 179f052..0ace380 100755 --- a/scripts/update_birdnet_snippets.sh +++ b/scripts/update_birdnet_snippets.sh @@ -9,7 +9,7 @@ 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* -execdir sudo chmod g+wr {} \+ +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 {} \+ chmod 666 ~/BirdNET-Pi/scripts/*.txt chmod 666 ~/BirdNET-Pi/*.txt From 14f09a02e02df77e2592f69aae122c8b68826d8f Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Sun, 16 Apr 2023 14:58:08 -0400 Subject: [PATCH 07/11] Add syslog snippet to diagnostic info script --- scripts/print_diagnostic_info.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/print_diagnostic_info.sh b/scripts/print_diagnostic_info.sh index df6a3bb..b33d6e9 100644 --- a/scripts/print_diagnostic_info.sh +++ b/scripts/print_diagnostic_info.sh @@ -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 From adce59fe49780134a61a9edfe031eb971fdb6d86 Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Sun, 16 Apr 2023 15:00:24 -0400 Subject: [PATCH 08/11] remove world-writable perms --- scripts/update_birdnet_snippets.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/update_birdnet_snippets.sh b/scripts/update_birdnet_snippets.sh index 0ace380..b4fb2a6 100755 --- a/scripts/update_birdnet_snippets.sh +++ b/scripts/update_birdnet_snippets.sh @@ -15,6 +15,10 @@ 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 From 91d2a6042198fdeac9f6fc297ffe6380cb21fca0 Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Mon, 17 Apr 2023 10:51:27 -0400 Subject: [PATCH 09/11] fix backlog message showing when it shouldn't --- scripts/overview.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/overview.php b/scripts/overview.php index 7f41c1c..9cf96d4 100644 --- a/scripts/overview.php +++ b/scripts/overview.php @@ -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 "

Your system is currently processing a backlog of audio. This can take several hours before normal functionality of your BirdNET-Pi resumes.

"; } else { echo "

No Detections For Today.

"; From 712121e43234a4dfe71b509967020fc10db9a281 Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Mon, 17 Apr 2023 11:05:46 -0400 Subject: [PATCH 10/11] warn user on every page if lon/lat aren't set --- homepage/views.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/homepage/views.php b/homepage/views.php index b4d59a0..987f522 100644 --- a/homepage/views.php +++ b/homepage/views.php @@ -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 "
WARNING: Your latitude and longitude are not set properly. Please do so now in Tools -> Settings.
"; +} +elseif ($config["LATITUDE"] == "0.000") { + echo "
WARNING: Your latitude is not set properly. Please do so now in Tools -> Settings.
"; +} +elseif ($config["LONGITUDE"] == "0.000") { + echo "
WARNING: Your longitude is not set properly. Please do so now in Tools -> Settings.
"; +} ?>