BirdNET-Pi icon indicating copy to clipboard operation
BirdNET-Pi copied to clipboard

Trigger a script when a certain bird is heard

Open Blinko1987 opened this issue 2 years ago • 3 comments

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"

Blinko1987 avatar Aug 17 '23 06:08 Blinko1987

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");

ehpersonal38 avatar Aug 19 '23 02:08 ehpersonal38

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"}

deepcoder avatar Aug 19 '23 05:08 deepcoder

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")```

Blinko1987 avatar Aug 19 '23 06:08 Blinko1987