diff --git a/Birders_Guide_Installer.sh b/Birders_Guide_Installer.sh index c45aa57..eec2292 100755 --- a/Birders_Guide_Installer.sh +++ b/Birders_Guide_Installer.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -e my_dir=${HOME}/BirdNET-Pi -branch=main +branch=testing trap '${my_dir}/scripts/dump_logs.sh && exit' EXIT SIGHUP SIGINT @@ -108,7 +108,7 @@ stage_2() { if [ ! -d ${my_dir} ];then cd ~ || exit 1 echo "Cloning the BirdNET-Pi repository $branch branch into your home directory" - git clone -b ${branch} https://github.com/mcguirepr89/BirdNET-Pi.git ~/BirdNET-Pi + git clone --depth 1 -b ${branch} https://github.com/mcguirepr89/BirdNET-Pi.git ~/BirdNET-Pi else cd ${my_dir} && git checkout ${branch} fi @@ -232,19 +232,19 @@ DO_RECORDING=y ################################################################################ #----------------------- Web-hosting/Caddy File-server -----------------------# -#__________The two variables below can be set to enable web access_____________# +#________The four variables below can be set to enable internet access_________# #____________to your data,(e.g., extractions, raw data, live___________________# #______________audio stream, BirdNET.selection.txt files)______________________# # Leave these EMPTY if you do not want to enable web access # -## EXTRACTIONS_URL is the URL where the extractions, data-set, and live-stream +## BIRDNETPI_URL is the URL where the extractions, data-set, and live-stream ## will be web-hosted. If you do not own a domain, or would just prefer to keep -## the BirdNET-Pi on your local network, you can set this to http://localhost. -## Setting this (even to http://localhost) will also allow you to enable the -## GoTTY web logging features below. +## the BirdNET-Pi on your local network, keep this EMPTY. -EXTRACTIONS_URL=http://raspberrypi.local +BIRDNETPI_URL= +EXTRACTIONLOG_URL= +BIRDNETLOG_URL= ## CADDY_PWD is the plaintext password (that will be hashed) and used to access ## the "Processed" directory and live audio stream. This MUST be set if you diff --git a/README.md b/README.md index 0a7e5e0..7ff375f 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,14 @@ # BirdNET-Pi -![version](https://img.shields.io/badge/version-0.2-orange) +![version](https://img.shields.io/badge/version-0.4-blue) A realtime acoustic bird classification system for the Raspberry Pi 4B ## Introduction The BirdNET-Pi project is built on the [TFLite version of BirdNET](https://github.com/kahst/BirdNET-Lite). It is able to recognize bird sounds from a USB sound card in realtime. +[Check out my live system](https://birdnetpi.pmcgui.xyz)
+[and NatureStation.net](https://birds.naturestation.net) + ## Features * 24/7 recording and BirdNET-Lite analysis * Web interface access to all data and logs @@ -24,6 +27,8 @@ The BirdNET-Pi project is built on the [TFLite version of BirdNET](https://githu * A USB Microphone or Sound Card ## Installation +[Headless installation guide available here](https://github.com/mcguirepr89/BirdNET-Pi/wiki/%22Headless%22-installation-using-VNC) + The system can be installed with: ``` curl -s https://raw.githubusercontent.com/mcguirepr89/BirdNET-Pi/main/Birders_Guide_Installer.sh | bash diff --git a/Testing_UPDATER b/Testing_UPDATER deleted file mode 100644 index 1f7ec48..0000000 --- a/Testing_UPDATER +++ /dev/null @@ -1 +0,0 @@ -I hope this works:) diff --git a/birdnet.conf-defaults b/birdnet.conf-defaults index f3de83c..118e0d4 100644 --- a/birdnet.conf-defaults +++ b/birdnet.conf-defaults @@ -53,19 +53,17 @@ DO_RECORDING= ################################################################################ #----------------------- Web-hosting/Caddy File-server -----------------------# -#__________The two variables below can be set to enable web access_____________# +#_______The two variables below can be set to enable internet access___________# #____________to your data,(e.g., extractions, raw data, live___________________# #______________audio stream, BirdNET.selection.txt files)______________________# # Leave these EMPTY if you do not want to enable web access # -## EXTRACTIONS_URL is the URL where the extractions, data-set, and live-stream +## BIRDNETPI_URL is the URL where the extractions, data-set, and live-stream ## will be web-hosted. If you do not own a domain, or would just prefer to keep -## BirdNET-Pi on your local network, you can set this to http://localhost. -## Setting this (even to http://localhost) will also allow you to enable the -## GoTTY web logging features below. +## BirdNET-Pi on your local network, keep this empty. -EXTRACTIONS_URL= +BIRDNETPI_URL= ## CADDY_PWD is the plaintext password (that will be hashed) and used to access ## the "Processed" directory and live audio stream. This MUST be set if you diff --git a/homepage/external.html b/homepage/external.html new file mode 100644 index 0000000..ec8343d --- /dev/null +++ b/homepage/external.html @@ -0,0 +1,60 @@ + + +HTML Frames Example - Content + + + +tbc.... +

Thanks

+stefan kahl +patrick mcguire +

Similar Systems

+

Technical Details

+machine learning +deep learning +

Used Tools

+SoX +ffmpeg +Python +Tensorfflow (Lite) +Rasberian OS +

Disclaimer

+

Other Systems

+links to other systems + + + +

Content

+

Replacing the Contents of the Current Frame

+

Clicking on these links will open the new page within the current frame.

+ + +

Replacing the Whole Frameset

+

When you click on any of the following links, the whole frameset is replaced with the new website. This is because we're using target="_top" in the anchor links.

+ + +

Open a New Window

+

These links open in a new browser window. This is because we use target="_blank".

+ + + + \ No newline at end of file diff --git a/homepage/footer.html b/homepage/footer.html new file mode 100644 index 0000000..86b361f --- /dev/null +++ b/homepage/footer.html @@ -0,0 +1,22 @@ + + +HTML Frames Example - Footer + + + +

Play Live Audio Stream

+

+ + diff --git a/homepage/images/.DS_Store b/homepage/images/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/homepage/images/.DS_Store differ diff --git a/homepage/images/bird.png b/homepage/images/bird.png new file mode 100644 index 0000000..807ea72 Binary files /dev/null and b/homepage/images/bird.png differ diff --git a/homepage/index.html b/homepage/index.html new file mode 100644 index 0000000..d0e9455 --- /dev/null +++ b/homepage/index.html @@ -0,0 +1,40 @@ + + + + +BirdNET-Pi + + + + + + + + + + + + + + + --> + + +<p>This section (everything between the 'noframes' tags) will only be displayed if the users' browser doesn't support frames. You can provide a link to a non-frames version of the website here. Feel free to use HTML tags within this section.</p> + + + + diff --git a/homepage/menu.html b/homepage/menu.html new file mode 100644 index 0000000..9de1d4e --- /dev/null +++ b/homepage/menu.html @@ -0,0 +1,36 @@ + + +HTML Frames Example - Menu + + + +

Extractions

+
By Common Name
+
By Date
+
By Scientific Name
+
Processed
+

External Links

+
BirdNET-Pi Repository
+
Wiki Help Page
+
Weather
+
The Cornell Lab of Ornithology
+ + diff --git a/templates/index.html b/homepage/mobile.html similarity index 100% rename from templates/index.html rename to homepage/mobile.html diff --git a/homepage/top.html b/homepage/top.html new file mode 100644 index 0000000..f56035e --- /dev/null +++ b/homepage/top.html @@ -0,0 +1,42 @@ + + + BirdNET-Pi + + + +
+ +
+

BirdNET-Pi

+

+ Database View | + Spectrogram View | + BirdNET-Lite Log | + Extraction Log | + System Info | + Tools +

+ + diff --git a/scripts/backup_data.php b/scripts/backup_data.php new file mode 100644 index 0000000..c6587be --- /dev/null +++ b/scripts/backup_data.php @@ -0,0 +1,4 @@ + /tmp/birdnetbackup.log 2&>1"); +header('Location: /backup_inprogress.html'); +?> diff --git a/scripts/backup_data.sh b/scripts/backup_data.sh new file mode 100755 index 0000000..2379fde --- /dev/null +++ b/scripts/backup_data.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Tar and compress all data +source /etc/birdnet/birdnet.conf + +tar -czvf /home/pi/BirdNET-Pi/BirdNET-Pi_Data_Dump_$(date +%F).tar.gz ${EXTRACTED} /home/pi/BirdNET-Pi/BirdDB.txt diff --git a/scripts/backup_inprogress.html b/scripts/backup_inprogress.html new file mode 100644 index 0000000..f671163 --- /dev/null +++ b/scripts/backup_inprogress.html @@ -0,0 +1,12 @@ + + + + + + + A backup is being made that includes all of
+ your extractions and the BirdDB.txt
+

+ The backup is in /home/pi/BirdNET-Pi + + diff --git a/scripts/birdnet-pi-config b/scripts/birdnet-pi-config new file mode 100755 index 0000000..b6e5a9c --- /dev/null +++ b/scripts/birdnet-pi-config @@ -0,0 +1,872 @@ +#!/bin/sh +# Altered from raspi-config tool below +# https://github.com/RPi-Distro/birdnetpi-config +# +# See LICENSE file for copyright and license details +# Copyright (c) 2012 Alex Bradbury + +my_dir=$(realpath $(dirname $0)) +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)) +} + +set_config_var() { + lua - "$1" "$2" "$3" < "$3.bak" +local key=assert(arg[1]) +local value=assert(arg[2]) +local fn=assert(arg[3]) +local file=assert(io.open(fn)) +local made_change=false +for line in file:lines() do + if line:match("^#?%s*"..key.."=.*$") then + line=key.."="..value + made_change=true + end + print(line) +end + +if not made_change then + print(key.."="..value) +end +EOF +mv "$3.bak" "$3" +} + +clear_config_var() { + lua - "$1" "$2" < "$2.bak" +local key=assert(arg[1]) +local fn=assert(arg[2]) +local file=assert(io.open(fn)) +for line in file:lines() do + if line:match("^%s*"..key.."=.*$") then + line="#"..line + end + print(line) +end +EOF +mv "$2.bak" "$2" +} + +get_config_var() { + lua - "$1" "$2" < /dev/tty1 >&0 2>&1' + udevadm trigger --subsystem-match=input --action=change + return 0 +} + +do_change_locale() { + if [ "$INTERACTIVE" = True ]; then + dpkg-reconfigure locales + else + local LOCALE="$1" + if ! LOCALE_LINE="$(grep "^$LOCALE " /usr/share/i18n/SUPPORTED)"; then + return 1 + fi + local ENCODING="$(echo $LOCALE_LINE | cut -f2 -d " ")" + echo "$LOCALE $ENCODING" > /etc/locale.gen + sed -i "s/^\s*LANG=\S*/LANG=$LOCALE/" /etc/default/locale + dpkg-reconfigure -f noninteractive locales + fi +} + +do_change_timezone() { + if [ "$INTERACTIVE" = True ]; then + dpkg-reconfigure tzdata + else + local TIMEZONE="$1" + if [ ! -f "/usr/share/zoneinfo/$TIMEZONE" ]; then + return 1; + fi + rm /etc/localtime + echo "$TIMEZONE" > /etc/timezone + dpkg-reconfigure -f noninteractive tzdata + fi +} + +get_wifi_country() { + CODE=${1:-0} + IFACE="$(list_wlan_interfaces | head -n 1)" + if [ -z "$IFACE" ]; then + if [ "$INTERACTIVE" = True ]; then + whiptail --msgbox "No wireless interface found" 20 60 + fi + return 1 + fi + if ! wpa_cli -i "$IFACE" status > /dev/null 2>&1; then + if [ "$INTERACTIVE" = True ]; then + whiptail --msgbox "Could not communicate with wpa_supplicant" 20 60 + fi + 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 + if [ "$INTERACTIVE" = True ]; then + whiptail --msgbox "No wireless interface found" 20 60 + fi + return 1 + fi + + if ! wpa_cli -i "$IFACE" status > /dev/null 2>&1; then + if [ "$INTERACTIVE" = True ]; then + whiptail --msgbox "Could not communicate with wpa_supplicant" 20 60 + fi + return 1 + fi + + oIFS="$IFS" + if [ "$INTERACTIVE" = True ]; then + 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) + else + COUNTRY=$1 + true + fi + 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 + if [ "$INTERACTIVE" = True ]; then + whiptail --msgbox "Wireless LAN country set to $COUNTRY" 20 60 1 + fi + 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 + if [ "$INTERACTIVE" = True ]; then + 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=$? + else + RET=$1 + fi + 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 + if [ "$INTERACTIVE" = True ]; then + whiptail --msgbox "The SSH server is $STATUS" 20 60 1 + fi +} + +get_vnc() { + if systemctl status vncserver-x11-serviced.service | grep -q -w active; then + echo 0 + else + echo 1 + fi +} + +do_vnc() { + DEFAULT=--defaultno + if [ $(get_vnc) -eq 0 ]; then + DEFAULT= + fi + if [ "$INTERACTIVE" = True ]; then + whiptail --yesno "Would you like the VNC Server to be enabled?" $DEFAULT 20 60 2 + RET=$? + else + RET=$1 + fi + 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 + if [ "$INTERACTIVE" = True ]; then + whiptail --msgbox "The VNC Server is $STATUS" 20 60 1 + fi +} + +disable_raspi_config_at_boot() { + if [ -e /etc/profile.d/birdnetpi-config.sh ]; then + rm -f /etc/profile.d/birdnetpi-config.sh + if [ -e /etc/systemd/system/getty@tty1.service.d/birdnetpi-config-override.conf ]; then + rm /etc/systemd/system/getty@tty1.service.d/birdnetpi-config-override.conf + fi + telinit q + fi +} + +get_boot_cli() { + if systemctl get-default | grep -q multi-user ; then + echo 0 + else + echo 1 + fi +} + +get_autologin() { + if [ $(get_boot_cli) -eq 0 ]; then + # booting to CLI + # stretch or buster - is there an autologin conf file? + if [ -e /etc/systemd/system/getty@tty1.service.d/autologin.conf ] ; then + echo 0 + else + # stretch or earlier - check the getty service symlink for autologin + if [ $(deb_ver) -le 9 ] && grep -q autologin /etc/systemd/system/getty.target.wants/getty@tty1.service ; then + echo 0 + else + echo 1 + fi + fi + else + # booting to desktop - check the autologin for lightdm + if grep -q "^autologin-user=" /etc/lightdm/lightdm.conf ; then + echo 0 + else + echo 1 + fi + fi +} + +do_update() { + apt-get update && + apt-get install birdnetpi-config && + printf "Sleeping 5 seconds before reloading birdnetpi-config\n" && + sleep 5 && + exec birdnetpi-config +} + +do_audio() { + if is_pulseaudio ; then + oIFS="$IFS" + if [ "$INTERACTIVE" = True ]; then + list=$(sudo -u $SUDO_USER XDG_RUNTIME_DIR=/run/user/$SUDO_UID pacmd list-sinks | grep -e index -e alsa.name | sed s/*//g | sed s/^[' '\\t]*//g | sed s/'index: '//g | sed s/'alsa.name = '//g | sed s/'bcm2835 '//g | sed s/\"//g | tr '\n' '/') + if ! [ -z "$list" ] ; then + IFS="/" + AUDIO_OUT=$(whiptail --menu "Choose the audio output" 20 60 10 ${list} 3>&1 1>&2 2>&3) + else + whiptail --msgbox "No internal audio devices found" 20 60 1 + return 1 + fi + else + AUDIO_OUT=$1 + true + fi + if [ $? -eq 0 ]; then + sudo -u $SUDO_USER XDG_RUNTIME_DIR=/run/user/$SUDO_UID pactl set-default-sink $AUDIO_OUT + fi + IFS=$oIFS + else + if aplay -l | grep -q "bcm2835 ALSA"; then + if [ "$INTERACTIVE" = True ]; then + AUDIO_OUT=$(whiptail --menu "Choose the audio output" 20 60 10 \ + "0" "Auto" \ + "1" "Force 3.5mm ('headphone') jack" \ + "2" "Force HDMI" \ + 3>&1 1>&2 2>&3) + else + AUDIO_OUT=$1 + fi + if [ $? -eq 0 ]; then + amixer cset numid=3 "$AUDIO_OUT" + fi + else + ASPATH=$(getent passwd $USER | cut -d : -f 6)/.asoundrc + if [ "$INTERACTIVE" = True ]; then + CARD0=$(LC_ALL=C aplay -l | grep bcm2835 | grep "card 0" | cut -d [ -f 3 | cut -d ] -f 1 | cut -d ' ' -f 2-) + CARD1=$(LC_ALL=C aplay -l | grep bcm2835 | grep "card 1" | cut -d [ -f 3 | cut -d ] -f 1 | cut -d ' ' -f 2-) + CARD2=$(LC_ALL=C aplay -l | grep bcm2835 | grep "card 2" | cut -d [ -f 3 | cut -d ] -f 1 | cut -d ' ' -f 2-) + if ! [ -z "$CARD2" ]; then + AUDIO_OUT=$(whiptail --menu "Choose the audio output" 20 60 10 \ + "0" "$CARD0" \ + "1" "$CARD1" \ + "2" "$CARD2" \ + 3>&1 1>&2 2>&3) + elif ! [ -z "$CARD1" ]; then + AUDIO_OUT=$(whiptail --menu "Choose the audio output" 20 60 10 \ + "0" "$CARD0" \ + "1" "$CARD1" \ + 3>&1 1>&2 2>&3) + elif ! [ -z "$CARD0" ]; then + AUDIO_OUT=$(whiptail --menu "Choose the audio output" 20 60 10 \ + "0" "$CARD0" \ + 3>&1 1>&2 2>&3) + else + whiptail --msgbox "No internal audio devices found" 20 60 1 + false + fi + else + AUDIO_OUT=$1 + fi + if [ $? -eq 0 ]; then + cat << EOF > $ASPATH +pcm.!default { + type asym + playback.pcm { + type plug + slave.pcm "output" + } + capture.pcm { + type plug + slave.pcm "input" + } +} + +pcm.output { + type hw + card $AUDIO_OUT +} + +ctl.!default { + type hw + card $AUDIO_OUT +} +EOF + fi + fi + fi +} + +do_resolution() { + if [ "$INTERACTIVE" = True ]; then + CMODE=$(get_config_var hdmi_mode $CONFIG) + CGROUP=$(get_config_var hdmi_group $CONFIG) + if [ $CMODE -eq 0 ] ; then + CSET="Default" + elif [ $CGROUP -eq 2 ] ; then + CSET="DMT Mode "$CMODE + else + CSET="CEA Mode "$CMODE + fi + oIFS="$IFS" + IFS="/" + if tvservice -d /dev/null | grep -q Nothing ; then + value="Default/720x480/DMT Mode 4/640x480 60Hz 4:3/DMT Mode 9/800x600 60Hz 4:3/DMT Mode 16/1024x768 60Hz 4:3/DMT Mode 85/1280x720 60Hz 16:9/DMT Mode 35/1280x1024 60Hz 5:4/DMT Mode 51/1600x1200 60Hz 4:3/DMT Mode 82/1920x1080 60Hz 16:9/" + else + value="Default/Monitor preferred resolution/" + value=$value$(tvservice -m CEA | grep progressive | cut -b 12- | sed 's/mode \([0-9]\+\): \([0-9]\+\)x\([0-9]\+\) @ \([0-9]\+\)Hz \([0-9]\+\):\([0-9]\+\), clock:[0-9]\+MHz progressive/CEA Mode \1\/\2x\3 \4Hz \5:\6/' | tr '\n' '/') + value=$value$(tvservice -m DMT | grep progressive | cut -b 12- | sed 's/mode \([0-9]\+\): \([0-9]\+\)x\([0-9]\+\) @ \([0-9]\+\)Hz \([0-9]\+\):\([0-9]\+\), clock:[0-9]\+MHz progressive/DMT Mode \1\/\2x\3 \4Hz \5:\6/' | tr '\n' '/') + fi + RES=$(whiptail --default-item $CSET --menu "Choose screen resolution" 20 60 10 ${value} 3>&1 1>&2 2>&3) + STATUS=$? + IFS=$oIFS + if [ $STATUS -eq 0 ] ; then + GRS=$(echo "$RES" | cut -d ' ' -f 1) + MODE=$(echo "$RES" | cut -d ' ' -f 3) + if [ $GRS = "Default" ] ; then + MODE=0 + elif [ $GRS = "DMT" ] ; then + GROUP=2 + else + GROUP=1 + fi + fi + else + GROUP=$1 + MODE=$2 + STATUS=0 + fi + if [ $STATUS -eq 0 ]; then + if [ $MODE -eq 0 ]; then + clear_config_var hdmi_force_hotplug $CONFIG + clear_config_var hdmi_group $CONFIG + clear_config_var hdmi_mode $CONFIG + else + set_config_var hdmi_force_hotplug 1 $CONFIG + set_config_var hdmi_group $GROUP $CONFIG + set_config_var hdmi_mode $MODE $CONFIG + fi + if [ "$INTERACTIVE" = True ]; then + if [ $MODE -eq 0 ] ; then + whiptail --msgbox "The resolution is set to default" 20 60 1 + else + whiptail --msgbox "The resolution is set to $GRS mode $MODE" 20 60 1 + fi + fi + if [ $MODE -eq 0 ] ; then + TSET="Default" + elif [ $GROUP -eq 2 ] ; then + TSET="DMT Mode "$MODE + else + TSET="CEA Mode "$MODE + fi + if [ "$TSET" != "$CSET" ] ; then + ASK_TO_REBOOT=1 + fi + fi +} + +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 + if [ "$INTERACTIVE" = True ]; then + whiptail --msgbox "No wireless interface found" 20 60 + fi + return 1 + fi + + if ! wpa_cli -i "$IFACE" status > /dev/null 2>&1; then + if [ "$INTERACTIVE" = True ]; then + whiptail --msgbox "Could not communicate with wpa_supplicant" 20 60 + fi + return 1 + fi + + if [ "$INTERACTIVE" = True ] && [ -z "$(get_wifi_country)" ]; then + do_wifi_country + fi + + SSID="$1" + while [ -z "$SSID" ] && [ "$INTERACTIVE" = True ]; 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" + while [ "$INTERACTIVE" = True ]; do + 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 + break + fi + done + + # 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 + if [ "$INTERACTIVE" = True ]; then + whiptail --msgbox "Failed to set SSID or passphrase" 20 60 + fi + 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_update() { + apt update && apt -y full-upgrade + ASK_TO_REBOOT=1 +} + +do_install_birdnet() { + ${my_dir}/Birders_Guide_Installer.sh + ASK_TO_REBOOT=1 +} + +do_finish() { + disable_raspi_config_at_boot + 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 + 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 birdnetpi-config'\n" + exit 1 +fi + +if [ -n "${OPT_MEMORY_SPLIT:-}" ]; then + set -e # Fail when a command errors + set_memory_split "${OPT_MEMORY_SPLIT}" + exit 0 +fi + +do_system_menu() { + if is_pi ; then + FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnetpi-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" \ + 3>&1 1>&2 2>&3) + else + exit + fi + RET=$? + if [ $RET -eq 1 ]; then + return 0 + elif [ $RET -eq 0 ]; then + case "$FUN" in + Password*) do_change_pass ;; + Audio*) do_audio ;; + Wireless*) do_wifi_ssid_passphrase ;; + *) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;; + esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1 + fi +} + +do_display_menu() { + if is_pi ; then + FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnetpi-config)" --menu "Display Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \ + "Resolution" "Set a specific screen resolution" \ + 3>&1 1>&2 2>&3) + else + exit + fi + RET=$? + if [ $RET -eq 1 ]; then + return 0 + elif [ $RET -eq 0 ]; then + case "$FUN" in + Resolution*) do_resolution ;; + *) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;; + esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1 + fi +} + +do_interface_menu() { + if is_pi ; then + FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnetpi-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 + 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 +} + +do_internationalisation_menu() { + FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnetpi-config)" --menu "Localisation Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \ + "Locale" "Configure language and regional settings" \ + "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) + RET=$? + if [ $RET -eq 1 ]; then + return 0 + elif [ $RET -eq 0 ]; then + case "$FUN" in + Locale*) do_change_locale ;; + Time*) do_change_timezone ;; + 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 +} +# +# Interactive use loop +# +if [ "$INTERACTIVE" = True ]; then + [ -e $CONFIG ] || touch $CONFIG + calc_wt_size + while [ "$USER" = "root" ] || [ -z "$USER" ]; do + if ! USER=$(whiptail --inputbox "birdnetpi-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 + if is_pi ; then + FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnetpi-config)" --backtitle "$(cat /proc/device-tree/model)" --menu "Setup Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Finish --ok-button Select \ + "System Options" "Configure system settings" \ + "Display Options" "Configure display settings" \ + "Interface Options" "Configure connections to peripherals" \ + "Localisation Options" "Configure language and regional settings" \ + "Update the OS" "Update the underlying operating system" \ + "Install BirdNET-PI" "Install BirdNET-Pi" \ + 3>&1 1>&2 2>&3) + else + exit + fi + RET=$? + if [ $RET -eq 1 ]; then + do_finish + elif [ $RET -eq 0 ]; then + case "$FUN" in + System*) do_system_menu ;; + Display*) do_display_menu ;; + Interface*) do_interface_menu ;; + Localisation*) do_internationalisation_menu ;; + Update*) do_update;; + Install*) do_install_birdnet;; + *) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;; + esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1 + else + exit 1 + fi + done +fi diff --git a/scripts/clear_all_data.php b/scripts/clear_all_data.php index 4a187de..b0be43d 100644 --- a/scripts/clear_all_data.php +++ b/scripts/clear_all_data.php @@ -1,4 +1,4 @@ diff --git a/scripts/dump_logs.sh b/scripts/dump_logs.sh index 101e967..bc11c8b 100755 --- a/scripts/dump_logs.sh +++ b/scripts/dump_logs.sh @@ -3,25 +3,14 @@ # set -x # Uncomment to debug source /etc/birdnet/birdnet.conf &> /dev/null LOG_DIR="${HOME}/BirdNET-Pi/logs" -SERVICES=(avahi-alias@.service -birdnet_analysis.service -birdnet_log.service -birdnet_recording.service -birdstats.service -birdterminal.service -caddy.service -extraction_log.service -extraction.service -extraction.timer -icecast2.service -livestream.service -${SYSTEMD_MOUNT}) + +services=$(awk '/service/ && /systemctl/ && !/php/ {print $3}' ${my_dir}/install_services.sh | sort) # Create logs directory [ -d ${LOG_DIR} ] || mkdir ${LOG_DIR} # Create services logs -for i in "${SERVICES[@]}";do +for i in "${services[@]}";do if [ -L /etc/systemd/system/multi-user.target.wants/${i} ];then journalctl -u ${i} -n 100 --no-pager > ${LOG_DIR}/${i}.log cp -L /etc/systemd/system/multi-user.target.wants/${i} ${LOG_DIR}/${i} diff --git a/scripts/index.html b/scripts/index.html index 7c52582..be41683 100644 --- a/scripts/index.html +++ b/scripts/index.html @@ -27,12 +27,15 @@ +
+ +
-
+
diff --git a/scripts/install_birdnet.sh b/scripts/install_birdnet.sh index 458f99c..6b620fc 100755 --- a/scripts/install_birdnet.sh +++ b/scripts/install_birdnet.sh @@ -98,10 +98,7 @@ echo " BirdNet is installed!! 'sudo systemctl disable --now birdnet_analysis.service' Visit - http://birdnetpi.local to see your extractions, - http://birdlog.local to see the log output of the birdnet_analysis.service, - http://extractionlog.local to see the log output of the extraction.service, and - http://birdstats.local to see the BirdNET-Pi Report" + the BirdNET-Pi homepage at http://birdnetpi.local" echo read -n1 -p " Would you like to run the birdnet_analysis.service now?" YN echo diff --git a/scripts/install_config.sh b/scripts/install_config.sh index 2dafe15..e435af7 100755 --- a/scripts/install_config.sh +++ b/scripts/install_config.sh @@ -43,7 +43,7 @@ get_DO_RECORDING() { done } -get_EXTRACTIONS_URL() { +get_BIRDNETPI_URL() { while true;do read -n1 -p "Would you like to access the extractions via a web browser? @@ -56,11 +56,11 @@ get_EXTRACTIONS_URL() { case $CADDY_SERVICE in [Yy] ) read -p "What URL would you like to publish the extractions to? *Note: Set this to http://localhost if you do not want to make the - extractions publically available: " EXTRACTIONS_URL + extractions publically available: " BIRDNETPI_URL get_CADDY_PWD get_ICE_PWD break;; - [Nn] ) EXTRACTIONS_URL= CADDY_PWD= ICE_PWD=;break;; + [Nn] ) BIRDNETPI_URL= CADDY_PWD= ICE_PWD=;break;; * ) echo "Please answer Yes or No";; esac done @@ -165,7 +165,7 @@ configure() { get_DB_PWDS get_DO_EXTRACTIONS get_DO_RECORDING - get_EXTRACTIONS_URL + get_BIRDNETPI_URL get_PUSHED get_INSTALL_NOMACHINE get_CHANNELS @@ -226,19 +226,21 @@ DO_RECORDING=${DO_RECORDING} ################################################################################ #----------------------- Web-hosting/Caddy File-server -----------------------# -#__________The two variables below can be set to enable web access_____________# +#________The four variables below can be set to enable internet access_________# #____________to your data,(e.g., extractions, raw data, live___________________# #______________audio stream, BirdNET.selection.txt files)______________________# # Leave these EMPTY if you do not want to enable web access # -## EXTRACTIONS_URL is the URL where the extractions, data-set, and live-stream +## BIRDNETPI_URL is the URL where the extractions, data-set, and live-stream ## will be web-hosted. If you do not own a domain, or would just prefer to keep ## BirdNET-Pi on your local network, you can set this to http://localhost. ## Setting this (even to http://localhost) will also allow you to enable the ## GoTTY web logging features below. -EXTRACTIONS_URL=${EXTRACTIONS_URL} +BIRDNETPI_URL=${BIRDNETPI_URL} +EXTRACTIONLOG_URL=${EXTRACTIONLOG_URL} +BIRDNETLOG_URL=${BIRDNETLOG_URL} ## CADDY_PWD is the plaintext password (that will be hashed) and used to access ## the "Processed" directory and live audio stream. This MUST be set if you diff --git a/scripts/install_services.sh b/scripts/install_services.sh index 388e029..b73ffed 100755 --- a/scripts/install_services.sh +++ b/scripts/install_services.sh @@ -11,6 +11,14 @@ nomachine_url="https://download.nomachine.com/download/7.6/Arm/nomachine_7.6.2_3 gotty_url="https://github.com/yudai/gotty/releases/download/v1.0.1/gotty_linux_arm.tar.gz" config_file="$(dirname ${my_dir})/birdnet.conf" +set_hostname() { + if [ "$(hostname)" != "birdnetpi" ];then + echo "Setting hostname to 'birdnetpi'" + hostnamectl set-hostname birdnetpi + sed -i 's/raspberrypi/birdnetpi/g' /etc/hosts + fi +} + install_scripts() { echo "Installing BirdNET-Pi scripts to /usr/local/bin" ln -sf ${my_dir}/* /usr/local/bin/ @@ -90,7 +98,7 @@ ExecStart=/usr/local/bin/species_notifier.sh [Install] WantedBy=multi-user.target EOF - systemctl enable --now pushed_notifications + systemctl enable pushed_notifications.service } create_necessary_dirs() { @@ -100,15 +108,33 @@ create_necessary_dirs() { [ -d ${EXTRACTED}/By_Common_Name ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Common_Name [ -d ${EXTRACTED}/By_Scientific_Name ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Scientific_Name [ -d ${PROCESSED} ] || sudo -u ${USER} mkdir -p ${PROCESSED} - [ -L ${EXTRACTED}/index.html ] || sudo -u ${USER} ln -s $(dirname ${my_dir})/templates/index.html ${EXTRACTED} - [ -L ${EXTRACTED}/scripts ] || sudo -u ${USER} ln -s $(dirname ${my_dir})/scripts ${EXTRACTED} - [ -L ${EXTRACTED}/spectrogram.php ] || sudo -u ${USER} ln -s $(dirname ${my_dir})/scripts/spectrogram.* ${EXTRACTED} - [ -L ${EXTRACTED}/viewdb.php ] || sudo -u ${USER} ln -s $(dirname ${my_dir})/scripts/viewdb.php ${EXTRACTED} - sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED} - [ -L ${EXTRACTED}/phpsysinfo.ini ] || sudo -u ${USER} cp ${HOME}/phpsysinfo/phpsysinfo.ini.new ${HOME}/phpsysinfo/phpsysinfo.ini + sudo -u ${USER} ln -fs $(dirname ${my_dir})/homepage/* ${EXTRACTED} + if [ ! -z ${BIRDNETLOG_URL} ];then + BIRDNETLOG_URL="$(echo ${BIRDNETLOG_URL} | sed 's/\/\//\\\/\\\//g')" + sudo -u${USER} sed -i "s/http:\/\/birdnetpi.local:8080/"${BIRDNETLOG_URL}"/g" $(dirname ${my_dir})/homepage/*.html + fi + if [ ! -z ${EXTRACTIONLOG_URL} ];then + EXTRACTIONLOG_URL="$(echo ${EXTRACTIONLOG_URL} | sed 's/\/\//\\\/\\\//g')" + sudo -u${USER} sed -i "s/http:\/\/birdnetpi.local:8888/"${EXTRACTIONLOG_URL}"/g" $(dirname ${my_dir})/homepage/*.html + fi + + sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts ${EXTRACTED} + if [ ! -z ${BIRDNETPI_URL} ];then + BIRDNETPI_URL="$(echo ${BIRDNETPI_URL} | sed 's/\/\//\\\/\\\//g')" + sudo -u${USER} sed -i "s/http:\/\/birdnetpi.local/"${BIRDNETPI_URL}"/g" $(dirname ${my_dir})/homepage/*.html + phpfiles="$(grep -l birdnetpi.local ${my_dir}/*.php)" + for i in "${phpfiles[@]}";do + sudo -u${USER} sed -i "s/http:\/\/birdnetpi.local/"${BIRDNETPI_URL}"/g" ${i} + done + fi + + sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/spectrogram.php ${EXTRACTED} + sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/viewdb.php ${EXTRACTED} + sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED} + [ -L ${EXTRACTED}/phpsysinfo/phpsysinfo.ini ] || sudo -u ${USER} cp ${HOME}/phpsysinfo/phpsysinfo.ini.new ${HOME}/phpsysinfo/phpsysinfo.ini } - + install_alsa() { echo "Checking for alsa-utils and pulseaudio" if which arecord &> /dev/null ;then @@ -172,26 +198,7 @@ install_Caddyfile() { fi HASHWORD=$(caddy hash-password -plaintext ${CADDY_PWD}) cat << EOF > /etc/caddy/Caddyfile -${EXTRACTIONS_URL} { - root * ${EXTRACTED} - file_server browse - basicauth /Processed* { - birdnet ${HASHWORD} - } - basicauth /scripts* { - birdnet ${HASHWORD} - } - basicauth /stream { - birdnet ${HASHWORD} - } - basicauth /phpsysinfo* { - birdnet ${HASHWORD} - } - reverse_proxy /stream localhost:8000 - php_fastcgi unix//run/php/php7.3-fpm.sock -} - -http://birdnetpi.local { +http://localhost http://birdnetpi.local ${BIRDNETPI_URL} { root * ${EXTRACTED} file_server browse basicauth /Processed* { @@ -210,6 +217,22 @@ http://birdnetpi.local { php_fastcgi unix//run/php/php7.3-fpm.sock } EOF + if [ ! -z ${EXTRACTIONLOG_URL} ];then + cat << EOF >> /etc/caddy/Caddyfile + +${EXTRACTIONLOG_URL} { + reverse_proxy localhost:8888 +} +EOF + fi + if [ ! -z ${BIRDNETLOG_URL} ];then + cat << EOF >> /etc/caddy/Caddyfile + +${BIRDNETLOG_URL} { + reverse_proxy localhost:8080 +} +EOF + fi systemctl reload caddy } @@ -234,7 +257,7 @@ ExecStart=/bin/bash -c "/usr/bin/avahi-publish -a -R %I $(avahi-resolve -4 -n %H [Install] WantedBy=multi-user.target EOF - systemctl enable --now avahi-alias@birdnetpi.local.service + systemctl enable avahi-alias@birdnetpi.local.service } install_spectrogram_service() { @@ -250,7 +273,7 @@ ExecStart=/usr/local/bin/spectrogram.sh [Install] WantedBy=multi-user.target EOF - systemctl enable --now spectrogram_viewer.service + systemctl enable spectrogram_viewer.service } install_gotty_logs() { @@ -277,7 +300,7 @@ ExecStart=/usr/local/bin/gotty -p 8080 --title-format "BirdNET-Pi Log" journalct [Install] WantedBy=multi-user.target EOF - systemctl enable --now birdnet_log.service + systemctl enable birdnet_log.service echo "Installing the extraction_log.service" cat << EOF > /etc/systemd/system/extraction_log.service [Unit] @@ -294,7 +317,7 @@ ExecStart=/usr/local/bin/gotty -p 8888 --title-format "Extractions Log" journalc [Install] WantedBy=multi-user.target EOF - systemctl enable --now extraction_log.service + systemctl enable extraction_log.service } install_sox() { @@ -357,12 +380,12 @@ install_icecast() { echo "icecast2 icecast2/icecast-setup boolean false" | debconf-set-selections apt install -qqy icecast2 config_icecast - systemctl enable --now icecast2 + systemctl enable icecast2.service /etc/init.d/icecast2 start else echo "Icecast2 is installed" config_icecast - systemctl enable --now icecast2 + systemctl enable icecast2.service /etc/init.d/icecast2 start fi } @@ -395,7 +418,7 @@ ExecStart=/usr/local/bin/livestream.sh [Install] WantedBy=multi-user.target EOF - systemctl enable --now livestream.service + systemctl enable livestream.service } install_nomachine() { @@ -419,6 +442,7 @@ install_cleanup_cron() { } install_selected_services() { + set_hostname install_scripts install_birdnet_analysis @@ -431,7 +455,6 @@ install_selected_services() { install_recording_service fi - if [ ! -z "${EXTRACTIONS_URL}" ];then install_caddy install_Caddyfile install_avahi_aliases @@ -442,7 +465,6 @@ install_selected_services() { install_spectrogram_service install_edit_birdnet_conf install_pushed_notifications - fi if [ ! -z "${ICE_PWD}" ];then install_icecast diff --git a/scripts/install_tmux_services.sh b/scripts/install_tmux_services.sh deleted file mode 100755 index 49512af..0000000 --- a/scripts/install_tmux_services.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env bash -# This script installs a web-based terminal @ http://birdterminal.local -# ONLY run this additional script if you trust everyone on your -# local network completely as the credentials are sent WITHOUT -# any SSL/TLS encryption. For a secure remote connection to your -# BirdNET-Pi command line, consider enabling SSH on the -# Raspberry Pi and using another Linux machine or an SSH -# client software, or you can alternately add the 'tls internal' -# directive to the Caddyfile to add a self-signed certificate for TLS/SSL -# encryption. For remote desktop access, NoMachine can be installed. -source /etc/birdnet/birdnet.conf -my_dir=$(realpath $(dirname $0)) - -# Install tmux from version control -install_tmux() { - DEPENDS=( - automake - autoconf - libevent-2* - libevent-dev - ncurses-bin - ncurses-base - ncurses-term - libncurses-dev - build-essential - bison - pkg-config - gcc - ) - - if which tmux &>/dev/null; then - echo "tmux is installed" - else - - sudo apt update && sudo apt -y install "${DEPENDS[@]}" - - cd ${HOME} && git clone https://github.com/tmux/tmux.git - cd tmux - sh autogen.sh - ./configure && make && sudo make install - cd && rm -drf ./tmux - sudo ln -sf "$(dirname ${my_dir})/templates/tmux.conf" /etc/tmux.conf - fi -} - -install_web_terminal() { - cat << EOF | sudo tee /etc/systemd/system/birdterminal.service -[Unit] -Description=A BirdNET-Pi Web Terminal - -[Service] -Restart=on-failure -RestartSec=3 -Type=simple -User=${BIRDNET_USER} -Environment=TERM=xterm-256color -ExecStart=/usr/local/bin/gotty -w --title-format "Login!" -p 9111 tmux new -A -s Login sudo bash -c login - -[Install] -WantedBy=multi-user.target -EOF - HASHWORD="$(caddy hash-password -plaintext "${CADDY_PWD}")" - cat << EOF | sudo tee -a /etc/caddy/Caddyfile -http://birdterminal.local { - reverse_proxy localhost:9111 - basicauth { - birdnet "${HASHWORD}" - } -} -EOF - sudo systemctl enable --now birdterminal.service - sudo systemctl enable --now avahi-alias@birdterminal.local.service - sudo systemctl restart caddy -} -install_tmux -install_web_terminal diff --git a/scripts/reboot_system.php b/scripts/reboot_system.php index df7c8d0..e7f56d8 100644 --- a/scripts/reboot_system.php +++ b/scripts/reboot_system.php @@ -1,4 +1,3 @@ diff --git a/scripts/rebuild_db.sh b/scripts/rebuild_db.sh new file mode 100755 index 0000000..fed7f04 --- /dev/null +++ b/scripts/rebuild_db.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +# Rebuild DB from BirdDB.txt +source /etc/birdnet/birdnet.conf +BIRDNET_DIR=/home/pi/BirdNET-Pi +sudo ${BIRDNET_DIR}/scripts/createdb.sh +sudo mysql birds -e " + LOAD DATA LOCAL INFILE '/home/pi/BirdNET-Pi/BirdDB.txt' + INTO TABLE detections + FIELDS TERMINATED BY ';'" diff --git a/scripts/restart_birdnet_analysis.php b/scripts/restart_birdnet_analysis.php index d495ba9..f99e013 100644 --- a/scripts/restart_birdnet_analysis.php +++ b/scripts/restart_birdnet_analysis.php @@ -1,4 +1,4 @@ diff --git a/scripts/restart_birdnet_recording.php b/scripts/restart_birdnet_recording.php index b3a5a6e..1712058 100644 --- a/scripts/restart_birdnet_recording.php +++ b/scripts/restart_birdnet_recording.php @@ -1,4 +1,4 @@ diff --git a/scripts/restart_caddy.php b/scripts/restart_caddy.php index 80b539f..fa9f6d2 100644 --- a/scripts/restart_caddy.php +++ b/scripts/restart_caddy.php @@ -1,4 +1,4 @@ diff --git a/scripts/restart_extraction.php b/scripts/restart_extraction.php index 83af548..f52aa58 100644 --- a/scripts/restart_extraction.php +++ b/scripts/restart_extraction.php @@ -1,4 +1,4 @@ diff --git a/scripts/restart_services.php b/scripts/restart_services.php index 2f9caf4..c1e7b55 100644 --- a/scripts/restart_services.php +++ b/scripts/restart_services.php @@ -1,4 +1,4 @@ diff --git a/scripts/restart_services.sh b/scripts/restart_services.sh index f767776..8bd1064 100755 --- a/scripts/restart_services.sh +++ b/scripts/restart_services.sh @@ -1,23 +1,15 @@ #!/usr/bin/env bash # Restarts ALL services and removes ALL unprocessed audio source /etc/birdnet/birdnet.conf +my_dir=/home/pi/BirdNET-Pi/scripts sudo systemctl stop birdnet_recording.service sudo rm -rf ${RECS_DIR}/$(date +%B-%Y/%d-%A)/* sudo systemctl start birdnet_recording.service -SERVICES=(avahi-alias@birdlog.local.service -avahi-alias@birdnetpi.local.service -avahi-alias@birdstats.local.service -avahi-alias@extractionlog.local.service -birdnet_analysis.service -birdnet_log.service -birdstats.service -extraction.timer -extractionlog.service -livestream.service) +services=($(awk '/service/ && /systemctl/ && !/php/ {print $3}' ${my_dir}/install_services.sh | sort)) -for i in "${SERVICES[@]}";do - sudo systemctl restart ${i} +for i in "${services[@]}";do +sudo systemctl restart "${i}" done - +sudo systemctl restart extraction.timer diff --git a/scripts/shutdown_system.php b/scripts/shutdown_system.php index f344edc..74ce980 100644 --- a/scripts/shutdown_system.php +++ b/scripts/shutdown_system.php @@ -1,4 +1,3 @@ diff --git a/scripts/spectrogram.php b/scripts/spectrogram.php index 3aa0629..6b43be7 100644 --- a/scripts/spectrogram.php +++ b/scripts/spectrogram.php @@ -1,4 +1,5 @@ "; +echo ""; ?> diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh index ed8fc6c..9cd8ce5 100755 --- a/scripts/uninstall.sh +++ b/scripts/uninstall.sh @@ -45,30 +45,10 @@ uninstall.sh update_species.sh ${HOME}/.gotty) - -SERVICES=(avahi-alias@birdlog.local.service -avahi-alias@birdnetpi.local.service -avahi-alias@birdstats.local.service -avahi-alias@extractionlog.local.service -avahi-alias@birdterminal.local.service -birdnet_analysis.service -birdnet_log.service -birdnet_recording.d -birdnet_recording.service -birdstats.service -birdterminal.service -caddy.service -edit_birdnet_conf.service -extraction_log.service -extraction.service -extraction.timer -livestream.service -pushed_notifications.service -spectrogram_viewer.service -${SYSTEMD_MOUNT}) +services=$(awk '/service/ && /systemctl/ && !/php/ {print $3}' ${my_dir}/install_services.sh | sort) remove_services() { - for i in "${SERVICES[@]}"; do + for i in "${services[@]}"; do if [ -L /etc/systemd/system/multi-user.target.wants/"${i}" ];then sudo systemctl disable --now "${i}" fi diff --git a/scripts/update_birdnet.php b/scripts/update_birdnet.php index ff20b68..a5d5b44 100644 --- a/scripts/update_birdnet.php +++ b/scripts/update_birdnet.php @@ -1,4 +1,4 @@ /tmp/phpupdate.log 2&>1"); -header('Location: http://birdnetpi.local/index.html?success=true'); +header('Location: http://birdnetpi.local/scripts/update_inprogress.php'); ?> diff --git a/scripts/update_birdnet.sh b/scripts/update_birdnet.sh index aeb041d..e797ac0 100755 --- a/scripts/update_birdnet.sh +++ b/scripts/update_birdnet.sh @@ -8,69 +8,7 @@ HOME=/home/pi my_dir=${HOME}/BirdNET-Pi/scripts tmpfile=$(mktemp) -scripts=(birdnet_analysis.sh -birdnet_recording.sh -birdnet_stats.sh -cleanup.sh -clear_all_data.php -clear_all_data.sh -createdb.sh -disk_usage.sh -dump_logs.sh -edit_birdnet.conf.php -edit_birdnet.conf.sh -extract_new_birdsounds.sh -install_birdnet.sh -install_config.sh -install_services.sh -install_tmux_services.sh -install_zram_service.sh -livestream.sh -pretty_date.sh -reboot_system.php -reboot_system.sh -reconfigure_birdnet.sh -restart_birdnet_analysis.php -restart_birdnet_analysis.sh -restart_birdnet_recording.php -restart_birdnet_recording.sh -restart_caddy.php -restart_caddy.sh -restart_extraction.php -restart_extraction.sh -restart_services.php -restart_services.sh -shutdown_system.php -shutdown_system.sh -species_notifier.sh -spectrogram.php -spectrogram.sh -tmux -uninstall.sh -update_species.sh -${HOME}/.gotty) - - -# Change this to sourcing from current uninstall.sh -# Create a pre-update services array for disabling -# Create a post-update services array for restarting -services=(avahi-alias@birdlog.local.service -avahi-alias@birdnetpi.local.service -avahi-alias@birdstats.local.service -avahi-alias@extractionlog.local.service -avahi-alias@birdterminal.local.service -birdnet_analysis.service -birdnet_log.service -birdnet_recording.service -birdstats.service -birdterminal.service -edit_birdnet_conf.service -extraction_log.service -extraction.service -extraction.timer -livestream.service -pushed_notifications.service -spectrogram_viewer.service) +services=$(awk '/service/ && /systemctl/ && !/php/ {print $3}' ${my_dir}/install_services.sh | sort) remove_services() { for i in "${services[@]}"; do @@ -109,34 +47,13 @@ remove_scripts() { done } -restart_services() { - for i in ${services[@]};do - sudo systemctl restart ${i} - done -} - # Stage 1 removes old stuff remove_services remove_scripts # Stage 2 does a git pull to fetch new things -sudo -u${USER} git -C ${HOME}/BirdNET-Pi pull || exit 1 - -# Stage 3 updates the services -sudo ${my_dir}/update_services.sh - -# Stage 4 restarts the services -services=(avahi-alias@birdnetpi.local.service -birdnet_analysis.service -birdnet_log.service -birdnet_recording.service -edit_birdnet_conf.service -extraction_log.service -extraction.service -extraction.timer -livestream.service -pushed_notifications.service -spectrogram_viewer.service) - -restart_services +sudo -u${USER} git -C ${HOME}/BirdNET-Pi checkout -f || exit 1 +sudo -u${USER} git -C ${HOME}/BirdNET-Pi pull -f || exit 1 +# Trigger the new update_birdnet2.sh +sudo -u${USER} ${my_dir}/update_birdnet2.sh diff --git a/scripts/update_birdnet2.sh b/scripts/update_birdnet2.sh new file mode 100755 index 0000000..a0a5a89 --- /dev/null +++ b/scripts/update_birdnet2.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# Second stage of update +birdnet_conf=/home/pi/BirdNET-Pi/birdnet.conf + +# Stage 1 updates the birdnet.conf +sudo -upi sed -i 's/EXTRACTIONS_URL/BIRDNETPI_URL/g' +if ! grep EXTRACTIONLOG ${birdnet_conf} &> /dev/null;then + echo "EXTRACTIONLOG_URL=" >> ${birdnet_conf} + echo "BIRDNETLOG_URL=" >> ${birdnet_conf} +fi +sudo -upi sed -i 's/=http:\/\/birdnetpi.local/=/g' ${birdnet_conf} + +# Stage 2 updates the services +my_dir=${HOME}/BirdNET-Pi/scripts +sudo ${my_dir}/update_services.sh + +# Stage 2 restarts the services +newservices=$(awk '/service/ && /systemctl/ && !/php/ {print $3}' ${my_dir}/install_services.sh | sort) + +restart_newservices() { + for i in ${newservices[@]};do + sudo systemctl restart ${i} + done +} + +restart_newservices +sudo systemctl restart extraction.timer diff --git a/scripts/update_db_pwd.sh b/scripts/update_db_pwd.sh new file mode 100755 index 0000000..eba6dd0 --- /dev/null +++ b/scripts/update_db_pwd.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# Update database password +source /etc/birdnet/birdnet.conf + +sudo mysql -e " + UPDATE mysql.user + SET Password=PASSWORD('${DB_PWD}') + WHERE USER='birder' + AND Host='localhost'; + FLUSH PRIVILEGES"; +git -C /home/pi/BirdNET-Pi checkout -f analyze.py +git -C /home/pi/BirdNET-Pi checkout -f scripts/viewdb.php +sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/analyze.py +sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/viewdb.php diff --git a/scripts/update_inprogress.php b/scripts/update_inprogress.php new file mode 100644 index 0000000..cd35c9b --- /dev/null +++ b/scripts/update_inprogress.php @@ -0,0 +1,40 @@ + + + + + + + + +
+ + + + diff --git a/scripts/update_services.sh b/scripts/update_services.sh index 97e3b4c..e05c1f8 100755 --- a/scripts/update_services.sh +++ b/scripts/update_services.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# This installs the services that have been selected +# This reinstalls the services #set -x # Uncomment to enable debugging trap 'rm -f ${tmpfile}' EXIT trap 'exit 1' SIGINT SIGHUP @@ -11,6 +11,14 @@ nomachine_url="https://download.nomachine.com/download/7.6/Arm/nomachine_7.6.2_3 gotty_url="https://github.com/yudai/gotty/releases/download/v1.0.1/gotty_linux_arm.tar.gz" config_file="$(dirname ${my_dir})/birdnet.conf" +set_hostname() { + if [ "$(hostname)" != "birdnetpi" ];then + echo "Setting hostname to 'birdnetpi'" + hostnamectl set-hostname birdnetpi + sed -i 's/raspberrypi/birdnetpi/g' /etc/hosts + fi +} + install_scripts() { echo "Installing BirdNET-Pi scripts to /usr/local/bin" ln -sf ${my_dir}/* /usr/local/bin/ @@ -24,6 +32,8 @@ install_mariadb() { apt -qqy install mariadb-server echo "MariaDB Installed" fi + sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/analyze.py + sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/viewdb.php } install_birdnet_analysis() { @@ -88,7 +98,7 @@ ExecStart=/usr/local/bin/species_notifier.sh [Install] WantedBy=multi-user.target EOF - systemctl enable --now pushed_notifications + systemctl enable pushed_notifications.service } create_necessary_dirs() { @@ -98,15 +108,35 @@ create_necessary_dirs() { [ -d ${EXTRACTED}/By_Common_Name ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Common_Name [ -d ${EXTRACTED}/By_Scientific_Name ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Scientific_Name [ -d ${PROCESSED} ] || sudo -u ${USER} mkdir -p ${PROCESSED} - [ -L ${EXTRACTED}/index.html ] || sudo -u ${USER} ln -s $(dirname ${my_dir})/templates/index.html ${EXTRACTED} - [ -L ${EXTRACTED}/scripts ] || sudo -u ${USER} ln -s $(dirname ${my_dir})/scripts ${EXTRACTED} - [ -L ${EXTRACTED}/spectrogram.php ] || sudo -u ${USER} ln -s $(dirname ${my_dir})/scripts/spectrogram.* ${EXTRACTED} - [ -L ${EXTRACTED}/viewdb.php ] || sudo -u ${USER} ln -s $(dirname ${my_dir})/scripts/viewdb.php ${EXTRACTED} - sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED} - [ -L ${EXTRACTED}/phpsysinfo.ini ] || sudo -u ${USER} cp ${HOME}/phpsysinfo/phpsysinfo.ini.new ${HOME}/phpsysinfo/phpsysinfo.ini + sudo -u ${USER} ln -fs $(dirname ${my_dir})/homepage/* ${EXTRACTED} + set -x + if [ ! -z ${BIRDNETLOG_URL} ];then + BIRDNETLOG_URL="$(echo ${BIRDNETLOG_URL} | sed 's/\/\//\\\/\\\//g')" + sudo -u${USER} sed -i "s/http:\/\/birdnetpi.local:8080/"${BIRDNETLOG_URL}"/g" $(dirname ${my_dir})/homepage/*.html + fi + set +x + if [ ! -z ${EXTRACTIONLOG_URL} ];then + EXTRACTIONLOG_URL="$(echo ${EXTRACTIONLOG_URL} | sed 's/\/\//\\\/\\\//g')" + sudo -u${USER} sed -i "s/http:\/\/birdnetpi.local:8888/"${EXTRACTIONLOG_URL}"/g" $(dirname ${my_dir})/homepage/*.html + fi + + sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts ${EXTRACTED} + if [ ! -z ${BIRDNETPI_URL} ];then + BIRDNETPI_URL="$(echo ${BIRDNETPI_URL} | sed 's/\/\//\\\/\\\//g')" + sudo -u${USER} sed -i "s/http:\/\/birdnetpi.local/"${BIRDNETPI_URL}"/g" $(dirname ${my_dir})/homepage/*.html + phpfiles="$(grep -l birdnetpi.local ${my_dir}/*.php)" + for i in "${phpfiles[@]}";do + sudo -u${USER} sed -i "s/http:\/\/birdnetpi.local/"${BIRDNETPI_URL}"/g" ${i} + done + fi + + sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/spectrogram.php ${EXTRACTED} + sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/viewdb.php ${EXTRACTED} + sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED} + [ -L ${EXTRACTED}/phpsysinfo/phpsysinfo.ini ] || sudo -u ${USER} cp ${HOME}/phpsysinfo/phpsysinfo.ini.new ${HOME}/phpsysinfo/phpsysinfo.ini } - + install_alsa() { echo "Checking for alsa-utils and pulseaudio" if which arecord &> /dev/null ;then @@ -170,26 +200,7 @@ install_Caddyfile() { fi HASHWORD=$(caddy hash-password -plaintext ${CADDY_PWD}) cat << EOF > /etc/caddy/Caddyfile -${EXTRACTIONS_URL} { - root * ${EXTRACTED} - file_server browse - basicauth /Processed* { - birdnet ${HASHWORD} - } - basicauth /scripts* { - birdnet ${HASHWORD} - } - basicauth /stream { - birdnet ${HASHWORD} - } - basicauth /phpsysinfo* { - birdnet ${HASHWORD} - } - reverse_proxy /stream localhost:8000 - php_fastcgi unix//run/php/php7.3-fpm.sock -} - -http://birdnetpi.local { +http://localhost http://birdnetpi.local ${BIRDNETPI_URL} { root * ${EXTRACTED} file_server browse basicauth /Processed* { @@ -208,6 +219,22 @@ http://birdnetpi.local { php_fastcgi unix//run/php/php7.3-fpm.sock } EOF + if [ ! -z ${EXTRACTIONLOG_URL} ];then + cat << EOF >> /etc/caddy/Caddyfile + +${EXTRACTIONLOG_URL} { + reverse_proxy localhost:8888 +} +EOF + fi + if [ ! -z ${BIRDNETLOG_URL} ];then + cat << EOF >> /etc/caddy/Caddyfile + +${BIRDNETLOG_URL} { + reverse_proxy localhost:8080 +} +EOF + fi systemctl reload caddy } @@ -232,7 +259,7 @@ ExecStart=/bin/bash -c "/usr/bin/avahi-publish -a -R %I $(avahi-resolve -4 -n %H [Install] WantedBy=multi-user.target EOF - systemctl enable --now avahi-alias@birdnetpi.local.service + systemctl enable avahi-alias@birdnetpi.local.service } install_spectrogram_service() { @@ -248,7 +275,7 @@ ExecStart=/usr/local/bin/spectrogram.sh [Install] WantedBy=multi-user.target EOF - systemctl enable --now spectrogram_viewer.service + systemctl enable spectrogram_viewer.service } install_gotty_logs() { @@ -275,7 +302,7 @@ ExecStart=/usr/local/bin/gotty -p 8080 --title-format "BirdNET-Pi Log" journalct [Install] WantedBy=multi-user.target EOF - systemctl enable --now birdnet_log.service + systemctl enable birdnet_log.service echo "Installing the extraction_log.service" cat << EOF > /etc/systemd/system/extraction_log.service [Unit] @@ -292,7 +319,7 @@ ExecStart=/usr/local/bin/gotty -p 8888 --title-format "Extractions Log" journalc [Install] WantedBy=multi-user.target EOF - systemctl enable --now extraction_log.service + systemctl enable extraction_log.service } install_sox() { @@ -354,12 +381,12 @@ install_icecast() { echo "icecast2 icecast2/icecast-setup boolean false" | debconf-set-selections apt install -qqy icecast2 config_icecast - systemctl enable --now icecast2 + systemctl enable icecast2.service /etc/init.d/icecast2 start else echo "Icecast2 is installed" config_icecast - systemctl enable --now icecast2 + systemctl enable icecast2.service /etc/init.d/icecast2 start fi } @@ -392,7 +419,7 @@ ExecStart=/usr/local/bin/livestream.sh [Install] WantedBy=multi-user.target EOF - systemctl enable --now livestream.service + systemctl enable livestream.service } install_nomachine() { @@ -416,6 +443,7 @@ install_cleanup_cron() { } install_selected_services() { + set_hostname install_scripts install_birdnet_analysis @@ -428,7 +456,6 @@ install_selected_services() { install_recording_service fi - if [ ! -z "${EXTRACTIONS_URL}" ];then install_caddy install_Caddyfile install_avahi_aliases @@ -439,7 +466,6 @@ install_selected_services() { install_spectrogram_service install_edit_birdnet_conf install_pushed_notifications - fi if [ ! -z "${ICE_PWD}" ];then install_icecast diff --git a/scripts/viewdb.php b/scripts/viewdb.php index ac70b0f..4f85d38 100644 --- a/scripts/viewdb.php +++ b/scripts/viewdb.php @@ -1,4 +1,5 @@ connect_error) { } // SQL query to select data from database -$sql = "SELECT * FROM detections - ORDER BY Date DESC, Time DESC"; +$sql = "SELECT * FROM detections + ORDER BY Date DESC, Time DESC"; $fulltable = $mysqli->query($sql); $totalcount=mysqli_num_rows($fulltable); +$sql1 = "SELECT * FROM detections + WHERE Date = CURDATE() + ORDER BY Date DESC, Time DESC"; +$mosttable = $mysqli->query($sql1); + $sql2 = "SELECT * FROM detections WHERE Date = CURDATE()"; $todaystable = $mysqli->query($sql2); @@ -53,7 +59,7 @@ $mysqli->close(); - + BirdNET-Pi DB + -

Number of Detections

@@ -204,11 +212,11 @@ while($rows=$specieslist ->fetch_assoc())
-

Species stats

+

Species Statistics

- + fetch_assoc()) @@ -224,14 +232,13 @@ while($rows=$speciestally ->fetch_assoc())
SpeciesNumber of DetectionsDetections
-

BirdsDB Detections Table

+

Today's Detections

- - - + + @@ -242,13 +249,12 @@ while($rows=$speciestally ->fetch_assoc()) fetch_assoc()) +while($rows=$mosttable ->fetch_assoc()) { ?> - @@ -265,7 +271,6 @@ while($rows=$fulltable ->fetch_assoc()) ?>
Date TimeSci_NameCom_NameScientific NameCommon Name Confidence Lat Lon
- - + diff --git a/templates/Caddyfile_livestream b/templates/Caddyfile_livestream index ad4a10d..53f522b 100644 --- a/templates/Caddyfile_livestream +++ b/templates/Caddyfile_livestream @@ -1,15 +1,4 @@ -${EXTRACTIONS_URL} { - root * ${EXTRACTED} - file_server browse - basicauth ${PROCESSED}* { - birdnet ${HASHWORD} - } - basicauth /stream { - birdnet ${HASHWORD} - } - reverse_proxy /stream localhost:8000 -} -http://birdnetpi.local { +http://birdnetpi.local ${BIRDNETPI_URL} { root * ${EXTRACTED} file_server browse basicauth ${PROCESSED}* { @@ -26,6 +15,3 @@ http://birdlog.local { http://extractionlog.local { reverse_proxy localhost:8888 } -http://birdterminal.local { - reverse_proxy localhost:9111 -} diff --git a/templates/Caddyfile_nostream b/templates/Caddyfile_nostream index eef82f8..f60161f 100644 --- a/templates/Caddyfile_nostream +++ b/templates/Caddyfile_nostream @@ -1,14 +1,4 @@ -${EXTRACTIONS_URL} { - root * ${EXTRACTED} - file_server browse - basicauth ${PROCESSED}* { - birdnet ${HASHWORD} - } - basicauth /stream { - birdnet ${HASHWORD} - } -} -http://birdnetpi.local { +http://birdnetpi.local ${BIRDNETPI_URL} { root * ${EXTRACTED} file_server browse basicauth ${PROCESSED}* { @@ -24,6 +14,3 @@ http://birdlog.local { http://extractionlog.local { reverse_proxy localhost:8888 } -http://birdterminal.local { - reverse_proxy localhost:9111 -} diff --git a/version b/version deleted file mode 100644 index 0c0f9ab..0000000 --- a/version +++ /dev/null @@ -1,2 +0,0 @@ -main - 0.1b -* renamed to BirdNET-Pi diff --git a/version.md b/version.md new file mode 100644 index 0000000..84e5ccd --- /dev/null +++ b/version.md @@ -0,0 +1,5 @@ +# testing - 0.4 +## What's new +- New desktop web interface +- Better support for public installations + - Needs better documentation to explain how to set it up