Trigger a script when a certain bird is heard
I would like to set up BirdNET-Pi to trigger a script that turns on a laser and moves it around a tree. I have an Asian Koel that is driving me insane here in Thailand. He won't leave his favorite tree outside my window unless I get up at 4AM and point this 5W laser at him. Can anyone familiar with the code point me in the right direction to get a custom script triggered when this one specific bird is heard? All it does is turn on the laser and move it around a bit for 60 seconds. Hopefully this will train him to stay out of this tree and move on. If you don't know the Asian Koel, google "most annoying bird in the world"
In server.py around line 519 , you can do a check like (this is pseudocode)
if Com_Name == "Asian Koel": exec("my_laser_script.sh");
If you modify files in the BirdNET-Pi system, you run the risk that an update to the system will overwrite your changes.
In the link below, I created a small python program that is pretty much outside of BirdNET-Pi, so only a rather major update to the system will cause you to lose your code. The program is dependent on the format of the entries in the syslog file, so if that were to change then you would need to update the program. This example program creates MQTT records for each identified bird, however you can have the code do anything your like once it parses out the fields. I found the Aprise output a bit hard to work with, which is the reason for this code, the JSON fields generated are more consistent. Good hunting ;-) :
https://gist.github.com/deepcoder/c309087c456fc733435b47d83f4113ff
JSON that is generated:
{"ts": "1687047081.0", "sciname": "Baeolophus inornatus", "comname": "Oak Titmouse", "confidence": "0.7201002", "url": "http://en.wikipedia.org/wiki/Baeolophus_inornatus"}
This is what i'm using right now with birdnetlib. It works but I wish it would analyze in real time like birdnet-pi does.
from birdnetlib.analyzer import Analyzer
from datetime import datetime
import sounddevice as sd
from scipy.io import wavfile
import tempfile
import os
import subprocess
# Load and initialize the BirdNET-Analyzer models.
analyzer = Analyzer()
# Define the parameters for recording
sampling_rate = 44100 # Sampling rate in Hz
duration = 10 # Recording duration in seconds
# Define the path to your custom script
custom_script_path = os.path.join(os.path.dirname(__file__), "custom_script.py")
while True:
print("Recording for 10 seconds...")
recording = sd.rec(int(sampling_rate * duration), samplerate=sampling_rate, channels=2)
sd.wait() # Wait for recording to finish
print("Recording finished. Analyzing...")
# Save the recorded audio as a temporary WAV file
temp_dir = tempfile.mkdtemp()
temp_file_path = os.path.join(temp_dir, "temp_recording.wav")
wavfile.write(temp_file_path, sampling_rate, recording)
recording = Recording(
analyzer,
temp_file_path,
lat=30.4244,
lon=100.7463,
date=datetime(year=2023, month=8, day=18), # use date or week_48
min_conf=0.25,
)
recording.analyze()
print("Analysis results:")
with open("birds.txt", "a") as results_file:
for detection in recording.detections:
common_name = detection['common_name']
confidence = detection['confidence']
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") # Current date and time
results_file.write(f"Timestamp: {timestamp}, Species: {common_name}, Confidence: {confidence}\n")
if common_name == "Asian Koel":
print("Executing custom script...")
subprocess.run(["python", custom_script_path])
print("\nAnalysis results saved to 'birds.txt'. Waiting for the next recording...\n")```