diff --git a/README.md b/README.md index fec95a3..e4066d8 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ The installer takes care of any and all necessary updates, so you can run that a The installation creates a log in `/home/pi/installation.log` that you can [email me](mailto:mcguirepr89@gmail.com) if you encounter any issues during installation. ## Access -The BirdNET-Pi system can be accessed from any web browser on the same network: +The BirdNET-Pi can be accessed from any web browser on the same network: - http://birdnetpi.local - Default Basic Authentication Username: birdnet - Password is empty by default. Set this in "Tools" > "Settings" > "Advanced Settings" diff --git a/birdnet.conf-defaults b/birdnet.conf-defaults index db40f10..5863aab 100644 --- a/birdnet.conf-defaults +++ b/birdnet.conf-defaults @@ -69,7 +69,7 @@ PUSHED_APP_SECRET= ## it needs to analyze. Be sure this directory is readable and writable for ## the BIRDNET_USER. -RECS_DIR=/home/pi/BirdSongs +RECS_DIR=$HOME/BirdSongs ## REC_CARD is the sound card you would want the birdnet_recording.service to ## use. Leave this as "default" to use PulseAudio (recommended), or use @@ -141,12 +141,7 @@ EXTRACTION_LENGTH= AUDIOFMT=mp3 -## BIRDNET_USER should be the non-root user systemd should use to execute each -## service. - -BIRDNET_USER=pi - ## These are just for debugging LAST_RUN= THIS_RUN= -IDFILE=/home/pi/BirdNET-Pi/IdentifiedSoFar.txt +IDFILE=$HOME/BirdNET-Pi/IdentifiedSoFar.txt diff --git a/homepage/index.php b/homepage/index.php index 98df2b4..f2eacb7 100644 --- a/homepage/index.php +++ b/homepage/index.php @@ -18,10 +18,10 @@ echo " "; } if(isset($_GET['log'])) { - if (file_exists('/home/pi/BirdNET-Pi/thisrun.txt')) { + if (file_exists('./scripts/thisrun.txt')) { header("Location: /log");} } elseif(isset($_GET['spectrogram'])){ header("Location: /spectrogram.php"); diff --git a/homepage/views.php b/homepage/views.php index ca94810..10a356a 100644 --- a/homepage/views.php +++ b/homepage/views.php @@ -45,10 +45,10 @@ if(isset($_POST['view'])){ if($_POST['view'] == "Streamlit"){header('location:/stats');} if($_POST['view'] == "Daily Charts"){include('history.php');} if($_POST['view'] == "Tools"){ - if (file_exists('/home/pi/BirdNET-Pi/thisrun.txt')) { - $config = parse_ini_file('/home/pi/BirdNET-Pi/thisrun.txt'); - } elseif (file_exists('/home/pi/BirdNET-Pi/firstrun.ini')) { - $config = parse_ini_file('/home/pi/BirdNET-Pi/firstrun.ini'); + if (file_exists('./scripts/thisrun.txt')) { + $config = parse_ini_file('./scripts/thisrun.txt'); + } elseif (file_exists('./scripts/firstrun.ini')) { + $config = parse_ini_file('./scripts/firstrun.ini'); } $caddypwd = $config['CADDY_PWD']; if (!isset($_SERVER['PHP_AUTH_USER'])) { @@ -87,64 +87,64 @@ if(isset($_POST['view'])){ if($_POST['view'] == "Advanced"){include('scripts/advanced.php');} if($_POST['view'] == "Included"){ if(isset($_POST['species']) && isset($_POST['add'])){ - $file = '/home/pi/BirdNET-Pi/include_species_list.txt'; + $file = './scripts/include_species_list.txt'; $str = file_get_contents("$file"); $str = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $str); file_put_contents("$file", "$str"); if(isset($_POST['species'])){ foreach ($_POST['species'] as $selectedOption) - file_put_contents("/home/pi/BirdNET-Pi/include_species_list.txt", $selectedOption."\n", FILE_APPEND); + file_put_contents("./scripts/include_species_list.txt", $selectedOption."\n", FILE_APPEND); } } elseif(isset($_POST['species']) && isset($_POST['del'])){ - $file = '/home/pi/BirdNET-Pi/include_species_list.txt'; + $file = './scripts/include_species_list.txt'; $str = file_get_contents("$file"); $str = preg_replace('/^\h*\v+/m', '', $str); file_put_contents("$file", "$str"); foreach($_POST['species'] as $selectedOption) { - $content = file_get_contents("/home/pi/BirdNET-Pi/include_species_list.txt"); + $content = file_get_contents("../BirdNET-Pi/include_species_list.txt"); $newcontent = str_replace($selectedOption, "", "$content"); - file_put_contents("/home/pi/BirdNET-Pi/include_species_list.txt", "$newcontent"); + file_put_contents("./scripts/include_species_list.txt", "$newcontent"); } - $file = '/home/pi/BirdNET-Pi/include_species_list.txt'; + $file = './scripts/include_species_list.txt'; $str = file_get_contents("$file"); $str = preg_replace('/^\h*\v+/m', '', $str); file_put_contents("$file", "$str"); } - include('scripts/include_list.php'); + include('./scripts/include_list.php'); } if($_POST['view'] == "Excluded"){ if(isset($_POST['species']) && isset($_POST['add'])){ - $file = '/home/pi/BirdNET-Pi/exclude_species_list.txt'; + $file = './scripts/exclude_species_list.txt'; $str = file_get_contents("$file"); $str = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $str); file_put_contents("$file", "$str"); foreach ($_POST['species'] as $selectedOption) - file_put_contents("/home/pi/BirdNET-Pi/exclude_species_list.txt", $selectedOption."\n", FILE_APPEND); + file_put_contents("./scripts/exclude_species_list.txt", $selectedOption."\n", FILE_APPEND); } elseif (isset($_POST['species']) && isset($_POST['del'])){ - $file = '/home/pi/BirdNET-Pi/exclude_species_list.txt'; + $file = './scripts/exclude_species_list.txt'; $str = file_get_contents("$file"); $str = preg_replace('/^\h*\v+/m', '', $str); file_put_contents("$file", "$str"); foreach($_POST['species'] as $selectedOption) { - $content = file_get_contents("/home/pi/BirdNET-Pi/exclude_species_list.txt"); + $content = file_get_contents("./scripts/exclude_species_list.txt"); $newcontent = str_replace($selectedOption, "", "$content"); - file_put_contents("/home/pi/BirdNET-Pi/exclude_species_list.txt", "$newcontent"); + file_put_contents("./scripts/exclude_species_list.txt", "$newcontent"); } - $file = '/home/pi/BirdNET-Pi/exclude_species_list.txt'; + $file = './scripts/exclude_species_list.txt'; $str = file_get_contents("$file"); $str = preg_replace('/^\h*\v+/m', '', $str); file_put_contents("$file", "$str"); } - include('scripts/exclude_list.php'); + include('./scripts/exclude_list.php'); } if($_POST['view'] == "File"){ header('Location: scripts/filemanager/filemanager.php'); } if($_POST['view'] == "Webterm"){ - if (file_exists('/home/pi/BirdNET-Pi/thisrun.txt')) { - $config = parse_ini_file('/home/pi/BirdNET-Pi/thisrun.txt'); - } elseif (file_exists('/home/pi/BirdNET-Pi/firstrun.ini')) { - $config = parse_ini_file('/home/pi/BirdNET-Pi/firstrun.ini'); + if (file_exists('./scripts/thisrun.txt')) { + $config = parse_ini_file('./scripts/thisrun.txt'); + } elseif (file_exists('./scripts/firstrun.ini')) { + $config = parse_ini_file('./scripts/firstrun.ini'); } $caddypwd = $config['CADDY_PWD']; if (!isset($_SERVER['PHP_AUTH_USER'])) { diff --git a/newinstaller.sh b/newinstaller.sh index 315159f..64fa222 100644 --- a/newinstaller.sh +++ b/newinstaller.sh @@ -1,16 +1,19 @@ #!/usr/bin/env bash # Simple new installer +HOME=$HOME +USER=$USER + +export HOME=$HOME +export USER=$USER -HOME=/home/pi -USER=pi branch=main if ! which git &> /dev/null;then sudo apt update sudo apt -y install git fi -git clone -b ${branch} https://github.com/mcguirepr89/BirdNET-Pi.git ${HOME}/BirdNET-Pi && +git clone -b $branch https://github.com/mcguirepr89/BirdNET-Pi.git ${HOME}/BirdNET-Pi && -${HOME}/BirdNET-Pi/scripts/install_birdnet.sh +$HOME/BirdNET-Pi/scripts/install_birdnet.sh if [ ${PIPESTATUS[0]} -eq 0 ];then echo "Installation completed successfully" sudo reboot diff --git a/requirements.txt b/requirements.txt index ec07c81..9f651b4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,6 +8,5 @@ pytz tzlocal pandas seaborn -babel streamlit plotly diff --git a/scripts/advanced.php b/scripts/advanced.php index fbe8126..3ee3007 100644 --- a/scripts/advanced.php +++ b/scripts/advanced.php @@ -3,10 +3,10 @@ ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); -if (file_exists('/home/pi/BirdNET-Pi/thisrun.txt')) { - $config = parse_ini_file('/home/pi/BirdNET-Pi/thisrun.txt'); -} elseif (file_exists('/home/pi/BirdNET-Pi/firstrun.ini')) { - $config = parse_ini_file('/home/pi/BirdNET-Pi/firstrun.ini'); +if (file_exists('./scripts/thisrun.txt')) { + $config = parse_ini_file('./scripts/thisrun.txt'); +} elseif (file_exists('firstrun.ini')) { + $config = parse_ini_file('firstrun.ini'); } $caddypwd = $config['CADDY_PWD']; @@ -27,16 +27,16 @@ if (!isset($_SERVER['PHP_AUTH_USER'])) { } if(isset($_POST['submit'])) { - $contents = file_get_contents("/home/pi/BirdNET-Pi/birdnet.conf"); - $contents2 = file_get_contents("/home/pi/BirdNET-Pi/thisrun.txt"); + $contents = file_get_contents('/etc/birdnet/birdnet.conf'); + $contents2 = file_get_contents('./scripts/thisrun.txt'); if(isset($_POST["caddy_pwd"])) { $caddy_pwd = $_POST["caddy_pwd"]; if(strcmp($caddy_pwd,$config['CADDY_PWD']) !== 0) { $contents = preg_replace("/CADDY_PWD=.*/", "CADDY_PWD=$caddy_pwd", $contents); $contents2 = preg_replace("/CADDY_PWD=.*/", "CADDY_PWD=$caddy_pwd", $contents2); - $fh = fopen("/home/pi/BirdNET-Pi/birdnet.conf", "w"); - $fh2 = fopen("/home/pi/BirdNET-Pi/thisrun.txt", "w"); + $fh = fopen('/etc/birdnet/birdnet.conf', "w"); + $fh2 = fopen("./scripts/thisrun.txt", "w"); fwrite($fh, $contents); fwrite($fh2, $contents2); exec('sudo /usr/local/bin/update_caddyfile.sh > /dev/null 2>&1 &'); @@ -56,8 +56,8 @@ if(isset($_POST['submit'])) { if(strcmp($birdnetpi_url,$config['BIRDNETPI_URL']) !== 0) { $contents = preg_replace("/BIRDNETPI_URL=.*/", "BIRDNETPI_URL=$birdnetpi_url", $contents); $contents2 = preg_replace("/BIRDNETPI_URL=.*/", "BIRDNETPI_URL=$birdnetpi_url", $contents2); - $fh = fopen("/home/pi/BirdNET-Pi/birdnet.conf", "w"); - $fh2 = fopen("/home/pi/BirdNET-Pi/thisrun.txt", "w"); + $fh = fopen('/etc/birdnet/birdnet.conf', "w"); + $fh2 = fopen("./scripts/thisrun.txt", "w"); fwrite($fh, $contents); fwrite($fh2, $contents2); exec('sudo /usr/local/bin/update_caddyfile.sh > /dev/null 2>&1 &'); @@ -107,13 +107,15 @@ if(isset($_POST['submit'])) { $contents = preg_replace("/PRIVACY_MODE=.*/", "PRIVACY_MODE=$privacy_mode", $contents); $contents2 = preg_replace("/PRIVACY_MODE=.*/", "PRIVACY_MODE=$privacy_mode", $contents2); if(strcmp($privacy_mode,"on") == 0) { - exec('sudo sed -i \'s/\/usr\/local\/bin\/server.py/\/usr\/local\/bin\/privacy_server.py/g\' /home/pi/BirdNET-Pi/templates/birdnet_server.service'); - exec('sudo systemctl daemon-reload'); - exec('restart_services.sh'); + exec('sudo sed -i \'s/\/usr\/local\/bin\/server.py/\/usr\/local\/bin\/privacy_server.py/g\' ../../BirdNET-Pi/templates/birdnet_server.service'); + exec('sudo systemctl daemon-reload'); + exec('restart_services.sh'); + header('Location: /log'); } elseif(strcmp($privacy_mode,"off") == 0) { - exec('sudo sed -i \'s/\/usr\/local\/bin\/privacy_server.py/\/usr\/local\/bin\/server.py/g\' /home/pi/BirdNET-Pi/templates/birdnet_server.service'); - exec('sudo systemctl daemon-reload'); - exec('restart_services.sh'); + exec('sudo sed -i \'s/\/usr\/local\/bin\/privacy_server.py/\/usr\/local\/bin\/server.py/g\' ../../BirdNET-Pi/templates/birdnet_server.service'); + exec('sudo systemctl daemon-reload'); + exec('restart_services.sh'); + header('Location: /log'); } } } @@ -158,8 +160,8 @@ if(isset($_POST['submit'])) { } } - $fh = fopen("/home/pi/BirdNET-Pi/birdnet.conf", "w"); - $fh2 = fopen("/home/pi/BirdNET-Pi/thisrun.txt", "w"); + $fh = fopen('/etc/birdnet/birdnet.conf', "w"); + $fh2 = fopen("./scripts/thisrun.txt", "w"); fwrite($fh, $contents); fwrite($fh2, $contents2); } @@ -172,10 +174,10 @@ if(isset($_POST['submit'])) {

Advanced Settings

diff --git a/scripts/analyze.py b/scripts/analyze.py index dada0ae..4f36e80 100755 --- a/scripts/analyze.py +++ b/scripts/analyze.py @@ -1,4 +1,3 @@ -#!/home/pi/BirdNET-Pi/birdnet/bin/python3 import argparse import socket diff --git a/scripts/birdnet_analysis.sh b/scripts/birdnet_analysis.sh index acc0a47..f0e1e68 100755 --- a/scripts/birdnet_analysis.sh +++ b/scripts/birdnet_analysis.sh @@ -5,10 +5,10 @@ source /etc/birdnet/birdnet.conf # Document this run's birdnet.conf settings # Make a temporary file to compare the current birdnet.conf with # the birdnet.conf as it was the last time this script was called -my_dir=$(realpath $(dirname $0)) -if [ -z ${THIS_RUN} ];then THIS_RUN=/home/pi/BirdNET-Pi/thisrun.txt;fi +my_dir=$HOME/BirdNET-Pi/scripts +if [ -z ${THIS_RUN} ];then THIS_RUN=$my_dir/thisrun.txt;fi [ -f ${THIS_RUN} ] || touch ${THIS_RUN} && chmod g+w ${THIS_RUN} -if [ -z ${LAST_RUN} ];then LAST_RUN=/home/pi/BirdNET-Pi/lastrun.txt;fi +if [ -z ${LAST_RUN} ];then LAST_RUN=$my_dir/lastrun.txt;fi [ -z ${LATITUDE} ] && echo "LATITUDE not set, exiting 1" && exit 1 [ -z ${LONGITUDE} ] && echo "LONGITUDE not set, exiting 1" && exit 1 make_thisrun() { @@ -27,8 +27,8 @@ if ! diff ${LAST_RUN} ${THIS_RUN};then sudo systemctl start birdnet_recording.service fi -INCLUDE_LIST="/home/pi/BirdNET-Pi/include_species_list.txt" -EXCLUDE_LIST="/home/pi/BirdNET-Pi/exclude_species_list.txt" +INCLUDE_LIST="$HOME/BirdNET-Pi/include_species_list.txt" +EXCLUDE_LIST="$HOME/BirdNET-Pi/exclude_species_list.txt" if [ ! -f ${INCLUDE_LIST} ];then touch ${INCLUDE_LIST} && chmod g+rw ${INCLUDE_LIST} @@ -96,7 +96,7 @@ run_analysis() { fi for i in "${files[@]}";do - echo "${1}/${i}" > /home/pi/BirdNET-Pi/analyzing_now.txt + echo "${1}/${i}" > $HOME/BirdNET-Pi/analyzing_now.txt [ -z ${RECORDING_LENGTH} ] && RECORDING_LENGTH=15 [ ${RECORDING_LENGTH} == "60" ] && RECORDING_LENGTH=01:00 FILE_LENGTH="$(ffmpeg -i ${1}/${i} 2>&1 | awk -F. '/Duration/ {print $1}' | cut -d':' -f3-4)" diff --git a/scripts/birdnetpi_request.php b/scripts/birdnetpi_request.php index acb8769..968c174 100644 --- a/scripts/birdnetpi_request.php +++ b/scripts/birdnetpi_request.php @@ -1,10 +1,10 @@ $value) { diff --git a/scripts/birdweather_request.php b/scripts/birdweather_request.php index 7b99ec2..a8b82ab 100644 --- a/scripts/birdweather_request.php +++ b/scripts/birdweather_request.php @@ -1,10 +1,10 @@ $value) { diff --git a/scripts/clear_all_data.sh b/scripts/clear_all_data.sh index 5647341..d574f5e 100755 --- a/scripts/clear_all_data.sh +++ b/scripts/clear_all_data.sh @@ -3,9 +3,10 @@ # starting all data-collection from scratch. Only run this if you are sure # you are okay will losing all the data that you've collected and processed # so far. +set -x source /etc/birdnet/birdnet.conf -HOME=/home/pi -USER=pi +USER=$(awk -F: '/1000/ {print $1}' /etc/passwd) +HOME=$(awk -F: '/1000/ {print $6}' /etc/passwd) my_dir=${HOME}/BirdNET-Pi/scripts echo "Stopping services" sudo systemctl stop birdnet_recording.service @@ -16,35 +17,38 @@ sudo rm -drf "${RECS_DIR}" sudo rm -f "${IDFILE}" sudo rm -f $(dirname ${my_dir})/BirdDB.txt -echo "Creating necessary directories" -[ -d ${EXTRACTED} ] || mkdir -p ${EXTRACTED} -[ -d ${EXTRACTED}/By_Date ] || mkdir -p ${EXTRACTED}/By_Date -[ -d ${EXTRACTED}/Charts ] || mkdir -p ${EXTRACTED}/Charts -[ -d ${PROCESSED} ] || mkdir -p ${PROCESSED} +echo "Re-creating necessary directories" +[ -d ${EXTRACTED} ] || sudo -u ${USER} mkdir -p ${EXTRACTED} +[ -d ${EXTRACTED}/By_Date ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Date +[ -d ${EXTRACTED}/Charts ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/Charts +[ -d ${PROCESSED} ] || sudo -u ${USER} mkdir -p ${PROCESSED} + +sudo -u ${USER} ln -fs $(dirname $my_dir)/exclude_species_list.txt $my_dir +sudo -u ${USER} ln -fs $(dirname $my_dir)/include_species_list.txt $my_dir +sudo -u ${USER} ln -fs $(dirname $my_dir)/homepage/* ${EXTRACTED} +sudo -u ${USER} ln -fs $(dirname $my_dir)/model/labels.txt ${my_dir} +sudo -u ${USER} ln -fs $my_dir ${EXTRACTED} +sudo -u ${USER} ln -fs $my_dir/play.php ${EXTRACTED} +sudo -u ${USER} ln -fs $my_dir/spectrogram.php ${EXTRACTED} +sudo -u ${USER} ln -fs $my_dir/overview.php ${EXTRACTED} +sudo -u ${USER} ln -fs $my_dir/stats.php ${EXTRACTED} +sudo -u ${USER} ln -fs $my_dir/todays_detections.php ${EXTRACTED} +sudo -u ${USER} ln -fs $my_dir/history.php ${EXTRACTED} +sudo -u ${USER} ln -fs $my_dir/homepage/images/favicon.ico ${EXTRACTED} +sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED} +sudo -u ${USER} ln -fs $(dirname $my_dir)/templates/phpsysinfo.ini ${HOME}/phpsysinfo/ +sudo -u ${USER} ln -fs $(dirname $my_dir)/templates/green_bootstrap.css ${HOME}/phpsysinfo/templates/ +sudo -u ${USER} ln -fs $(dirname $my_dir)/templates/index_bootstrap.html ${HOME}/phpsysinfo/templates/html +chmod -R g+rw $my_dir +chmod -R g+rw ${RECS_DIR} -ln -fs $(dirname ${my_dir})/homepage/* ${EXTRACTED} -ln -fs $(dirname ${my_dir})/model/labels.txt ${my_dir}/ -ln -fs $(dirname ${my_dir})/scripts ${EXTRACTED} -ln -fs $(dirname ${my_dir})/scripts/play.php ${EXTRACTED} -ln -fs $(dirname ${my_dir})/scripts/spectrogram.php ${EXTRACTED} -ln -fs $(dirname ${my_dir})/scripts/overview.php ${EXTRACTED} -ln -fs $(dirname ${my_dir})/scripts/stats.php ${EXTRACTED} -ln -fs $(dirname ${my_dir})/scripts/todays_detections.php ${EXTRACTED} -ln -fs $(dirname ${my_dir})/scripts/history.php ${EXTRACTED} -ln -fs $(dirname ${my_dir})/homepage/images/favicon.ico ${EXTRACTED} -ln -fs ${HOME}/phpsysinfo ${EXTRACTED} -ln -fs $(dirname ${my_dir})/templates/phpsysinfo.ini ${HOME}/phpsysinfo/ -ln -fs $(dirname ${my_dir})/templates/green_bootstrap.css ${HOME}/phpsysinfo/templates/ -ln -fs $(dirname ${my_dir})/templates/index_bootstrap.html ${HOME}/phpsysinfo/templates/html -sudo chmod -R g+rw $(dirname ${my_dir}) -sudo chmod -R g+rw ${EXTRACTED} echo "Dropping and re-creating database" createdb.sh -echo "Generating BirdDB.txt" +echo "Re-generating BirdDB.txt" touch $(dirname ${my_dir})/BirdDB.txt echo "Date;Time;Sci_Name;Com_Name;Confidence;Lat;Lon;Cutoff;Week;Sens;Overlap" > $(dirname ${my_dir})/BirdDB.txt ln -sf $(dirname ${my_dir})/BirdDB.txt ${my_dir}/BirdDB.txt -chown pi:pi ${my_dir}/BirdDB.txt && chmod g+rw ${my_dir}/BirdDB.txt +chown $USER:$USER ${my_dir}/BirdDB.txt && chmod g+rw ${my_dir}/BirdDB.txt echo "Restarting services" restart_services.sh diff --git a/scripts/config.php b/scripts/config.php index 4c07b90..817f949 100644 --- a/scripts/config.php +++ b/scripts/config.php @@ -10,29 +10,33 @@ $birdweather_id = $_POST["birdweather_id"]; $pushed_app_key = $_POST["pushed_app_key"]; $pushed_app_secret = $_POST["pushed_app_secret"]; -$contents = file_get_contents("/home/pi/BirdNET-Pi/birdnet.conf"); +$contents = file_get_contents("/etc/birdnet/birdnet.conf"); $contents = preg_replace("/LATITUDE=.*/", "LATITUDE=$latitude", $contents); $contents = preg_replace("/LONGITUDE=.*/", "LONGITUDE=$longitude", $contents); $contents = preg_replace("/BIRDWEATHER_ID=.*/", "BIRDWEATHER_ID=$birdweather_id", $contents); $contents = preg_replace("/PUSHED_APP_KEY=.*/", "PUSHED_APP_KEY=$pushed_app_key", $contents); $contents = preg_replace("/PUSHED_APP_SECRET=.*/", "PUSHED_APP_SECRET=$pushed_app_secret", $contents); -$contents2 = file_get_contents("/home/pi/BirdNET-Pi/thisrun.txt"); +$contents2 = file_get_contents("./scripts/thisrun.txt"); $contents2 = preg_replace("/LATITUDE=.*/", "LATITUDE=$latitude", $contents2); $contents2 = preg_replace("/LONGITUDE=.*/", "LONGITUDE=$longitude", $contents2); $contents2 = preg_replace("/BIRDWEATHER_ID=.*/", "BIRDWEATHER_ID=$birdweather_id", $contents2); $contents2 = preg_replace("/PUSHED_APP_KEY=.*/", "PUSHED_APP_KEY=$pushed_app_key", $contents2); $contents2 = preg_replace("/PUSHED_APP_SECRET=.*/", "PUSHED_APP_SECRET=$pushed_app_secret", $contents2); -$fh = fopen("/home/pi/BirdNET-Pi/birdnet.conf", "w"); -$fh2 = fopen("/home/pi/BirdNET-Pi/thisrun.txt", "w"); +$fh = fopen("/etc/birdnet/birdnet.conf", "w"); +$fh2 = fopen("./scripts/thisrun.txt", "w"); fwrite($fh, $contents); fwrite($fh2, $contents2); $language = $_POST["language"]; if ($language != "none"){ - $command = "sudo -upi mv /home/pi/BirdNET-Pi/model/labels.txt /home/pi/BirdNET-Pi/model/labels.txt.old && sudo -upi unzip /home/pi/BirdNET-Pi/model/labels_l18n.zip $language -d /home/pi/BirdNET-Pi/model && sudo -upi mv /home/pi/BirdNET-Pi/model/$language /home/pi/BirdNET-Pi/model/labels.txt"; - $command_output = `$command`; + $user = shell_exec("awk -F: '/1000/{print $1}' /etc/passwd"); + $home = shell_exec("awk -F: '/1000/{print $6}' /etc/passwd"); + $home = trim($home); + $command = "sudo -u".$user." mv ".$home."/BirdNET-Pi/model/labels.txt ".$home."/BirdNET-Pi/model/labels.txt.old && sudo -u".$user." unzip ".$home."/BirdNET-Pi/model/labels_l18n.zip ".$language." -d ".$home."/BirdNET-Pi/model && sudo -u".$user." mv ".$home."/BirdNET-Pi/model/".$language." ".$home."/BirdNET-Pi/model/labels.txt"; + $command_output = `sudo $command`; + `sudo restart_services.sh`; } } @@ -46,10 +50,10 @@ if ($language != "none"){

Basic Settings

Set your Latitude and Longitude to 4 decimal places. Get your coordinates here.


-

BirdWeather.com is a weather map for bird sounds. Stations around the world supply audio and video streams to BirdWeather where they are then analyzed by BirdNET and compared to eBird Grid data. BirdWeather catalogues the bird audio and spectrogram visualizations so that you can listen to, view, and read about birds throughout the world. Email Tim to request a BirdWeather ID

+

BirdWeather.com is a weather map for bird sounds. Stations around the world supply audio and video streams to BirdWeather where they are then analyzed by BirdNET and compared to eBird Grid data. BirdWeather catalogues the bird audio and spectrogram visualizations so that you can listen to, view, and read about birds throughout the world. Email Tim to request a BirdWeather ID


diff --git a/scripts/createdb.sh b/scripts/createdb.sh index 72f1dce..920fe23 100755 --- a/scripts/createdb.sh +++ b/scripts/createdb.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source /etc/birdnet/birdnet.conf -sqlite3 /home/pi/BirdNET-Pi/scripts/birds.db << EOF +sqlite3 $HOME/BirdNET-Pi/scripts/birds.db << EOF DROP TABLE IF EXISTS detections; CREATE TABLE IF NOT EXISTS detections ( Date DATE, @@ -16,5 +16,5 @@ CREATE TABLE IF NOT EXISTS detections ( Overlap FLOAT, File_Name VARCHAR(100) NOT NULL); EOF -sudo chown pi:pi /home/pi/BirdNET-Pi/scripts/birds.db -sudo chmod g+w /home/pi/BirdNET-Pi/scripts/birds.db +chown $USER:$USER $HOME/BirdNET-Pi/scripts/birds.db +chmod g+w $HOME/BirdNET-Pi/scripts/birds.db diff --git a/scripts/daily_plot.py b/scripts/daily_plot.py index 750fe73..6762393 100755 --- a/scripts/daily_plot.py +++ b/scripts/daily_plot.py @@ -1,5 +1,3 @@ -#!/home/pi/BirdNET-Pi/birdnet/bin/python3 - import sqlite3 import os import configparser @@ -10,7 +8,8 @@ from matplotlib.colors import LogNorm from datetime import datetime import textwrap -conn = sqlite3.connect('/home/pi/BirdNET-Pi/scripts/birds.db') +userDir = os.path.expanduser('~') +conn = sqlite3.connect(userDir + '/BirdNET-Pi/scripts/birds.db') df = pd.read_sql_query("SELECT * from detections", conn) cursor = conn.cursor() cursor.execute('SELECT * FROM detections') @@ -99,7 +98,8 @@ f.subplots_adjust(top=0.9) plt.suptitle("Top 10 Last Updated: "+ str(now.strftime("%Y-%m-%d %H:%M"))) #Save combined plot -savename='/home/pi/BirdSongs/Extracted/Charts/Combo-'+str(now.strftime("%Y-%m-%d"))+'.png' +userDir = os.path.expanduser('~') +savename=userDir + '/BirdSongs/Extracted/Charts/Combo-'+str(now.strftime("%Y-%m-%d"))+'.png' plt.savefig(savename) plt.show() plt.close() @@ -167,7 +167,7 @@ f.subplots_adjust(top=0.9) plt.suptitle("Bottom 10 Last Updated: "+ str(now.strftime("%Y-%m-%d %H:%M"))) #Save combined plot -savename='/home/pi/BirdSongs/Extracted/Charts/Combo2-'+str(now.strftime("%Y-%m-%d"))+'.png' +savename=userDir + '/BirdSongs/Extracted/Charts/Combo2-'+str(now.strftime("%Y-%m-%d"))+'.png' plt.savefig(savename) plt.show() plt.close() diff --git a/scripts/dump_logs.sh b/scripts/dump_logs.sh index f4ca828..170afdc 100755 --- a/scripts/dump_logs.sh +++ b/scripts/dump_logs.sh @@ -3,7 +3,7 @@ # set -x # Uncomment to debug source /etc/birdnet/birdnet.conf &> /dev/null LOG_DIR="${HOME}/BirdNET-Pi/logs" -my_dir=/home/pi/BirdNET-Pi/scripts +my_dir=$HOME/BirdNET-Pi/scripts services=$(awk '/service/ && /systemctl/ && !/php/ {print $3}' ${my_dir}/install_services.sh | sort) # Create logs directory diff --git a/scripts/exclude_list.php b/scripts/exclude_list.php index f49e27c..5e5770e 100644 --- a/scripts/exclude_list.php +++ b/scripts/exclude_list.php @@ -12,7 +12,7 @@ error_reporting(E_ALL); ini_set('display_errors',1); - $filename = 'scripts/labels.txt'; + $filename = './scripts/labels.txt'; $eachline = file($filename, FILE_IGNORE_NEW_LINES); foreach($eachline as $lines){echo @@ -39,7 +39,7 @@

Excluded Species List

$lines";} diff --git a/scripts/install_birdnet.sh b/scripts/install_birdnet.sh index f5d1f15..daeb65d 100755 --- a/scripts/install_birdnet.sh +++ b/scripts/install_birdnet.sh @@ -1,11 +1,13 @@ #!/usr/bin/env bash # Install BirdNET script -set -x -exec > >(tee -i installation-$(date +%F).txt) 2>&1 +set -x # Debugging +exec > >(tee -i installation-$(date +%F).txt) 2>&1 # Make log set -e # exit installation if anything fails -my_dir=$(realpath $(dirname $0)) -trap '${my_dir}/dump_logs.sh && echo -e "\n\nExiting the installation. Goodbye!" && exit 1' SIGINT -cd $my_dir || exit 1 + +my_dir=$HOME/BirdNET-Pi +export my_dir=$my_dir + +cd $my_dir/scripts || exit 1 if [ "$(uname -m)" != "aarch64" ];then echo "BirdNET-Pi requires a 64-bit OS. @@ -18,7 +20,7 @@ fi #Install/Configure /etc/birdnet/birdnet.conf ./install_config.sh || exit 1 -sudo ./install_services.sh || exit 1 +sudo -E HOME=$HOME USER=$USER ./install_services.sh || exit 1 source /etc/birdnet/birdnet.conf install_birdnet() { @@ -26,7 +28,9 @@ install_birdnet() { echo "Establishing a python virtual environment" python3 -m venv birdnet source ./birdnet/bin/activate - pip3 install -U -r /home/pi/BirdNET-Pi/requirements.txt + pip3 install -U -r $HOME/BirdNET-Pi/requirements.txt + echo "Ensure all python scripts use the virtual environment" + sed -si "1 i\\#\!$HOME/BirdNET-Pi/birdnet/bin/python3" $my_dir/scripts/*.py } [ -d ${RECS_DIR} ] || mkdir -p ${RECS_DIR} &> /dev/null diff --git a/scripts/install_config.sh b/scripts/install_config.sh index 1ba34d6..cbd29f1 100755 --- a/scripts/install_config.sh +++ b/scripts/install_config.sh @@ -1,15 +1,14 @@ #!/usr/bin/env bash # Creates and installs the /etc/birdnet/birdnet.conf file -#set -x # Uncomment to enable debugging +set -x # Uncomment to enable debugging set -e trap 'exit 1' SIGINT SIGHUP -my_dir=$(realpath $(dirname $0)) -birdnetpi_dir=$(realpath $(dirname $my_dir)) -birdnet_conf="$(dirname ${my_dir})/birdnet.conf" +echo "Beginning $0" +birdnet_conf=$my_dir/birdnet.conf install_config() { - cat << EOF > $(dirname ${my_dir})/birdnet.conf + cat << EOF > $birdnet_conf ################################################################################ # Configuration settings for BirdNET-Pi # ################################################################################ @@ -83,7 +82,7 @@ PUSHED_APP_SECRET= ## it needs to analyze. Be sure this directory is readable and writable for ## the BIRDNET_USER. -RECS_DIR=/home/pi/BirdSongs +RECS_DIR=$HOME/BirdSongs ## REC_CARD is the sound card you would want the birdnet_recording.service to ## use. Leave this as "default" to use PulseAudio (recommended), or use @@ -95,11 +94,11 @@ REC_CARD=default ## after extractions have been made from them. This includes both WAVE and ## BirdNET.selection.txt files. -PROCESSED=/home/pi/BirdSongs/Processed +PROCESSED=$HOME/BirdSongs/Processed ## EXTRACTED is the directory where the extracted audio selections are moved. -EXTRACTED=/home/pi/BirdSongs/Extracted +EXTRACTED=$HOME/BirdSongs/Extracted ## OVERLAP is the value in seconds which BirdNET should use when analyzing ## the data. The values must be between 0.0-2.9. @@ -155,15 +154,11 @@ EXTRACTION_LENGTH= AUDIOFMT=mp3 -## BIRDNET_USER should be the non-root user systemd should use to execute each -## service. - -BIRDNET_USER=pi ## These are just for debugging LAST_RUN= THIS_RUN= -IDFILE=/home/pi/BirdNET-Pi/IdentifiedSoFar.txt +IDFILE=$HOME/BirdNET-Pi/IdentifiedSoFar.txt EOF } @@ -173,5 +168,5 @@ if ! [ -f ${birdnet_conf} ];then fi chmod g+w ${birdnet_conf} [ -d /etc/birdnet ] || sudo mkdir /etc/birdnet -sudo ln -sf $(dirname ${my_dir})/birdnet.conf /etc/birdnet/birdnet.conf -grep -ve '^#' -e '^$' /etc/birdnet/birdnet.conf > ${birdnetpi_dir}/firstrun.ini +sudo ln -sf $birdnet_conf /etc/birdnet/birdnet.conf +grep -ve '^#' -e '^$' /etc/birdnet/birdnet.conf > $my_dir/firstrun.ini diff --git a/scripts/install_services.sh b/scripts/install_services.sh index a30ef58..8ef7cff 100755 --- a/scripts/install_services.sh +++ b/scripts/install_services.sh @@ -3,11 +3,11 @@ set -x # Uncomment to enable debugging trap 'rm -f ${tmpfile}' EXIT trap 'exit 1' SIGINT SIGHUP -USER=pi -HOME=/home/pi -my_dir=${HOME}/BirdNET-Pi/scripts tmpfile=$(mktemp) -config_file="$(dirname ${my_dir})/birdnet.conf" + +config_file=$my_dir/birdnet.conf +export USER=$USER +export HOME=$HOME install_depends() { curl -1sLf \ @@ -34,11 +34,11 @@ update_etc_hosts() { } install_scripts() { - ln -sf ${my_dir}/* /usr/local/bin/ + ln -sf ${my_dir}/scripts/* /usr/local/bin/ } install_birdnet_analysis() { - cat << EOF > /home/pi/BirdNET-Pi/templates/birdnet_analysis.service + cat << EOF > $HOME/BirdNET-Pi/templates/birdnet_analysis.service [Unit] Description=BirdNET Analysis After=birdnet_server.service @@ -52,12 +52,12 @@ ExecStart=/usr/local/bin/birdnet_analysis.sh [Install] WantedBy=multi-user.target EOF - ln -sf /home/pi/BirdNET-Pi/templates/birdnet_analysis.service /usr/lib/systemd/system + ln -sf $HOME/BirdNET-Pi/templates/birdnet_analysis.service /usr/lib/systemd/system systemctl enable birdnet_analysis.service } install_birdnet_server() { - cat << EOF > /home/pi/BirdNET-Pi/templates/birdnet_server.service + cat << EOF > $HOME/BirdNET-Pi/templates/birdnet_server.service [Unit] Description=BirdNET Analysis Server Before=birdnet_analysis.service @@ -70,12 +70,12 @@ ExecStart=/usr/local/bin/server.py [Install] WantedBy=multi-user.target EOF - ln -sf /home/pi/BirdNET-Pi/templates/birdnet_server.service /usr/lib/systemd/system + ln -sf $HOME/BirdNET-Pi/templates/birdnet_server.service /usr/lib/systemd/system systemctl enable birdnet_server.service } install_extraction_service() { - cat << EOF > /home/pi/BirdNET-Pi/templates/extraction.service + cat << EOF > $HOME/BirdNET-Pi/templates/extraction.service [Unit] Description=BirdNET BirdSound Extraction [Service] @@ -87,24 +87,24 @@ ExecStart=/usr/bin/env bash -c 'while true;do extract_new_birdsounds.sh;sleep 3; [Install] WantedBy=multi-user.target EOF - ln -sf /home/pi/BirdNET-Pi/templates/extraction.service /usr/lib/systemd/system + ln -sf $HOME/BirdNET-Pi/templates/extraction.service /usr/lib/systemd/system systemctl enable extraction.service } install_pushed_notifications() { - cat << EOF > /home/pi/BirdNET-Pi/templates/pushed_notifications.service + cat << EOF > $HOME/BirdNET-Pi/templates/pushed_notifications.service [Unit] Description=BirdNET-Pi Pushed.co Notifications [Service] Restart=on-success RestartSec=3 Type=simple -User=pi +User=$USER ExecStart=/usr/local/bin/species_notifier.sh [Install] WantedBy=multi-user.target EOF - ln -sf /home/pi/BirdNET-Pi/templates/pushed_notifications.service /usr/lib/systemd/system + ln -sf $HOME/BirdNET-Pi/templates/pushed_notifications.service /usr/lib/systemd/system systemctl enable pushed_notifications.service } @@ -115,34 +115,36 @@ create_necessary_dirs() { [ -d ${EXTRACTED}/Charts ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/Charts [ -d ${PROCESSED} ] || sudo -u ${USER} mkdir -p ${PROCESSED} - sudo -u ${USER} ln -fs $(dirname ${my_dir})/homepage/* ${EXTRACTED} - sudo -u ${USER} ln -fs $(dirname ${my_dir})/model/labels.txt ${my_dir} - sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts ${EXTRACTED} - sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/play.php ${EXTRACTED} - sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/spectrogram.php ${EXTRACTED} - sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/overview.php ${EXTRACTED} - sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/stats.php ${EXTRACTED} - sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/todays_detections.php ${EXTRACTED} - sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/history.php ${EXTRACTED} - sudo -u ${USER} ln -fs $(dirname ${my_dir})/homepage/images/favicon.ico ${EXTRACTED} + sudo -u ${USER} ln -fs $my_dir/exclude_species_list.txt $my_dir/scripts + sudo -u ${USER} ln -fs $my_dir/include_species_list.txt $my_dir/scripts + sudo -u ${USER} ln -fs $my_dir/homepage/* ${EXTRACTED} + sudo -u ${USER} ln -fs $my_dir/model/labels.txt ${my_dir}/scripts + sudo -u ${USER} ln -fs $my_dir/scripts ${EXTRACTED} + sudo -u ${USER} ln -fs $my_dir/scripts/play.php ${EXTRACTED} + sudo -u ${USER} ln -fs $my_dir/scripts/spectrogram.php ${EXTRACTED} + sudo -u ${USER} ln -fs $my_dir/scripts/overview.php ${EXTRACTED} + sudo -u ${USER} ln -fs $my_dir/scripts/stats.php ${EXTRACTED} + sudo -u ${USER} ln -fs $my_dir/scripts/todays_detections.php ${EXTRACTED} + sudo -u ${USER} ln -fs $my_dir/scripts/history.php ${EXTRACTED} + sudo -u ${USER} ln -fs $my_dir/homepage/images/favicon.ico ${EXTRACTED} sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED} - sudo -u ${USER} ln -fs $(dirname ${my_dir})/templates/phpsysinfo.ini ${HOME}/phpsysinfo/ - sudo -u ${USER} ln -fs $(dirname ${my_dir})/templates/green_bootstrap.css ${HOME}/phpsysinfo/templates/ - sudo -u ${USER} ln -fs $(dirname ${my_dir})/templates/index_bootstrap.html ${HOME}/phpsysinfo/templates/html - chmod -R g+rw $(dirname ${my_dir}) + sudo -u ${USER} ln -fs $my_dir/templates/phpsysinfo.ini ${HOME}/phpsysinfo/ + sudo -u ${USER} ln -fs $my_dir/templates/green_bootstrap.css ${HOME}/phpsysinfo/templates/ + sudo -u ${USER} ln -fs $my_dir/templates/index_bootstrap.html ${HOME}/phpsysinfo/templates/html + chmod -R g+rw $my_dir chmod -R g+rw ${RECS_DIR} } generate_BirdDB() { echo "Generating BirdDB.txt" - if ! [ -f $(dirname ${my_dir})/BirdDB.txt ];then - sudo -u ${USER} touch $(dirname ${my_dir})/BirdDB.txt - echo "Date;Time;Sci_Name;Com_Name;Confidence;Lat;Lon;Cutoff;Week;Sens;Overlap" | sudo -u ${USER} tee -a $(dirname ${my_dir})/BirdDB.txt - elif ! grep Date $(dirname ${my_dir})/BirdDB.txt;then - sudo -u ${USER} sed -i '1 i\Date;Time;Sci_Name;Com_Name;Confidence;Lat;Lon;Cutoff;Week;Sens;Overlap' $(dirname ${my_dir})/BirdDB.txt + if ! [ -f $my_dir/BirdDB.txt ];then + sudo -u ${USER} touch $my_dir/BirdDB.txt + echo "Date;Time;Sci_Name;Com_Name;Confidence;Lat;Lon;Cutoff;Week;Sens;Overlap" | sudo -u ${USER} tee -a $my_dir/BirdDB.txt + elif ! grep Date $my_dir/BirdDB.txt;then + sudo -u ${USER} sed -i '1 i\Date;Time;Sci_Name;Com_Name;Confidence;Lat;Lon;Cutoff;Week;Sens;Overlap' $my_dir/BirdDB.txt fi - ln -sf $(dirname ${my_dir})/BirdDB.txt ${my_dir}/BirdDB.txt && - chown pi:pi ${my_dir}/BirdDB.txt && chmod g+rw ${my_dir}/BirdDB.txt + ln -sf $my_dir/BirdDB.txt ${my_dir}/BirdDB.txt && + chown $USER:$USER ${my_dir}/BirdDB.txt && chmod g+rw ${my_dir}/BirdDB.txt } set_login() { @@ -159,7 +161,7 @@ EOF install_recording_service() { echo "Installing birdnet_recording.service" - cat << EOF > /home/pi/BirdNET-Pi/templates/birdnet_recording.service + cat << EOF > $HOME/BirdNET-Pi/templates/birdnet_recording.service [Unit] Description=BirdNET Recording [Service] @@ -172,13 +174,13 @@ ExecStart=/usr/local/bin/birdnet_recording.sh [Install] WantedBy=multi-user.target EOF - ln -sf /home/pi/BirdNET-Pi/templates/birdnet_recording.service /usr/lib/systemd/system + ln -sf $HOME/BirdNET-Pi/templates/birdnet_recording.service /usr/lib/systemd/system systemctl enable birdnet_recording.service } install_custom_recording_service() { echo "Installing custom_recording.service" - cat << EOF > /home/pi/BirdNET-Pi/templates/custom_recording.service + cat << EOF > $HOME/BirdNET-Pi/templates/custom_recording.service [Unit] Description=BirdNET Custom Recording [Service] @@ -191,7 +193,7 @@ ExecStart=/usr/local/bin/custom_recording.sh [Install] WantedBy=multi-user.target EOF - ln -sf /home/pi/BirdNET-Pi/templates/custom_recording.service /usr/lib/systemd/system + ln -sf $HOME/BirdNET-Pi/templates/custom_recording.service /usr/lib/systemd/system } install_Caddyfile() { @@ -254,11 +256,12 @@ EOF fi systemctl enable caddy - usermod -aG pi caddy + usermod -aG $USER caddy + usermod -aG video caddy } install_avahi_aliases() { - cat << 'EOF' > /home/pi/BirdNET-Pi/templates/avahi-alias@.service + cat << 'EOF' > $HOME/BirdNET-Pi/templates/avahi-alias@.service [Unit] Description=Publish %I as alias for %H.local via mdns After=network.target network-online.target @@ -271,12 +274,12 @@ ExecStart=/bin/bash -c "/usr/bin/avahi-publish -a -R %I $(hostname -I |cut -d' ' [Install] WantedBy=multi-user.target EOF - ln -sf /home/pi/BirdNET-Pi/templates/avahi-alias@.service /usr/lib/systemd/system + ln -sf $HOME/BirdNET-Pi/templates/avahi-alias@.service /usr/lib/systemd/system systemctl enable avahi-alias@"$(hostname)".local.service } install_birdnet_stats_service() { - cat << EOF > /home/pi/BirdNET-Pi/templates/birdnet_stats.service + cat << EOF > $HOME/BirdNET-Pi/templates/birdnet_stats.service [Unit] Description=BirdNET Stats [Service] @@ -284,17 +287,17 @@ Restart=on-failure RestartSec=5 Type=simple User=${USER} -ExecStart=/home/pi/BirdNET-Pi/birdnet/bin/streamlit run /home/pi/BirdNET-Pi/scripts/plotly_streamlit.py --server.address localhost --server.baseUrlPath "/stats" +ExecStart=$HOME/BirdNET-Pi/birdnet/bin/streamlit run $HOME/BirdNET-Pi/scripts/plotly_streamlit.py --server.address localhost --server.baseUrlPath "/stats" [Install] WantedBy=multi-user.target EOF - ln -sf /home/pi/BirdNET-Pi/templates/birdnet_stats.service /usr/lib/systemd/system + ln -sf $HOME/BirdNET-Pi/templates/birdnet_stats.service /usr/lib/systemd/system systemctl enable birdnet_stats.service } install_spectrogram_service() { - cat << EOF > /home/pi/BirdNET-Pi/templates/spectrogram_viewer.service + cat << EOF > $HOME/BirdNET-Pi/templates/spectrogram_viewer.service [Unit] Description=BirdNET-Pi Spectrogram Viewer [Service] @@ -306,34 +309,34 @@ ExecStart=/usr/local/bin/spectrogram.sh [Install] WantedBy=multi-user.target EOF - ln -sf /home/pi/BirdNET-Pi/templates/spectrogram_viewer.service /usr/lib/systemd/system + ln -sf $HOME/BirdNET-Pi/templates/spectrogram_viewer.service /usr/lib/systemd/system systemctl enable spectrogram_viewer.service } install_chart_viewer_service() { echo "Installing the chart_viewer.service" - cat << EOF > /home/pi/BirdNET-Pi/templates/chart_viewer.service + cat << EOF > $HOME/BirdNET-Pi/templates/chart_viewer.service [Unit] Description=BirdNET-Pi Chart Viewer Service [Service] Restart=always RestartSec=300 Type=simple -User=pi +User=$USER ExecStart=/usr/local/bin/daily_plot.py [Install] WantedBy=multi-user.target EOF - ln -sf /home/pi/BirdNET-Pi/templates/chart_viewer.service /usr/lib/systemd/system + ln -sf $HOME/BirdNET-Pi/templates/chart_viewer.service /usr/lib/systemd/system systemctl enable chart_viewer.service } install_gotty_logs() { - sudo -u ${USER} ln -sf $(dirname ${my_dir})/templates/gotty \ + sudo -u ${USER} ln -sf $my_dir/templates/gotty \ ${HOME}/.gotty - sudo -u ${USER} ln -sf $(dirname ${my_dir})/templates/bashrc \ + sudo -u ${USER} ln -sf $my_dir/templates/bashrc \ ${HOME}/.bashrc - cat << EOF > /home/pi/BirdNET-Pi/templates/birdnet_log.service + cat << EOF > $HOME/BirdNET-Pi/templates/birdnet_log.service [Unit] Description=BirdNET Analysis Log [Service] @@ -346,9 +349,9 @@ ExecStart=/usr/local/bin/gotty --address localhost -p 8080 -P log --title-format [Install] WantedBy=multi-user.target EOF - ln -sf /home/pi/BirdNET-Pi/templates/birdnet_log.service /usr/lib/systemd/system + ln -sf $HOME/BirdNET-Pi/templates/birdnet_log.service /usr/lib/systemd/system systemctl enable birdnet_log.service - cat << EOF > /home/pi/BirdNET-Pi/templates/web_terminal.service + cat << EOF > $HOME/BirdNET-Pi/templates/web_terminal.service [Unit] Description=BirdNET-Pi Web Terminal [Service] @@ -361,7 +364,7 @@ ExecStart=/usr/local/bin/gotty --address localhost -w -p 8888 -P terminal --titl [Install] WantedBy=multi-user.target EOF - ln -sf /home/pi/BirdNET-Pi/templates/web_terminal.service /usr/lib/systemd/system + ln -sf $HOME/BirdNET-Pi/templates/web_terminal.service /usr/lib/systemd/system systemctl enable web_terminal.service } @@ -394,7 +397,7 @@ config_icecast() { } install_livestream_service() { - cat << EOF > /home/pi/BirdNET-Pi/templates/livestream.service + cat << EOF > $HOME/BirdNET-Pi/templates/livestream.service [Unit] Description=BirdNET-Pi Live Stream After=network-online.target @@ -409,12 +412,12 @@ ExecStart=/usr/local/bin/livestream.sh [Install] WantedBy=multi-user.target EOF - ln -sf /home/pi/BirdNET-Pi/templates/livestream.service /usr/lib/systemd/system + ln -sf $HOME/BirdNET-Pi/templates/livestream.service /usr/lib/systemd/system systemctl enable livestream.service } install_cleanup_cron() { - cat $(dirname ${my_dir})/templates/cleanup.cron >> /etc/crontab + sed "s/\$USER/$USER/g" $my_dir/templates/cleanup.cron >> /etc/crontab } install_services() { @@ -444,7 +447,7 @@ install_services() { generate_BirdDB configure_caddy_php config_icecast - ${my_dir}/createdb.sh + USER=$USER HOME=$HOME ${my_dir}/scripts/createdb.sh } if [ -f ${config_file} ];then diff --git a/scripts/overview.php b/scripts/overview.php index 9595a3f..49657af 100644 --- a/scripts/overview.php +++ b/scripts/overview.php @@ -1,12 +1,9 @@
"; } else { echo "

No Detections For Today

"; diff --git a/scripts/play.php b/scripts/play.php index a007341..8efb947 100644 --- a/scripts/play.php +++ b/scripts/play.php @@ -3,7 +3,7 @@ ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); -$db = new SQLite3('/home/pi/BirdNET-Pi/scripts/birds.db', SQLITE3_OPEN_CREATE | SQLITE3_OPEN_READWRITE); +$db = new SQLite3('./scripts/birds.db', SQLITE3_OPEN_CREATE | SQLITE3_OPEN_READWRITE); if($db == False){ echo "Database is busy"; header("refresh: 0;"); diff --git a/scripts/plotly_streamlit.py b/scripts/plotly_streamlit.py index 507d872..b42906d 100755 --- a/scripts/plotly_streamlit.py +++ b/scripts/plotly_streamlit.py @@ -1,4 +1,4 @@ -#!/home/pi/BirdNET-Pi/birdnet/bin/python3 +import os import streamlit as st import pandas as pd import numpy as np @@ -9,7 +9,8 @@ from pathlib import Path import sqlite3 from sqlite3 import Connection -URI_SQLITE_DB = "/home/pi/BirdNET-Pi/scripts/birds.db" +userDir = os.path.expanduser('~') +URI_SQLITE_DB = userDir + '/BirdNET-Pi/scripts/birds.db' st.set_page_config(layout='wide') @@ -31,24 +32,12 @@ st.markdown(""" """, unsafe_allow_html=True) -col1,col2,col3 = st.columns([20,20,20]) - -col1.title('BirdNET-Pi', anchor=None) -col2.image('/home/pi/BirdNET-Pi/homepage/images/bird.png') -col3.text('') - @st.cache(hash_funcs={Connection: id}) def get_connection(path:str): return sqlite3.connect(path,check_same_thread=False) - - -# def load_data(): -# df1 = pd.read_csv('/home/pi/BirdNET-Pi/BirdDB.txt', sep=';') -# return df1 - def get_data(conn: Connection): df1=pd.read_sql("SELECT * FROM detections", con=conn) return df1 @@ -179,6 +168,6 @@ st.plotly_chart(fig, use_container_width=True) #, config=config) # # extract_date=Date_Slider # -# audio_file = open('/home/pi/BirdSongs/Extracted/By_Date/2022-03-22/Yellow-streaked_Greenbul/Yellow-streaked_Greenbul-77-2022-03-22-birdnet-15:04:28.mp3', 'rb') +# audio_file = open('/home/*/BirdSongs/Extracted/By_Date/2022-03-22/Yellow-streaked_Greenbul/Yellow-streaked_Greenbul-77-2022-03-22-birdnet-15:04:28.mp3', 'rb') # audio_bytes = audio_file.read() -# cols4.audio(audio_bytes, format='audio/mp3') \ No newline at end of file +# cols4.audio(audio_bytes, format='audio/mp3') diff --git a/scripts/privacy_server.py b/scripts/privacy_server.py index 85efa21..15a5672 100755 --- a/scripts/privacy_server.py +++ b/scripts/privacy_server.py @@ -1,4 +1,3 @@ -#!/home/pi/BirdNET-Pi/birdnet/bin/python3 import socket import threading import os @@ -44,7 +43,8 @@ except: # Open most recent Configuration and grab DB_PWD as a python variable -with open('/home/pi/BirdNET-Pi/thisrun.txt', 'r') as f: +userDir = os.path.expanduser('~') +with open(userDir + '/BirdNET-Pi/thisrun.txt', 'r') as f: this_run = f.readlines() audiofmt = "." + str(str(str([i for i in this_run if i.startswith('AUDIOFMT')]).split('=')[1]).split('\\')[0]) @@ -59,7 +59,8 @@ def loadModel(): print('LOADING TF LITE MODEL...', end=' ') # Load TFLite model and allocate tensors. - myinterpreter = tflite.Interpreter(model_path='/home/pi/BirdNET-Pi/model/BirdNET_6K_GLOBAL_MODEL.tflite',num_threads=2) + modelpath = userDir + '/BirdNET-Pi/model/BirdNET_6K_GLOBAL_MODEL.tflite' + myinterpreter = tflite.Interpreter(model_path=modelpath,num_threads=2) myinterpreter.allocate_tensors() # Get input and output tensors. @@ -73,7 +74,7 @@ def loadModel(): # Load labels CLASSES = [] - with open('/home/pi/BirdNET-Pi/model/labels.txt', 'r') as lfile: + with open(userDir + '/BirdNET-Pi/model/labels.txt', 'r') as lfile: for line in lfile.readlines(): CLASSES.append(line.replace('\n', '')) @@ -170,11 +171,11 @@ def predict(sample, sensitivity): if p_sorted[i][0]=='Human_Human': print("HUMAN SCORE:",str(p_sorted[i])) HUMAN_FLAG=True - with open('/home/pi/BirdNET-Pi/HUMAN.txt', 'a') as rfile: + with open(userDir + '/BirdNET-Pi/HUMAN.txt', 'a') as rfile: rfile.write(str(datetime.datetime.now())+str(p_sorted[i])+ '\n') # date_stamp=datetime.datetime.now().strftime("%d_%m_%y_%H:%M:%S") # -# sf.write('./home/pi/human_sample.wav',np.random.randn(10,2) , 44100) #sample[0] +# sf.write('./home/*/human_sample.wav',np.random.randn(10,2) , 44100) #sample[0] # Only return first the top ten results #INCREASE THIS TO SEE IF HUMAN IS DETECTED MORE RELIABLY @@ -259,8 +260,8 @@ def handle_client(conn, addr): args = type('', (), {})() - args.i = '/home/pi/test.wav' - args.o = '/home/pi/test.wav.csv' + args.i = '' + args.o = '' args.birdweather_id = '99999' args.include_list = 'null' args.exclude_list = 'null' @@ -355,7 +356,7 @@ def handle_client(conn, addr): myReturn += str(i) + '-' + str(detections[i][0]) + '\n' - with open('/home/pi/BirdNET-Pi/BirdDB.txt', 'a') as rfile: + with open(userDir + '/BirdNET-Pi/BirdDB.txt', 'a') as rfile: for d in detections: for entry in detections[d]: if entry[1] >= min_conf and ((entry[0] in INCLUDE_LIST or len(INCLUDE_LIST) == 0) and (entry[0] not in EXCLUDE_LIST or len(EXCLUDE_LIST) == 0) ): @@ -381,7 +382,7 @@ def handle_client(conn, addr): #Connect to SQLite Database try: - con = sqlite3.connect('/home/pi/BirdNET-Pi/scripts/birds.db') + con = sqlite3.connect(userDir + '/BirdNET-Pi/scripts/birds.db') cur = con.cursor() cur.execute("INSERT INTO detections VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", (Date, Time, Sci_Name, Com_Name, str(score), Lat, Lon, Cutoff, Week, Sens, Overlap, File_Name)) diff --git a/scripts/restart_services.sh b/scripts/restart_services.sh index cb5384b..2de8f0d 100755 --- a/scripts/restart_services.sh +++ b/scripts/restart_services.sh @@ -2,7 +2,7 @@ # Restarts ALL services and removes ALL unprocessed audio source /etc/birdnet/birdnet.conf set -x -my_dir=/home/pi/BirdNET-Pi/scripts +my_dir=$HOME/BirdNET-Pi/scripts sudo systemctl stop birdnet_server.service sudo pkill server.py diff --git a/scripts/server.py b/scripts/server.py index 6d0b129..0746b88 100755 --- a/scripts/server.py +++ b/scripts/server.py @@ -1,4 +1,3 @@ -#!/home/pi/BirdNET-Pi/birdnet/bin/python3 import socket import threading import os @@ -44,7 +43,8 @@ except: # Open most recent Configuration and grab DB_PWD as a python variable -with open('/home/pi/BirdNET-Pi/thisrun.txt', 'r') as f: +userDir = os.path.expanduser('~') +with open(userDir + '/BirdNET-Pi/scripts/thisrun.txt', 'r') as f: this_run = f.readlines() audiofmt = "." + str(str(str([i for i in this_run if i.startswith('AUDIOFMT')]).split('=')[1]).split('\\')[0]) @@ -59,7 +59,8 @@ def loadModel(): print('LOADING TF LITE MODEL...', end=' ') # Load TFLite model and allocate tensors. - myinterpreter = tflite.Interpreter(model_path='/home/pi/BirdNET-Pi/model/BirdNET_6K_GLOBAL_MODEL.tflite',num_threads=2) + modelpath = userDir + '/BirdNET-Pi/model/BirdNET_6K_GLOBAL_MODEL.tflite' + myinterpreter = tflite.Interpreter(model_path=modelpath,num_threads=1) myinterpreter.allocate_tensors() # Get input and output tensors. @@ -73,7 +74,8 @@ def loadModel(): # Load labels CLASSES = [] - with open('/home/pi/BirdNET-Pi/model/labels.txt', 'r') as lfile: + labelspath = userDir + '/BirdNET-Pi/model/labels.txt' + with open(labelspath, 'r') as lfile: for line in lfile.readlines(): CLASSES.append(line.replace('\n', '')) @@ -233,8 +235,8 @@ def handle_client(conn, addr): args = type('', (), {})() - args.i = '/home/pi/test.wav' - args.o = '/home/pi/test.wav.csv' + args.i = '' + args.o = '' args.birdweather_id = '99999' args.include_list = 'null' args.exclude_list = 'null' @@ -329,7 +331,7 @@ def handle_client(conn, addr): myReturn += str(i) + '-' + str(detections[i][0]) + '\n' - with open('/home/pi/BirdNET-Pi/BirdDB.txt', 'a') as rfile: + with open(userDir + '/BirdNET-Pi/BirdDB.txt', 'a') as rfile: for d in detections: for entry in detections[d]: if entry[1] >= min_conf and ((entry[0] in INCLUDE_LIST or len(INCLUDE_LIST) == 0) and (entry[0] not in EXCLUDE_LIST or len(EXCLUDE_LIST) == 0) ): @@ -354,16 +356,17 @@ def handle_client(conn, addr): Date.replace("/", "-") + '-birdnet-' + Time + audiofmt #Connect to SQLite Database - try: - con = sqlite3.connect('/home/pi/BirdNET-Pi/scripts/birds.db') - cur = con.cursor() - cur.execute("INSERT INTO detections VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", (Date, Time, Sci_Name, Com_Name, str(score), Lat, Lon, Cutoff, Week, Sens, Overlap, File_Name)) + #try: + con = sqlite3.connect(userDir + '/BirdNET-Pi/scripts/birds.db') + cur = con.cursor() + cur.execute("INSERT INTO detections VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", (Date, Time, Sci_Name, Com_Name, str(score), Lat, Lon, Cutoff, Week, Sens, Overlap, File_Name)) + + con.commit() + con.close() + #except: + # print("Database busy") + # time.sleep(2) - con.commit() - con.close() - except: - print("Database busy") - time.sleep(2) print(str(current_date) + ';' + str(current_time) + ';' + entry[0].replace('_', ';') + ';' + str(entry[1]) + ';' + str(args.lat) + ';' + str(args.lon) + ';' + str(min_conf) + ';' + str(week) + ';' + str(args.sensitivity) +';' + str(args.overlap) + Com_Name.replace(" ", "_") + '-' + str(score) + '-' + str(current_date) + '-birdnet-' + str(current_time) + audiofmt + '\n') if birdweather_id != "99999": diff --git a/scripts/species_notifier.sh b/scripts/species_notifier.sh index a7a01bc..9596754 100755 --- a/scripts/species_notifier.sh +++ b/scripts/species_notifier.sh @@ -10,7 +10,7 @@ lastcheck="$(mktemp)" cp ${IDFILE} ${lastcheck} -/home/pi/BirdNET-Pi/scripts/update_species.sh +$HOME/BirdNET-Pi/scripts/update_species.sh if ! diff ${IDFILE} ${lastcheck} &> /dev/null;then SPECIES=$(diff ${IDFILE} ${lastcheck} \ diff --git a/scripts/spectrogram.php b/scripts/spectrogram.php index e9d87bc..2ed5f72 100644 --- a/scripts/spectrogram.php +++ b/scripts/spectrogram.php @@ -1,8 +1,8 @@ Reboot
- +
- +
diff --git a/scripts/todays_detections.php b/scripts/todays_detections.php index 8ed2eee..eb18512 100644 --- a/scripts/todays_detections.php +++ b/scripts/todays_detections.php @@ -3,7 +3,7 @@ ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); -$db = new SQLite3('/home/pi/BirdNET-Pi/scripts/birds.db', SQLITE3_OPEN_CREATE | SQLITE3_OPEN_READWRITE); +$db = new SQLite3('./scripts/birds.db', SQLITE3_OPEN_CREATE | SQLITE3_OPEN_READWRITE); if($db == False){ echo "Database is busy"; header("refresh: 0;"); diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh index 50823d3..da7d4c4 100755 --- a/scripts/uninstall.sh +++ b/scripts/uninstall.sh @@ -2,7 +2,7 @@ # Uninstall script to remove everything #set -x # Uncomment to debug trap 'rm -f ${TMPFILE}' EXIT -my_dir=/home/pi/BirdNET-Pi/scripts +my_dir=$HOME/BirdNET-Pi/scripts source /etc/birdnet/birdnet.conf &> /dev/null SCRIPTS=($(ls -1 ${my_dir}) ${HOME}/.gotty) set -x diff --git a/scripts/update_birdnet.sh b/scripts/update_birdnet.sh index e8e83c4..970dd04 100755 --- a/scripts/update_birdnet.sh +++ b/scripts/update_birdnet.sh @@ -2,14 +2,12 @@ # Update BirdNET-Pi source /etc/birdnet/birdnet.conf trap 'exit 1' SIGINT SIGHUP -USER=pi -HOME=/home/pi my_dir=${HOME}/BirdNET-Pi/scripts -sudo -u${USER} git -C /home/pi/BirdNET-Pi stash -sudo -u${USER} git -C /home/pi/BirdNET-Pi pull -f +sudo -u${USER} git -C $my_dir/BirdNET-Pi stash +sudo -u${USER} git -C $my_dir/BirdNET-Pi pull -f sudo systemctl daemon-reload -sudo -u${USER} git -C /home/pi/BirdNET-Pi stash pop +sudo -u${USER} git -C $my_dir/BirdNET-Pi stash pop sudo ln -sf $my_dir/* /usr/local/bin/ if ! grep PRIVACY_MODE /etc/birdnet/birdnet.conf;then sudo -u${USER} echo "PRIVACY_MODE=off" >> /etc/birdnet/birdnet.conf diff --git a/scripts/update_caddyfile.sh b/scripts/update_caddyfile.sh index c0f0e3e..4926d13 100755 --- a/scripts/update_caddyfile.sh +++ b/scripts/update_caddyfile.sh @@ -1,8 +1,6 @@ #!/usr/bin/env bash source /etc/birdnet/birdnet.conf -USER=pi -HOME=/home/pi -my_dir=/home/pi/BirdNET-Pi/scripts +my_dir=$HOME/BirdNET-Pi/scripts set -x [ -d /etc/caddy ] || mkdir /etc/caddy if [ -f /etc/caddy/Caddyfile ];then diff --git a/scripts/update_species.sh b/scripts/update_species.sh index eb59741..3989e73 100755 --- a/scripts/update_species.sh +++ b/scripts/update_species.sh @@ -2,4 +2,4 @@ # Update the species list #set -x source /etc/birdnet/birdnet.conf -sqlite3 /home/pi/BirdNET-Pi/scripts/birds.db "SELECT DISTINCT(Com_Name) FROM detections" | sort > ${IDFILE} +sqlite3 $HOME/BirdNET-Pi/scripts/birds.db "SELECT DISTINCT(Com_Name) FROM detections" | sort > ${IDFILE} diff --git a/scripts/write_config.sh b/scripts/write_config.sh index 15bfa31..6d66b2a 100755 --- a/scripts/write_config.sh +++ b/scripts/write_config.sh @@ -1,6 +1,6 @@ #!/usr/bin/bash # Writes variables to config file -birdnetpi_dir=/home/pi/BirdNET-Pi +birdnetpi_dir=$HOME/BirdNET-Pi birders_conf=${birdnetpi_dir}/Birders_Guide_Installer_Configuration.txt sed -i s/'^LATITUDE=$'/"LATITUDE=${new_lat}"/g ${birders_conf} sed -i s/'^LONGITUDE=$'/"LONGITUDE=${new_lon}"/g ${birders_conf} diff --git a/templates/bashrc b/templates/bashrc index f5a93a8..7c0a0d8 100644 --- a/templates/bashrc +++ b/templates/bashrc @@ -113,7 +113,8 @@ if ! shopt -oq posix; then fi cd ~/BirdNET-Pi function remove() { - find /home/pi/BirdSongs -iname *${1}* -exec rm -drfv {} + + source /etc/birdnet/birdnet.conf + find $RECS_DIR -iname *${1}* -exec rm -drfv {} + } alias rerc="source ~/.bashrc" alias vimrc="vim ~/.bashrc" diff --git a/templates/cleanup.cron b/templates/cleanup.cron index 42e5a26..4fb2fec 100644 --- a/templates/cleanup.cron +++ b/templates/cleanup.cron @@ -1,6 +1,6 @@ #birdnet -*/5 * * * * pi /usr/local/bin/disk_check.sh &> /dev/null +*/5 * * * * $USER /usr/local/bin/disk_check.sh &> /dev/null #birdnet -*/3 * * * * pi /usr/local/bin/cleanup.sh &> /dev/null +*/3 * * * * $USER /usr/local/bin/cleanup.sh &> /dev/null #birdnet -@reboot pi /usr/local/bin/cleanup.sh &> /dev/null +@reboot $USER /usr/local/bin/cleanup.sh &> /dev/null