0) { syslog(LOG_INFO, $output); } } if(isset($_GET['threshold'])) { $threshold = $_GET['threshold']; if (!is_numeric($threshold) || $threshold < 0 || $threshold > 1) { die('Invalid threshold value'); } $command = "sudo -u $user ".$home."/BirdNET-Pi/birdnet/bin/python3 ".$home."/BirdNET-Pi/scripts/species.py --threshold $threshold 2>&1"; $output = shell_exec($command); echo $output; die(); } if(isset($_GET['restart_php']) && $_GET['restart_php'] == "true") { shell_exec("sudo service php*-fpm restart"); die(); } # Basic Settings if(isset($_GET["latitude"])){ $latitude = $_GET["latitude"]; $longitude = $_GET["longitude"]; $site_name = $_GET["site_name"]; $site_name = str_replace('"', "", $site_name); $site_name = str_replace('\'', "", $site_name); $birdweather_id = $_GET["birdweather_id"]; $apprise_input = $_GET['apprise_input']; $apprise_notification_title = $_GET['apprise_notification_title']; $apprise_notification_body = $_GET['apprise_notification_body']; $minimum_time_limit = $_GET['minimum_time_limit']; $flickr_api_key = $_GET['flickr_api_key']; $flickr_filter_email = $_GET["flickr_filter_email"]; $language = $_GET["language"]; $timezone = $_GET["timezone"]; $model = $_GET["model"]; $sf_thresh = $_GET["sf_thresh"]; if(isset($_GET['data_model_version'])) { $data_model_version = 2; } else { $data_model_version = 1; } $only_notify_species_names = $_GET['only_notify_species_names']; $only_notify_species_names_2 = $_GET['only_notify_species_names_2']; if(isset($_GET['apprise_notify_each_detection'])) { $apprise_notify_each_detection = 1; } else { $apprise_notify_each_detection = 0; } if(isset($_GET['apprise_notify_new_species'])) { $apprise_notify_new_species = 1; } else { $apprise_notify_new_species = 0; } if(isset($_GET['apprise_notify_new_species_each_day'])) { $apprise_notify_new_species_each_day = 1; } else { $apprise_notify_new_species_each_day = 0; } if(isset($_GET['apprise_weekly_report'])) { $apprise_weekly_report = 1; } else { $apprise_weekly_report = 0; } if(isset($timezone) && in_array($timezone, DateTimeZone::listIdentifiers())) { shell_exec("sudo timedatectl set-timezone ".$timezone); $_SESSION['my_timezone'] = $timezone; date_default_timezone_set($timezone); echo ""; } // logic for setting the date and time based on user inputs from the form below if(isset($_GET['date']) && isset($_GET['time'])) { // can't set the date manually if it's getting it from the internet, disable ntp exec("sudo timedatectl set-ntp false"); // check if valid date and time $datetime = DateTime::createFromFormat('Y-m-d H:i', $_GET['date'] . ' ' . $_GET['time']); if ($datetime && $datetime->format('Y-m-d H:i') === $_GET['date'] . ' ' . $_GET['time']) { exec("sudo date -s '".$_GET['date']." ".$_GET['time']."'"); } } else { // user checked 'use time from internet if available,' so make sure that's on if(strlen(trim(exec("sudo timedatectl | grep \"NTP service: active\""))) == 0){ exec("sudo timedatectl set-ntp true"); sleep(3); } } if ($model != $config['MODEL'] || $language != $config['DATABASE_LANG']){ if(strlen($language) == 2){ // Archive old language file syslog_shell_exec("cp -f $home/BirdNET-Pi/model/labels.txt $home/BirdNET-Pi/model/labels.txt.old", $user); if($model == "BirdNET_GLOBAL_6K_V2.4_Model_FP16"){ // Install new language label file syslog_shell_exec("chmod +x $home/BirdNET-Pi/scripts/install_language_label_nm.sh && $home/BirdNET-Pi/scripts/install_language_label_nm.sh -l $language", $user); } else { syslog_shell_exec("$home/BirdNET-Pi/scripts/install_language_label.sh -l $language", $user); } syslog(LOG_INFO, "Successfully changed language to '$language' and model to '$model'"); } } $contents = file_get_contents("/etc/birdnet/birdnet.conf"); $contents = preg_replace("/SITE_NAME=.*/", "SITE_NAME=\"$site_name\"", $contents); $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("/APPRISE_NOTIFICATION_TITLE=.*/", "APPRISE_NOTIFICATION_TITLE=\"$apprise_notification_title\"", $contents); $contents = preg_replace("/APPRISE_NOTIFICATION_BODY=.*/", "APPRISE_NOTIFICATION_BODY=\"$apprise_notification_body\"", $contents); $contents = preg_replace("/APPRISE_NOTIFY_EACH_DETECTION=.*/", "APPRISE_NOTIFY_EACH_DETECTION=$apprise_notify_each_detection", $contents); $contents = preg_replace("/APPRISE_NOTIFY_NEW_SPECIES=.*/", "APPRISE_NOTIFY_NEW_SPECIES=$apprise_notify_new_species", $contents); $contents = preg_replace("/APPRISE_NOTIFY_NEW_SPECIES_EACH_DAY=.*/", "APPRISE_NOTIFY_NEW_SPECIES_EACH_DAY=$apprise_notify_new_species_each_day", $contents); $contents = preg_replace("/APPRISE_WEEKLY_REPORT=.*/", "APPRISE_WEEKLY_REPORT=$apprise_weekly_report", $contents); $contents = preg_replace("/FLICKR_API_KEY=.*/", "FLICKR_API_KEY=$flickr_api_key", $contents); $contents = preg_replace("/DATABASE_LANG=.*/", "DATABASE_LANG=$language", $contents); $contents = preg_replace("/FLICKR_FILTER_EMAIL=.*/", "FLICKR_FILTER_EMAIL=$flickr_filter_email", $contents); $contents = preg_replace("/APPRISE_MINIMUM_SECONDS_BETWEEN_NOTIFICATIONS_PER_SPECIES=.*/", "APPRISE_MINIMUM_SECONDS_BETWEEN_NOTIFICATIONS_PER_SPECIES=$minimum_time_limit", $contents); $contents = preg_replace("/MODEL=.*/", "MODEL=$model", $contents); $contents = preg_replace("/SF_THRESH=.*/", "SF_THRESH=$sf_thresh", $contents); $contents = preg_replace("/DATA_MODEL_VERSION=.*/", "DATA_MODEL_VERSION=$data_model_version", $contents); $contents = preg_replace("/APPRISE_ONLY_NOTIFY_SPECIES_NAMES=.*/", "APPRISE_ONLY_NOTIFY_SPECIES_NAMES=\"$only_notify_species_names\"", $contents); $contents = preg_replace("/APPRISE_ONLY_NOTIFY_SPECIES_NAMES_2=.*/", "APPRISE_ONLY_NOTIFY_SPECIES_NAMES_2=\"$only_notify_species_names_2\"", $contents); if($site_name != $config["SITE_NAME"]) { echo ""; } $fh = fopen("/etc/birdnet/birdnet.conf", "w"); fwrite($fh, $contents); if(isset($apprise_input)){ $appriseconfig = fopen($home."/BirdNET-Pi/apprise.txt", "w"); fwrite($appriseconfig, $apprise_input); $apprise_config = $apprise_input; } syslog(LOG_INFO, "Restarting Services"); shell_exec("sudo restart_services.sh"); } if(isset($_GET['sendtest']) && $_GET['sendtest'] == "true") { $db = new SQLite3($home."/BirdNET-Pi/scripts/birds.db", SQLITE3_OPEN_READONLY); $db->busyTimeout(1000); $cf = explode("\n",$_GET['apprise_config']); $cf = "'".implode("' '", $cf)."'"; $statement0 = $db->prepare('SELECT * FROM detections WHERE Date == DATE(\'now\', \'localtime\') ORDER BY TIME DESC LIMIT 1'); $result0 = $statement0->execute(); while($todaytable=$result0->fetchArray(SQLITE3_ASSOC)) { $sciname = $todaytable['Sci_Name']; $comname = $todaytable['Com_Name']; $confidence = $todaytable['Confidence']; $filename = $todaytable['File_Name']; $date = $todaytable['Date']; $time = $todaytable['Time']; $week = $todaytable['Week']; $latitude = $todaytable['Lat']; $longitude = $todaytable['Lon']; $cutoff = $todaytable['Cutoff']; $sens = $todaytable['Sens']; $overlap = $todaytable['Overlap']; } $title = $_GET['apprise_notification_title']; $body = $_GET['apprise_notification_body']; if($config["BIRDNETPI_URL"] != "") { $filename = $config["BIRDNETPI_URL"]."?filename=".$filename; } else{ $filename = "http://".$_SERVER['SERVER_NAME']."/"."?filename=".$filename; } $attach=""; $exampleimage = "https://live.staticflickr.com/7430/27545810581_8bfa8289a3_c.jpg"; if (strpos($body, '$flickrimage') !== false) { $attach = "--attach ".$exampleimage; } if (strpos($body, '{') === false) { $exampleimage = ""; } $title = str_replace("\$sciname", $sciname, $title); $title = str_replace("\$comname", $comname, $title); $title = str_replace("\$confidencepct", round($confidence*100), $title); $title = str_replace("\$confidence", $confidence, $title); $title = str_replace("\$listenurl", $filename, $title); $title = str_replace("\$date", $date, $title); $title = str_replace("\$time", $time, $title); $title = str_replace("\$week", $week, $title); $title = str_replace("\$latitude", $latitude, $title); $title = str_replace("\$longitude", $longitude, $title); $title = str_replace("\$cutoff", $cutoff, $title); $title = str_replace("\$sens", $sens, $title); $title = str_replace("\$overlap", $overlap, $title); $title = str_replace("\$flickrimage", $exampleimage, $title); $title = str_replace("\$reason", 'Test message', $title); $body = str_replace("\$sciname", $sciname, $body); $body = str_replace("\$comname", $comname, $body); $body = str_replace("\$confidencepct", round($confidence*100), $body); $body = str_replace("\$confidence", $confidence, $body); $body = str_replace("\$listenurl", $filename, $body); $body = str_replace("\$date", $date, $body); $body = str_replace("\$time", $time, $body); $body = str_replace("\$week", $week, $body); $body = str_replace("\$latitude", $latitude, $body); $body = str_replace("\$longitude", $longitude, $body); $body = str_replace("\$cutoff", $cutoff, $body); $body = str_replace("\$sens", $sens, $body); $body = str_replace("\$overlap", $overlap, $body); $body = str_replace("\$flickrimage", $exampleimage, $body); $body = str_replace("\$reason", 'Test message', $body); $temp = tmpfile(); $tpath = stream_get_meta_data($temp)['uri']; fwrite($temp, $body); echo "
".shell_exec($home."/BirdNET-Pi/birdnet/bin/apprise -vv --plugin-path ".$home."/.apprise/plugins "." -t '".escapeshellcmd($title)."' ".$attach." ".$cf." <".$tpath)."
"; fclose($temp); die(); } // have to get the config again after we change the variables, so the UI reflects the changes too $config = get_config($force_reload=true); ?>

Basic Settings


Model


style="display: none" id="soft"> > [ Info here ]
[more info]

  
BirdNET_GLOBAL_6K_V2.4_Model_FP16 (2023)

This is the BirdNET-Analyzer model, the most advanced BirdNET model to date. Currently it supports over 6,000 species worldwide, giving quite good species coverage for people in most of the world.

BirdNET_6K_GLOBAL_MODEL (2020)

This is the BirdNET-Lite model, with bird sound recognition for more than 6,000 species worldwide. This has generally worse performance than the newer models but is kept as a legacy option.

[ In-depth technical write-up on the models here ]

Location

(Optional)

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


BirdWeather


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


Notifications

Apprise Notifications can be setup and enabled for 90+ notification services. Each service should be on its own line.


$sciname
Scientific Name
$comname
Common Name
$confidence
Confidence Score
$confidencepct
Confidence Score as a percentage (eg. 0.91 => 91)
$listenurl
A link to the detection
$date
Date
$time
Time
$week
Week
$latitude
Latitude
$longitude
Longitude
$cutoff
Minimum Confidence set in "Advanced Settings"
$sens
Sigmoid Sensitivity set in "Advanced Settings"
$overlap
Overlap set in "Advanced Settings"
$flickrimage
A preview image of the detected species from Flickr. Set your API key below.
$reason
The reason a notification was sent

Use the variables defined above to customize your notification title and body.


' />
>
>
>
>







Bird Photos from Flickr



Set your Flickr API key to enable the display of bird images next to detections. Get your free key here.


Localization


0) { $checkedvalue = "checked"; $disabledvalue = "disabled"; } else { $checkedvalue = ""; $disabledvalue = ""; } ?>

Time and Date

If connected to the internet, retrieve time automatically? >
> >