Clean and add new monitoring service

This commit is contained in:
Alexandre
2024-10-07 15:27:23 +02:00
committed by GitHub
parent 03f30ad353
commit 7f50d30822
3 changed files with 56 additions and 200 deletions

View File

@@ -2,90 +2,89 @@
# shellcheck shell=bash # shellcheck shell=bash
echo "Starting service: throttlerecording" echo "Starting service: throttlerecording"
touch "$HOME"/BirdSongs/StreamData/analyzing_now.txt touch "$HOME/BirdSongs/StreamData/analyzing_now.txt"
# variables for readability # Read configuration
srv="birdnet_recording"
analyzing_now="."
counter=10
set +u
# shellcheck disable=SC1091
source /config/birdnet.conf 2>/dev/null source /config/birdnet.conf 2>/dev/null
# Ensure folder exists # Set constants
srv="birdnet_recording"
srv2="birdnet_analysis"
ingest_dir="$RECS_DIR/StreamData" ingest_dir="$RECS_DIR/StreamData"
counter=10
# Check permissions # Ensure directories and permissions
mkdir -p "$ingest_dir"
chown -R pi:pi "$ingest_dir"
chmod -R 755 "$ingest_dir"
ingest_dir="$(readlink -f "$ingest_dir")" || true
mkdir -p "$ingest_dir" mkdir -p "$ingest_dir"
chown -R pi:pi "$ingest_dir" chown -R pi:pi "$ingest_dir"
chmod -R 755 "$ingest_dir" chmod -R 755 "$ingest_dir"
function apprisealert() { # Function to send notifications using Apprise
# Set failed check so it only runs once apprisealert() {
touch "$HOME"/BirdNET-Pi/failed_servicescheck local notification=""
NOTIFICATION="" local stopped_service="<br><b>Stopped services:</b> "
STOPPEDSERVICE="<br><b>Stopped services:</b> "
services=(birdnet_analysis # Check for stopped services
chart_viewer services=(birdnet_analysis chart_viewer spectrogram_viewer icecast2 birdnet_recording birdnet_log birdnet_stats)
spectrogram_viewer for service in "${services[@]}"; do
icecast2 if [[ "$(systemctl is-active "$service")" == "inactive" ]]; then
birdnet_recording stopped_service+="$service; "
birdnet_log
birdnet_stats)
for i in "${services[@]}"; do
if [[ "$(sudo systemctl is-active "${i}".service)" == "inactive" ]]; then
STOPPEDSERVICE+="${i}; "
fi fi
done done
NOTIFICATION+="$STOPPEDSERVICE"
NOTIFICATION+="<br><b>Additional informations</b>: " # Build notification message
NOTIFICATION+="<br><b>Since:</b> ${LASTCHECK:-unknown}" notification+="$stopped_service"
NOTIFICATION+="<br><b>System:</b> ${SITE_NAME:-$(hostname)}" notification+="<br><b>Additional information</b>: "
NOTIFICATION+="<br>Available disk space: $(df -h "$(readlink -f "$HOME/BirdSongs")" | awk 'NR==2 {print $4}')" notification+="<br><b>Since:</b> ${LASTCHECK:-unknown}"
if [ -n "$BIRDNETPI_URL" ]; then notification+="<br><b>System:</b> ${SITE_NAME:-$(hostname)}"
NOTIFICATION+="<br> <a href=\"$BIRDNETPI_URL\">Access your BirdNET-Pi</a>" notification+="<br>Available disk space: $(df -h "$HOME/BirdSongs" | awk 'NR==2 {print $4}')"
fi [[ -n "$BIRDNETPI_URL" ]] && notification+="<br><a href=\"$BIRDNETPI_URL\">Access your BirdNET-Pi</a>"
# Send notification
TITLE="BirdNET-Analyzer stopped" TITLE="BirdNET-Analyzer stopped"
"$HOME"/BirdNET-Pi/birdnet/bin/apprise -vv -t "$TITLE" -b "${NOTIFICATION}" --input-format=html --config="$HOME/BirdNET-Pi/apprise.txt" "$HOME/BirdNET-Pi/birdnet/bin/apprise" -vv -t "$TITLE" -b "$notification" --input-format=html --config="$HOME/BirdNET-Pi/apprise.txt"
} }
# Main loop
while true; do while true; do
sleep 61 sleep 61
# Restart analysis if clogged # Restart analysis if clogged
############################
if ((counter <= 0)); then if ((counter <= 0)); then
latest="$(cat "$ingest_dir"/analyzing_now.txt)" current_file="$(cat "$ingest_dir/analyzing_now.txt")"
if [[ "$latest" == "$analyzing_now" ]]; then if [[ "$current_file" == "$analyzing_now" ]]; then
echo "$(date) WARNING no change in analyzing_now for 10 iterations, restarting services" echo "$(date) WARNING no change in analyzing_now for 10 iterations, restarting services"
/."$HOME"/BirdNET-Pi/scripts/restart_services.sh "$HOME/BirdNET-Pi/scripts/restart_services.sh"
fi fi
counter=10 counter=10
analyzing_now=$(cat "$ingest_dir"/analyzing_now.txt) analyzing_now="$current_file"
fi fi
# Pause recorder to catch-up # Check recorder state and queue length
############################ wav_count=$(find "$ingest_dir" -maxdepth 1 -name '*.wav' | wc -l)
service_state=$(systemctl is-active "$srv")
analysis_state=$(systemctl is-active "$srv2")
wavs="$(find "$ingest_dir" -maxdepth 1 -name '*.wav' | wc -l)" bashio::log.green "$(date) INFO: $wav_count wav files waiting in $ingest_dir, $srv state is $service_state, $srv2 state is $analysis_state"
state="$(systemctl is-active "$srv")"
bashio::log.green "$(date) INFO ${wavs} wav files waiting in $ingest_dir, $srv state is $state" # Pause recorder if queue is too large
if ((wav_count > 50)); then
if ((wavs > 100)); then bashio::log.red "$(date) WARNING: Too many files in queue, pausing $srv and restarting $srv2"
bashio::log.red "$(date) WARNING too many files in queue, pausing $srv"
sudo systemctl stop "$srv" sudo systemctl stop "$srv"
sudo systemctl restart birdnet_analysis sudo systemctl restart "$srv2"
if [ -s "$HOME/BirdNET-Pi/apprise.txt" ]; then apprisealert; fi [[ -s "$HOME/BirdNET-Pi/apprise.txt" ]] && apprisealert
elif [[ "$state" != "active" ]]; then elif ((wav_count > 30)); then
bashio::log.yellow "$(date) INFO started $srv service" bashio::log.red "$(date) WARNING: Too many files in queue, restarting $srv2"
sudo systemctl start $srv sudo systemctl restart "$srv2"
sudo systemctl restart birdnet_analysis [[ -s "$HOME/BirdNET-Pi/apprise.txt" ]] && apprisealert
else
if [[ "$service_state" != "active" ]]; then
bashio::log.yellow "$(date) INFO: Restarting $srv service"
sudo systemctl restart "$srv"
fi
if [[ "$analysis_state" != "active" ]]; then
bashio::log.yellow "$(date) INFO: Restarting $srv2 service"
sudo systemctl restart "$srv2"
fi
fi fi
((counter--)) ((counter--))

View File

@@ -1,116 +0,0 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
</style>
<p><strong>This tool will allow to convert on-the-fly species to compensate for model errors. It SHOULD NOT BE USED except if you know what you are doing, instead the model errors should be reported to the owner. However, it is still convenient for systematic biases that are confirmed through careful listening of samples, while waiting for the models to be updated.</strong></p>
<div class="customlabels column1">
<form action="" method="GET" id="add">
<input type="hidden" id="species" name="species">
<h3>Specie to convert from :</h3>
<!-- Input box to filter options in the first table -->
<input type="text" id="species1Search" onkeyup="filterOptions('species1')" placeholder="Search for species...">
<select name="species1" id="species1" size="25">
<?php
error_reporting(E_ALL);
ini_set('display_errors',1);
$filename = './scripts/labels.txt';
$eachline = file($filename, FILE_IGNORE_NEW_LINES);
foreach($eachline as $lines){echo
"<option value=\"".$lines."\">$lines</option>";}
?>
</select>
<br><br> <!-- Added a space between the two tables -->
<h3>Specie to convert to :</h3>
<!-- Input box to filter options in the second table -->
<input type="text" id="species2Search" onkeyup="filterOptions('species2')" placeholder="Search for species...">
<select name="species2" id="species2" size="25">
<?php
foreach($eachline as $lines){echo
"<option value=\"".$lines."\">$lines</option>";}
?>
</select>
<input type="hidden" name="add" value="add">
</form>
<div class="customlabels smaller">
<button type="submit" name="view" value="Converted" form="add">>>ADD>></button>
</div>
</div>
<div class="customlabels column2">
<table><td>
<button type="submit" name="view" value="Converted" form="add">>>ADD>></button>
<br><br>
<button type="submit" name="view" value="Converted" form="del">REMOVE</button>
</td></table>
</div>
<div class="customlabels column3" style="margin-top: 0;"> <!-- Removed the blank space above the table -->
<form action="" method="GET" id="del">
<h3>Converted Species List</h3>
<select name="species[]" id="value2" multiple size="25">
<?php
$filename = './scripts/convert_species_list.txt'; // Changed the file path
$eachline = file($filename, FILE_IGNORE_NEW_LINES);
foreach($eachline as $lines){
echo
"<option value=\"".$lines."\">$lines</option>";
}?>
</select>
<input type="hidden" name="del" value="del">
</form>
<div class="customlabels smaller">
<button type="submit" name="view" value="Converted" form="del">REMOVE</button>
</div>
</div>
<input type="hidden" id="hiddenSpecies" name="hiddenSpecies">
<script>
document.getElementById("add").addEventListener("submit", function(event) {
var speciesSelect1 = document.getElementById("species1");
var speciesSelect2 = document.getElementById("species2");
if (speciesSelect1.selectedIndex < 0 || speciesSelect2.selectedIndex < 0) {
alert("Please select a species from both lists.");
document.querySelector('.views').style.opacity = 1;
event.preventDefault();
} else {
var selectedSpecies1 = speciesSelect1.options[speciesSelect1.selectedIndex].value;
var selectedSpecies2 = speciesSelect2.options[speciesSelect2.selectedIndex].value;
document.getElementById("species").value = selectedSpecies1 + ";" + selectedSpecies2;
}
});
// Store the original list of options in a variable
var originalOptions = {};
// Function to filter options in a select element
function filterOptions(id) {
var input = document.getElementById(id + "Search");
var filter = input.value.toUpperCase();
var select = document.getElementById(id);
var options = select.getElementsByTagName("option");
// If the original list of options for this select element hasn't been stored yet, store it
if (!originalOptions[id]) {
originalOptions[id] = Array.from(options).map(option => option.value);
}
// Clear the select element
while (select.firstChild) {
select.removeChild(select.firstChild);
}
// Populate the select element with the filtered labels
originalOptions[id].forEach(label => {
if (label.toUpperCase().indexOf(filter) > -1) {
let option = document.createElement('option');
option.value = label;
option.text = label;
select.appendChild(option);
}
});
}
</script>

View File

@@ -1,27 +0,0 @@
if($_GET['view'] == "Converted"){
ensure_authenticated();
if(isset($_GET['species']) && isset($_GET['add'])){
$file = './scripts/convert_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");
// Write $_GET['species'] to the file
file_put_contents("./scripts/convert_species_list.txt", htmlspecialchars_decode($_GET['species'], ENT_QUOTES)."\n", FILE_APPEND);
} elseif (isset($_GET['species']) && isset($_GET['del'])){
$file = './scripts/convert_species_list.txt';
$str = file_get_contents("$file");
$str = preg_replace('/^\h*\v+/m', '', $str);
file_put_contents("$file", "$str");
foreach($_GET['species'] as $selectedOption) {
$content = file_get_contents("./scripts/convert_species_list.txt");
$newcontent = str_replace($selectedOption, "", "$content");
$newcontent = str_replace(htmlspecialchars_decode($selectedOption, ENT_QUOTES), "", "$content");
file_put_contents("./scripts/convert_species_list.txt", "$newcontent");
}
$file = './scripts/convert_species_list.txt';
$str = file_get_contents("$file");
$str = preg_replace('/^\h*\v+/m', '', $str);
file_put_contents("$file", "$str");
}
include('./scripts/convert_list.php');
}