Merge branch 'main' of https://github.com/lloydbayley/BirdNET-Pi
This commit is contained in:
@@ -66,7 +66,7 @@ Currently listening in these countries . . . that I know of . . .
|
|||||||
* **Automatic extraction and cataloguing** of bird sounds
|
* **Automatic extraction and cataloguing** of bird sounds
|
||||||
* **Tools to visualize your recorded bird data** and analyze trends
|
* **Tools to visualize your recorded bird data** and analyze trends
|
||||||
* **Live audio stream and spectrogram**
|
* **Live audio stream and spectrogram**
|
||||||
* **Automatic disk space management** that periodically purges old audio files to manage disk space
|
* **Automatic disk space management** that periodically purges old audio files
|
||||||
* [BirdWeather](https://app.birdweather.com) integration -- you can request a BirdWeather ID from BirdNET-Pi's "Tools" > "Settings" page
|
* [BirdWeather](https://app.birdweather.com) integration -- you can request a BirdWeather ID from BirdNET-Pi's "Tools" > "Settings" page
|
||||||
* Web interface access to all data and logs provided by [Caddy](https://caddyserver.com)
|
* Web interface access to all data and logs provided by [Caddy](https://caddyserver.com)
|
||||||
* [GoTTY](https://github.com/yudai/gotty) Web Terminal
|
* [GoTTY](https://github.com/yudai/gotty) Web Terminal
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ APPRISE_WEEKLY_REPORT=1
|
|||||||
APPRISE_NOTIFY_NEW_SPECIES_EACH_DAY=0
|
APPRISE_NOTIFY_NEW_SPECIES_EACH_DAY=0
|
||||||
APPRISE_MINIMUM_SECONDS_BETWEEN_NOTIFICATIONS_PER_SPECIES=0
|
APPRISE_MINIMUM_SECONDS_BETWEEN_NOTIFICATIONS_PER_SPECIES=0
|
||||||
APPRISE_ONLY_NOTIFY_SPECIES_NAMES=""
|
APPRISE_ONLY_NOTIFY_SPECIES_NAMES=""
|
||||||
|
APPRISE_ONLY_NOTIFY_SPECIES_NAMES_2=""
|
||||||
|
|
||||||
#---------------------- Flickr Images API Configuration -----------------------#
|
#---------------------- Flickr Images API Configuration -----------------------#
|
||||||
## If FLICKR_API_KEY is set, the web interface will try and display bird images
|
## If FLICKR_API_KEY is set, the web interface will try and display bird images
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+10
-5
@@ -54,6 +54,7 @@ if(isset($_GET["latitude"])){
|
|||||||
$model = $_GET["model"];
|
$model = $_GET["model"];
|
||||||
$sf_thresh = $_GET["sf_thresh"];
|
$sf_thresh = $_GET["sf_thresh"];
|
||||||
$only_notify_species_names = $_GET['only_notify_species_names'];
|
$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'])) {
|
if(isset($_GET['apprise_notify_each_detection'])) {
|
||||||
$apprise_notify_each_detection = 1;
|
$apprise_notify_each_detection = 1;
|
||||||
@@ -120,7 +121,7 @@ if(isset($_GET["latitude"])){
|
|||||||
// Archive old language file
|
// Archive old language file
|
||||||
syslog_shell_exec("cp -f $home/BirdNET-Pi/model/labels.txt $home/BirdNET-Pi/model/labels.txt.old", $user);
|
syslog_shell_exec("cp -f $home/BirdNET-Pi/model/labels.txt $home/BirdNET-Pi/model/labels.txt.old", $user);
|
||||||
|
|
||||||
if($model == "BirdNET_GLOBAL_3K_V2.2_Model_FP16"){
|
if($model == "BirdNET_GLOBAL_3K_V2.3_Model_FP16"){
|
||||||
// Install new language label file
|
// Install new language label file
|
||||||
syslog_shell_exec("sudo chmod +x $home/BirdNET-Pi/scripts/install_language_label_nm.sh && $home/BirdNET-Pi/scripts/install_language_label_nm.sh -l $language", $user);
|
syslog_shell_exec("sudo chmod +x $home/BirdNET-Pi/scripts/install_language_label_nm.sh && $home/BirdNET-Pi/scripts/install_language_label_nm.sh -l $language", $user);
|
||||||
} else {
|
} else {
|
||||||
@@ -150,6 +151,7 @@ if(isset($_GET["latitude"])){
|
|||||||
$contents = preg_replace("/MODEL=.*/", "MODEL=$model", $contents);
|
$contents = preg_replace("/MODEL=.*/", "MODEL=$model", $contents);
|
||||||
$contents = preg_replace("/SF_THRESH=.*/", "SF_THRESH=$sf_thresh", $contents);
|
$contents = preg_replace("/SF_THRESH=.*/", "SF_THRESH=$sf_thresh", $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=.*/", "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);
|
||||||
|
|
||||||
$contents2 = file_get_contents("./scripts/thisrun.txt");
|
$contents2 = file_get_contents("./scripts/thisrun.txt");
|
||||||
$contents2 = preg_replace("/SITE_NAME=.*/", "SITE_NAME=\"$site_name\"", $contents2);
|
$contents2 = preg_replace("/SITE_NAME=.*/", "SITE_NAME=\"$site_name\"", $contents2);
|
||||||
@@ -169,6 +171,7 @@ if(isset($_GET["latitude"])){
|
|||||||
$contents2 = preg_replace("/MODEL=.*/", "MODEL=$model", $contents2);
|
$contents2 = preg_replace("/MODEL=.*/", "MODEL=$model", $contents2);
|
||||||
$contents2 = preg_replace("/SF_THRESH=.*/", "SF_THRESH=$sf_thresh", $contents2);
|
$contents2 = preg_replace("/SF_THRESH=.*/", "SF_THRESH=$sf_thresh", $contents2);
|
||||||
$contents2 = preg_replace("/APPRISE_ONLY_NOTIFY_SPECIES_NAMES=.*/", "APPRISE_ONLY_NOTIFY_SPECIES_NAMES=\"$only_notify_species_names\"", $contents2);
|
$contents2 = preg_replace("/APPRISE_ONLY_NOTIFY_SPECIES_NAMES=.*/", "APPRISE_ONLY_NOTIFY_SPECIES_NAMES=\"$only_notify_species_names\"", $contents2);
|
||||||
|
$contents2 = preg_replace("/APPRISE_ONLY_NOTIFY_SPECIES_NAMES_2=.*/", "APPRISE_ONLY_NOTIFY_SPECIES_NAMES_2=\"$only_notify_species_names_2\"", $contents2);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -325,7 +328,7 @@ if (!isset($_SERVER['PHP_AUTH_USER'])) {
|
|||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
document.getElementById('modelsel').addEventListener('change', function() {
|
document.getElementById('modelsel').addEventListener('change', function() {
|
||||||
if(this.value == "BirdNET_GLOBAL_3K_V2.2_Model_FP16"){
|
if(this.value == "BirdNET_GLOBAL_3K_V2.3_Model_FP16"){
|
||||||
document.getElementById("soft").style.display="unset";
|
document.getElementById("soft").style.display="unset";
|
||||||
} else {
|
} else {
|
||||||
document.getElementById("soft").style.display="none";
|
document.getElementById("soft").style.display="none";
|
||||||
@@ -357,7 +360,7 @@ function sendTestNotification(e) {
|
|||||||
<label for="model">Select a Model: </label>
|
<label for="model">Select a Model: </label>
|
||||||
<select id="modelsel" name="model">
|
<select id="modelsel" name="model">
|
||||||
<?php
|
<?php
|
||||||
$models = array("BirdNET_6K_GLOBAL_MODEL", "BirdNET_GLOBAL_3K_V2.2_Model_FP16");
|
$models = array("BirdNET_6K_GLOBAL_MODEL", "BirdNET_GLOBAL_3K_V2.3_Model_FP16");
|
||||||
foreach($models as $modelName){
|
foreach($models as $modelName){
|
||||||
$isSelected = "";
|
$isSelected = "";
|
||||||
if($config['MODEL'] == $modelName){
|
if($config['MODEL'] == $modelName){
|
||||||
@@ -473,7 +476,7 @@ function runProcess() {
|
|||||||
<dt>BirdNET_6K_GLOBAL_MODEL (2020)</dt><br>
|
<dt>BirdNET_6K_GLOBAL_MODEL (2020)</dt><br>
|
||||||
<dd id="ddnewline">This is the BirdNET-Lite model, with bird sound recognition for more than 6,000 species worldwide. This is the default option and will generally work very for people in most of the world.</dd>
|
<dd id="ddnewline">This is the BirdNET-Lite model, with bird sound recognition for more than 6,000 species worldwide. This is the default option and will generally work very for people in most of the world.</dd>
|
||||||
<br>
|
<br>
|
||||||
<dt>BirdNET_GLOBAL_3K_V2.2_Model_FP16 (2022)</dt><br>
|
<dt>BirdNET_GLOBAL_3K_V2.3_Model_FP16 (2022)</dt><br>
|
||||||
<dd id="ddnewline">This is the BirdNET-Analyzer model, a newer work-in-progress project with aims to improve on the BirdNET-Lite model. Currently it only supports about 3,500 species worldwide, meaning for some regions (North America, Europe, Australia) it will usually outperform the BirdNET-Lite model, but for other regions it will be worse.</dd><br>
|
<dd id="ddnewline">This is the BirdNET-Analyzer model, a newer work-in-progress project with aims to improve on the BirdNET-Lite model. Currently it only supports about 3,500 species worldwide, meaning for some regions (North America, Europe, Australia) it will usually outperform the BirdNET-Lite model, but for other regions it will be worse.</dd><br>
|
||||||
<dt>[ In-depth technical write-up on the models <a target="_blank" href="https://github.com/mcguirepr89/BirdNET-Pi/wiki/BirdNET-Pi:-some-theory-on-classification-&-some-practical-hints">here</a> ]</dt>
|
<dt>[ In-depth technical write-up on the models <a target="_blank" href="https://github.com/mcguirepr89/BirdNET-Pi/wiki/BirdNET-Pi:-some-theory-on-classification-&-some-practical-hints">here</a> ]</dt>
|
||||||
</dl>
|
</dl>
|
||||||
@@ -550,7 +553,9 @@ https://discordapp.com/api/webhooks/{WebhookID}/{WebhookToken}
|
|||||||
<label for="minimum_time_limit">Minimum time between notifications of the same species (sec):</label>
|
<label for="minimum_time_limit">Minimum time between notifications of the same species (sec):</label>
|
||||||
<input type="number" id="minimum_time_limit" name="minimum_time_limit" value="<?php echo $config['APPRISE_MINIMUM_SECONDS_BETWEEN_NOTIFICATIONS_PER_SPECIES'];?>" min="0"><br>
|
<input type="number" id="minimum_time_limit" name="minimum_time_limit" value="<?php echo $config['APPRISE_MINIMUM_SECONDS_BETWEEN_NOTIFICATIONS_PER_SPECIES'];?>" min="0"><br>
|
||||||
<label for="only_notify_species_names">Exclude these species (comma separated common names):</label>
|
<label for="only_notify_species_names">Exclude these species (comma separated common names):</label>
|
||||||
<input type="text" id="only_notify_species_names" placeholder="Northern Cardinal,American Crow,Carolina Chickadee" name="only_notify_species_names" value="<?php echo $config['APPRISE_ONLY_NOTIFY_SPECIES_NAMES'];?>" size=96><br>
|
<input type="text" id="only_notify_species_names" placeholder="Mourning Dove,American Crow" name="only_notify_species_names" value="<?php echo $config['APPRISE_ONLY_NOTIFY_SPECIES_NAMES'];?>" size=96><br>
|
||||||
|
<label for="only_notify_species_names_2">ONLY notify for these species (comma separated common names):</label>
|
||||||
|
<input type="text" id="only_notify_species_names_2" placeholder="Northern Cardinal,Carolina Chickadee,Eastern Bluebird" name="only_notify_species_names_2" value="<?php echo $config['APPRISE_ONLY_NOTIFY_SPECIES_NAMES_2'];?>" size=96><br>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ APPRISE_WEEKLY_REPORT=1
|
|||||||
APPRISE_NOTIFY_NEW_SPECIES_EACH_DAY=0
|
APPRISE_NOTIFY_NEW_SPECIES_EACH_DAY=0
|
||||||
APPRISE_MINIMUM_SECONDS_BETWEEN_NOTIFICATIONS_PER_SPECIES=0
|
APPRISE_MINIMUM_SECONDS_BETWEEN_NOTIFICATIONS_PER_SPECIES=0
|
||||||
APPRISE_ONLY_NOTIFY_SPECIES_NAMES=""
|
APPRISE_ONLY_NOTIFY_SPECIES_NAMES=""
|
||||||
|
APPRISE_ONLY_NOTIFY_SPECIES_NAMES_2=""
|
||||||
|
|
||||||
#---------------------- Flickr Images API Configuration -----------------------#
|
#---------------------- Flickr Images API Configuration -----------------------#
|
||||||
## If FLICKR_API_KEY is set, the web interface will try and display bird images
|
## If FLICKR_API_KEY is set, the web interface will try and display bird images
|
||||||
|
|||||||
@@ -309,8 +309,8 @@ body::-webkit-scrollbar {
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<div class="overview">
|
<div class="overview">
|
||||||
<dialog style="margin-top: 5px;max-height: 100vh;
|
<dialog style="margin-top: 5px;max-height: 95vh;
|
||||||
overflow-y: auto;" id="attribution-dialog">
|
overflow-y: auto;overscroll-behavior:contain" id="attribution-dialog">
|
||||||
<h1 id="modalHeading"></h1>
|
<h1 id="modalHeading"></h1>
|
||||||
<p id="modalText"></p>
|
<p id="modalText"></p>
|
||||||
<button onclick="hideDialog()">Close</button>
|
<button onclick="hideDialog()">Close</button>
|
||||||
@@ -349,7 +349,7 @@ body::-webkit-scrollbar {
|
|||||||
|
|
||||||
function setModalText(iter, title, text, authorlink, photolink, licenseurl) {
|
function setModalText(iter, title, text, authorlink, photolink, licenseurl) {
|
||||||
document.getElementById('modalHeading').innerHTML = "Photo: \""+decodeURIComponent(title.replaceAll("+"," "))+"\" Attribution";
|
document.getElementById('modalHeading').innerHTML = "Photo: \""+decodeURIComponent(title.replaceAll("+"," "))+"\" Attribution";
|
||||||
document.getElementById('modalText').innerHTML = "<div><img style='border-radius:5px;max-height: calc(100vh - 15rem);display: block;margin: 0 auto;' src='"+photolink+"'></div><br><div>Image link: <a target='_blank' href="+text+">"+text+"</a><br>Author link: <a target='_blank' href="+authorlink+">"+authorlink+"</a><br>License URL: <a href="+licenseurl+" target='_blank'>"+licenseurl+"</a></div>";
|
document.getElementById('modalText').innerHTML = "<div><img style='border-radius:5px;max-height: calc(100vh - 15rem);display: block;margin: 0 auto;' src='"+photolink+"'></div><br><div style='white-space:nowrap'>Image link: <a target='_blank' href="+text+">"+text+"</a><br>Author link: <a target='_blank' href="+authorlink+">"+authorlink+"</a><br>License URL: <a href="+licenseurl+" target='_blank'>"+licenseurl+"</a></div>";
|
||||||
last_photo_link = text;
|
last_photo_link = text;
|
||||||
showDialog();
|
showDialog();
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -231,7 +231,7 @@ function toggleLock(filename, type, elem) {
|
|||||||
elem.setAttribute("onclick", elem.getAttribute("onclick").replace("add","del"));
|
elem.setAttribute("onclick", elem.getAttribute("onclick").replace("add","del"));
|
||||||
} else {
|
} else {
|
||||||
elem.setAttribute("src","images/unlock.svg");
|
elem.setAttribute("src","images/unlock.svg");
|
||||||
elem.setAttribute("title", "This file is not excluded from being purged.");
|
elem.setAttribute("title", "This file will be deleted when disk space needs to be freed.");
|
||||||
elem.setAttribute("onclick", elem.getAttribute("onclick").replace("del","add"));
|
elem.setAttribute("onclick", elem.getAttribute("onclick").replace("del","add"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -489,7 +489,7 @@ echo "<table>
|
|||||||
if($config["FULL_DISK"] == "purge") {
|
if($config["FULL_DISK"] == "purge") {
|
||||||
if(!in_array($filename_formatted, $disk_check_exclude_arr)) {
|
if(!in_array($filename_formatted, $disk_check_exclude_arr)) {
|
||||||
$imageicon = "images/unlock.svg";
|
$imageicon = "images/unlock.svg";
|
||||||
$title = "This file is not excluded from being purged.";
|
$title = "This file will be deleted when disk space needs to be freed (>95% usage).";
|
||||||
$type = "add";
|
$type = "add";
|
||||||
} else {
|
} else {
|
||||||
$imageicon = "images/lock.svg";
|
$imageicon = "images/lock.svg";
|
||||||
@@ -564,7 +564,7 @@ echo "<table>
|
|||||||
if($config["FULL_DISK"] == "purge") {
|
if($config["FULL_DISK"] == "purge") {
|
||||||
if(!in_array($filename_formatted, $disk_check_exclude_arr)) {
|
if(!in_array($filename_formatted, $disk_check_exclude_arr)) {
|
||||||
$imageicon = "images/unlock.svg";
|
$imageicon = "images/unlock.svg";
|
||||||
$title = "This file is not excluded from being purged.";
|
$title = "This file will be deleted when disk space needs to be freed (>95% usage).";
|
||||||
$type = "add";
|
$type = "add";
|
||||||
} else {
|
} else {
|
||||||
$imageicon = "images/lock.svg";
|
$imageicon = "images/lock.svg";
|
||||||
|
|||||||
+4
-4
@@ -71,7 +71,7 @@ def loadModel():
|
|||||||
print('LOADING TF LITE MODEL...', end=' ')
|
print('LOADING TF LITE MODEL...', end=' ')
|
||||||
|
|
||||||
# Load TFLite model and allocate tensors.
|
# Load TFLite model and allocate tensors.
|
||||||
# model will either be BirdNET_GLOBAL_3K_V2.2_Model_FP16 (new) or BirdNET_6K_GLOBAL_MODEL (old)
|
# model will either be BirdNET_GLOBAL_3K_V2.3_Model_FP16 (new) or BirdNET_6K_GLOBAL_MODEL (old)
|
||||||
modelpath = userDir + '/BirdNET-Pi/model/'+model+'.tflite'
|
modelpath = userDir + '/BirdNET-Pi/model/'+model+'.tflite'
|
||||||
myinterpreter = tflite.Interpreter(model_path=modelpath, num_threads=2)
|
myinterpreter = tflite.Interpreter(model_path=modelpath, num_threads=2)
|
||||||
myinterpreter.allocate_tensors()
|
myinterpreter.allocate_tensors()
|
||||||
@@ -104,7 +104,7 @@ def loadMetaModel():
|
|||||||
global M_OUTPUT_LAYER_INDEX
|
global M_OUTPUT_LAYER_INDEX
|
||||||
|
|
||||||
# Load TFLite model and allocate tensors.
|
# Load TFLite model and allocate tensors.
|
||||||
M_INTERPRETER = tflite.Interpreter(model_path=userDir + '/BirdNET-Pi/model/BirdNET_GLOBAL_3K_V2.2_MData_Model_FP16.tflite')
|
M_INTERPRETER = tflite.Interpreter(model_path=userDir + '/BirdNET-Pi/model/BirdNET_GLOBAL_3K_V2.3_MData_Model_FP16.tflite')
|
||||||
M_INTERPRETER.allocate_tensors()
|
M_INTERPRETER.allocate_tensors()
|
||||||
|
|
||||||
# Get input and output tensors.
|
# Get input and output tensors.
|
||||||
@@ -272,7 +272,7 @@ def analyzeAudioData(chunks, lat, lon, week, sensitivity, overlap,):
|
|||||||
start = time.time()
|
start = time.time()
|
||||||
print('ANALYZING AUDIO...', end=' ', flush=True)
|
print('ANALYZING AUDIO...', end=' ', flush=True)
|
||||||
|
|
||||||
if model == "BirdNET_GLOBAL_3K_V2.2_Model_FP16":
|
if model == "BirdNET_GLOBAL_3K_V2.3_Model_FP16":
|
||||||
if len(PREDICTED_SPECIES_LIST) == 0 or len(INCLUDE_LIST) != 0:
|
if len(PREDICTED_SPECIES_LIST) == 0 or len(INCLUDE_LIST) != 0:
|
||||||
predictSpeciesList(lat,lon,week)
|
predictSpeciesList(lat,lon,week)
|
||||||
|
|
||||||
@@ -584,7 +584,7 @@ def handle_client(conn, addr):
|
|||||||
post_commonName = "\"commonName\": \"" + entry[0].split('_')[1].split("/")[0] + "\","
|
post_commonName = "\"commonName\": \"" + entry[0].split('_')[1].split("/")[0] + "\","
|
||||||
post_scientificName = "\"scientificName\": \"" + entry[0].split('_')[0] + "\","
|
post_scientificName = "\"scientificName\": \"" + entry[0].split('_')[0] + "\","
|
||||||
|
|
||||||
if model == "BirdNET_GLOBAL_3K_V2.2_Model_FP16":
|
if model == "BirdNET_GLOBAL_3K_V2.3_Model_FP16":
|
||||||
post_algorithm = "\"algorithm\": " + "\"2p2\"" + ","
|
post_algorithm = "\"algorithm\": " + "\"2p2\"" + ","
|
||||||
else:
|
else:
|
||||||
post_algorithm = "\"algorithm\": " + "\"alpha\"" + ","
|
post_algorithm = "\"algorithm\": " + "\"alpha\"" + ","
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ def loadMetaModel():
|
|||||||
global CLASSES
|
global CLASSES
|
||||||
|
|
||||||
# Load TFLite model and allocate tensors.
|
# Load TFLite model and allocate tensors.
|
||||||
M_INTERPRETER = tflite.Interpreter(model_path=userDir + '/BirdNET-Pi/model/BirdNET_GLOBAL_3K_V2.2_MData_Model_FP16.tflite')
|
M_INTERPRETER = tflite.Interpreter(model_path=userDir + '/BirdNET-Pi/model/BirdNET_GLOBAL_3K_V2.3_MData_Model_FP16.tflite')
|
||||||
M_INTERPRETER.allocate_tensors()
|
M_INTERPRETER.allocate_tensors()
|
||||||
|
|
||||||
# Get input and output tensors.
|
# Get input and output tensors.
|
||||||
|
|||||||
+3
-2
@@ -142,7 +142,8 @@ tr:first-child td {
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<dialog id="attribution-dialog">
|
<dialog style="margin-top: 5px;max-height: 95vh;
|
||||||
|
overflow-y: auto;overscroll-behavior:contain" id="attribution-dialog">
|
||||||
<h1 id="modalHeading"></h1>
|
<h1 id="modalHeading"></h1>
|
||||||
<p id="modalText"></p>
|
<p id="modalText"></p>
|
||||||
<button onclick="hideDialog()">Close</button>
|
<button onclick="hideDialog()">Close</button>
|
||||||
@@ -162,7 +163,7 @@ function hideDialog() {
|
|||||||
|
|
||||||
function setModalText(iter, title, text, authorlink) {
|
function setModalText(iter, title, text, authorlink) {
|
||||||
document.getElementById('modalHeading').innerHTML = "Photo "+iter+": \""+title+"\" Attribution";
|
document.getElementById('modalHeading').innerHTML = "Photo "+iter+": \""+title+"\" Attribution";
|
||||||
document.getElementById('modalText').innerHTML = "Image link: <a target='_blank' href="+text+">"+text+"</a><br>Author link: <a target='_blank' href="+authorlink+">"+authorlink+"</a>";
|
document.getElementById('modalText').innerHTML = "<div style='white-space:nowrap'>Image link: <a target='_blank' href="+text+">"+text+"</a><br>Author link: <a target='_blank' href="+authorlink+">"+authorlink+"</a></div>";
|
||||||
showDialog();
|
showDialog();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -44,4 +44,12 @@ function update() {
|
|||||||
<form action="" method="GET">
|
<form action="" method="GET">
|
||||||
<button type="submit" name="submit" value="sudo clear_all_data.sh" onclick="return confirm('Clear ALL Data? Note that this cannot be undone and will take up to 90 seconds.')">Clear ALL data</button>
|
<button type="submit" name="submit" value="sudo clear_all_data.sh" onclick="return confirm('Clear ALL Data? Note that this cannot be undone and will take up to 90 seconds.')">Clear ALL data</button>
|
||||||
</form>
|
</form>
|
||||||
|
<?php
|
||||||
|
$cmd="cd ".$home."/BirdNET-Pi && sudo -u ".$user." git rev-list --max-count=1 HEAD";
|
||||||
|
$curr_hash = shell_exec($cmd);
|
||||||
|
?>
|
||||||
|
<p style="font-size:11px;text-align:center"></br></br>Running version: </p>
|
||||||
|
<a href="https://github.com/mcguirepr89/BirdNET-Pi/commit/<?php echo $curr_hash; ?>" target="_blank">
|
||||||
|
<p style="font-size:11px;text-align:center;box-sizing: border-box"><?php echo $curr_hash; ?></p>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -230,6 +230,7 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" ) {
|
|||||||
$comname = preg_replace('/ /', '_', $todaytable['Com_Name']);
|
$comname = preg_replace('/ /', '_', $todaytable['Com_Name']);
|
||||||
$comname = preg_replace('/\'/', '_', $comname);
|
$comname = preg_replace('/\'/', '_', $comname);
|
||||||
$filename = "/By_Date/".date('Y-m-d')."/".$comname."/".$todaytable['File_Name'];
|
$filename = "/By_Date/".date('Y-m-d')."/".$comname."/".$todaytable['File_Name'];
|
||||||
|
$filename_formatted = $todaytable['Date']."/".$comname."/".$todaytable['File_Name'];
|
||||||
$sciname = preg_replace('/ /', '_', $todaytable['Sci_Name']);
|
$sciname = preg_replace('/ /', '_', $todaytable['Sci_Name']);
|
||||||
$args = "&license=2%2C3%2C4%2C5%2C6%2C9&orientation=square,portrait";
|
$args = "&license=2%2C3%2C4%2C5%2C6%2C9&orientation=square,portrait";
|
||||||
$comnameprefix = "%20bird";
|
$comnameprefix = "%20bird";
|
||||||
@@ -308,7 +309,9 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" ) {
|
|||||||
?>
|
?>
|
||||||
<?php if(isset($_GET['display_limit']) && is_numeric($_GET['display_limit'])){ ?>
|
<?php if(isset($_GET['display_limit']) && is_numeric($_GET['display_limit'])){ ?>
|
||||||
<tr class="relative" id="<?php echo $iterations; ?>">
|
<tr class="relative" id="<?php echo $iterations; ?>">
|
||||||
<td class="relative"><a target="_blank" href="index.php?filename=<?php echo $todaytable['File_Name']; ?>"><img class="copyimage" title="Open in new tab" width=25 src="images/copy.png"></a>
|
<td class="relative">
|
||||||
|
<img style='cursor:pointer;right:45px' src='images/delete.svg' onclick='deleteDetection("<?php echo $filename_formatted; ?>")' class="copyimage" width=25 title='Delete Detection'>
|
||||||
|
<a target="_blank" href="index.php?filename=<?php echo $todaytable['File_Name']; ?>"><img class="copyimage" title="Open in new tab" width=25 src="images/copy.png"></a>
|
||||||
|
|
||||||
|
|
||||||
<div class="centered_image_container">
|
<div class="centered_image_container">
|
||||||
@@ -419,8 +422,8 @@ die();
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<div class="viewdb">
|
<div class="viewdb">
|
||||||
<dialog style="margin-top: 5px;max-height: 100vh;
|
<dialog style="margin-top: 5px;max-height: 95vh;
|
||||||
overflow-y: auto;" id="attribution-dialog">
|
overflow-y: auto;overscroll-behavior:contain" id="attribution-dialog">
|
||||||
<h1 id="modalHeading"></h1>
|
<h1 id="modalHeading"></h1>
|
||||||
<p id="modalText"></p>
|
<p id="modalText"></p>
|
||||||
<button style="font-weight:bold;color:blue" onclick="hideDialog()">Close</button>
|
<button style="font-weight:bold;color:blue" onclick="hideDialog()">Close</button>
|
||||||
@@ -431,6 +434,25 @@ die();
|
|||||||
<script src="static/chartjs-plugin-trendline.min.js"></script>
|
<script src="static/chartjs-plugin-trendline.min.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
function deleteDetection(filename,copylink=false) {
|
||||||
|
if (confirm("Are you sure you want to delete this detection from the database?") == true) {
|
||||||
|
const xhttp = new XMLHttpRequest();
|
||||||
|
xhttp.onload = function() {
|
||||||
|
if(this.responseText == "OK"){
|
||||||
|
if(copylink == true) {
|
||||||
|
window.top.close();
|
||||||
|
} else {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert("Database busy.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhttp.open("GET", "play.php?deletefile="+filename, true);
|
||||||
|
xhttp.send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var last_photo_link;
|
var last_photo_link;
|
||||||
var dialog = document.querySelector('dialog');
|
var dialog = document.querySelector('dialog');
|
||||||
dialogPolyfill.registerDialog(dialog);
|
dialogPolyfill.registerDialog(dialog);
|
||||||
@@ -461,9 +483,9 @@ die();
|
|||||||
function setModalText(iter, title, text, authorlink, photolink, licenseurl) {
|
function setModalText(iter, title, text, authorlink, photolink, licenseurl) {
|
||||||
document.getElementById('modalHeading').innerHTML = "Photo: \""+decodeURIComponent(title.replaceAll("+"," "))+"\" Attribution";
|
document.getElementById('modalHeading').innerHTML = "Photo: \""+decodeURIComponent(title.replaceAll("+"," "))+"\" Attribution";
|
||||||
<?php if($kiosk == false) { ?>
|
<?php if($kiosk == false) { ?>
|
||||||
document.getElementById('modalText').innerHTML = "<div><img style='border-radius:5px;max-height: calc(100vh - 15rem);display: block;margin: 0 auto;' src='"+photolink+"'></div><br><div>Image link: <a target='_blank' href="+text+">"+text+"</a><br>Author link: <a target='_blank' href="+authorlink+">"+authorlink+"</a><br>License URL: <a href="+licenseurl+" target='_blank'>"+licenseurl+"</a></div>";
|
document.getElementById('modalText').innerHTML = "<div><img style='border-radius:5px;max-height: calc(100vh - 15rem);display: block;margin: 0 auto;' src='"+photolink+"'></div><br><div style='white-space:nowrap'>Image link: <a target='_blank' href="+text+">"+text+"</a><br>Author link: <a target='_blank' href="+authorlink+">"+authorlink+"</a><br>License URL: <a href="+licenseurl+" target='_blank'>"+licenseurl+"</a></div>";
|
||||||
<?php } else { ?>
|
<?php } else { ?>
|
||||||
document.getElementById('modalText').innerHTML = "<div><img style='border-radius:5px;max-height: calc(100vh - 15rem);display: block;margin: 0 auto;' src='"+photolink+"'></div><br><div>Image link: <a target='_blank'>"+text+"</a><br>Author link: <a target='_blank'>"+authorlink+"</a><br>License URL: <a target='_blank'>"+licenseurl+"</a></div>";
|
document.getElementById('modalText').innerHTML = "<div><img style='border-radius:5px;max-height: calc(100vh - 15rem);display: block;margin: 0 auto;' src='"+photolink+"'></div><br><div style='white-space:nowrap'>Image link: <a target='_blank'>"+text+"</a><br>Author link: <a target='_blank'>"+authorlink+"</a><br>License URL: <a target='_blank'>"+licenseurl+"</a></div>";
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
last_photo_link = text;
|
last_photo_link = text;
|
||||||
showDialog();
|
showDialog();
|
||||||
@@ -570,7 +592,9 @@ function searchDetections(searchvalue) {
|
|||||||
function loadDetections(detections_limit, element=undefined) {
|
function loadDetections(detections_limit, element=undefined) {
|
||||||
const xhttp = new XMLHttpRequest();
|
const xhttp = new XMLHttpRequest();
|
||||||
xhttp.onload = function() {
|
xhttp.onload = function() {
|
||||||
|
<?php if($kiosk == false) { ?>
|
||||||
document.getElementsByClassName("legacyview")[0].style.display="unset";
|
document.getElementsByClassName("legacyview")[0].style.display="unset";
|
||||||
|
<?php } ?>
|
||||||
if(typeof element !== "undefined")
|
if(typeof element !== "undefined")
|
||||||
{
|
{
|
||||||
element.remove();
|
element.remove();
|
||||||
|
|||||||
@@ -190,6 +190,9 @@ fi
|
|||||||
if ! grep APPRISE_ONLY_NOTIFY_SPECIES_NAMES /etc/birdnet/birdnet.conf &>/dev/null;then
|
if ! grep APPRISE_ONLY_NOTIFY_SPECIES_NAMES /etc/birdnet/birdnet.conf &>/dev/null;then
|
||||||
sudo -u$USER echo "APPRISE_ONLY_NOTIFY_SPECIES_NAMES=\"\"" >> /etc/birdnet/birdnet.conf
|
sudo -u$USER echo "APPRISE_ONLY_NOTIFY_SPECIES_NAMES=\"\"" >> /etc/birdnet/birdnet.conf
|
||||||
fi
|
fi
|
||||||
|
if ! grep APPRISE_ONLY_NOTIFY_SPECIES_NAMES_2 /etc/birdnet/birdnet.conf &>/dev/null;then
|
||||||
|
sudo -u$USER echo "APPRISE_ONLY_NOTIFY_SPECIES_NAMES_2=\"\"" >> /etc/birdnet/birdnet.conf
|
||||||
|
fi
|
||||||
|
|
||||||
if ! grep RTSP_STREAM_TO_LIVESTREAM /etc/birdnet/birdnet.conf &>/dev/null;then
|
if ! grep RTSP_STREAM_TO_LIVESTREAM /etc/birdnet/birdnet.conf &>/dev/null;then
|
||||||
sudo -u$USER echo "RTSP_STREAM_TO_LIVESTREAM=\"0\"" >> /etc/birdnet/birdnet.conf
|
sudo -u$USER echo "RTSP_STREAM_TO_LIVESTREAM=\"0\"" >> /etc/birdnet/birdnet.conf
|
||||||
@@ -214,5 +217,15 @@ if ! grep LogLevel_SpectrogramViewerService /etc/birdnet/birdnet.conf &>/dev/nul
|
|||||||
sudo -u$USER echo "LogLevel_SpectrogramViewerService=\"error\"" >> /etc/birdnet/birdnet.conf
|
sudo -u$USER echo "LogLevel_SpectrogramViewerService=\"error\"" >> /etc/birdnet/birdnet.conf
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if grep -q '^MODEL=BirdNET_GLOBAL_3K_V2.2_Model_FP16$' /etc/birdnet/birdnet.conf;then
|
||||||
|
language=$(grep "^DATABASE_LANG=" /etc/birdnet/birdnet.conf | cut -d= -f2)
|
||||||
|
sed -i 's/BirdNET_GLOBAL_3K_V2.2_Model_FP16/BirdNET_GLOBAL_3K_V2.3_Model_FP16/' /etc/birdnet/birdnet.conf
|
||||||
|
sed -i 's/BirdNET_GLOBAL_3K_V2.2_Model_FP16/BirdNET_GLOBAL_3K_V2.3_Model_FP16/' $HOME/BirdNET-Pi/scripts/thisrun.txt
|
||||||
|
sed -i 's/BirdNET_GLOBAL_3K_V2.2_Model_FP16/BirdNET_GLOBAL_3K_V2.3_Model_FP16/' $HOME/BirdNET-Pi/birdnet.conf
|
||||||
|
cp -f $HOME/BirdNET-Pi/model/labels.txt $HOME/BirdNET-Pi/model/labels.txt.old
|
||||||
|
sudo chmod +x $HOME/BirdNET-Pi/scripts/install_language_label_nm.sh && $HOME/BirdNET-Pi/scripts/install_language_label_nm.sh -l "$language"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
sudo systemctl daemon-reload
|
sudo systemctl daemon-reload
|
||||||
restart_services.sh
|
restart_services.sh
|
||||||
|
|||||||
@@ -52,6 +52,11 @@ def sendAppriseNotifications(species, confidence, path, date, time, week, latitu
|
|||||||
if any(bird.lower().replace(" ", "") in comName.lower().replace(" ", "") for bird in APPRISE_ONLY_NOTIFY_SPECIES_NAMES.split(",")):
|
if any(bird.lower().replace(" ", "") in comName.lower().replace(" ", "") for bird in APPRISE_ONLY_NOTIFY_SPECIES_NAMES.split(",")):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
APPRISE_ONLY_NOTIFY_SPECIES_NAMES_2 = settings_dict.get('APPRISE_ONLY_NOTIFY_SPECIES_NAMES_2')
|
||||||
|
if APPRISE_ONLY_NOTIFY_SPECIES_NAMES_2 is not None and APPRISE_ONLY_NOTIFY_SPECIES_NAMES_2.strip() != "":
|
||||||
|
if not any(bird.lower().replace(" ", "") in comName.lower().replace(" ", "") for bird in APPRISE_ONLY_NOTIFY_SPECIES_NAMES_2.split(",")):
|
||||||
|
return
|
||||||
|
|
||||||
APPRISE_MINIMUM_SECONDS_BETWEEN_NOTIFICATIONS_PER_SPECIES = settings_dict.get('APPRISE_MINIMUM_SECONDS_BETWEEN_NOTIFICATIONS_PER_SPECIES')
|
APPRISE_MINIMUM_SECONDS_BETWEEN_NOTIFICATIONS_PER_SPECIES = settings_dict.get('APPRISE_MINIMUM_SECONDS_BETWEEN_NOTIFICATIONS_PER_SPECIES')
|
||||||
if APPRISE_MINIMUM_SECONDS_BETWEEN_NOTIFICATIONS_PER_SPECIES != "0":
|
if APPRISE_MINIMUM_SECONDS_BETWEEN_NOTIFICATIONS_PER_SPECIES != "0":
|
||||||
if species_last_notified.get(comName) is not None:
|
if species_last_notified.get(comName) is not None:
|
||||||
|
|||||||
Reference in New Issue
Block a user