sndid/sndid-server.py

169 lines
4.5 KiB
Python

#!/usr/bin/env python
"""
sndid-server
Copyright 2022, 2023, Joe Weiss <joe.weiss@gmail.com>
Copyright 2023, Jeff Moe <moe@spacecruft.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
https://github.com/joeweiss/birdnetlib/blob/main/examples/simple_tcp_server.py
"""
from birdnetlib import RecordingBuffer
from birdnetlib.analyzer import Analyzer
import birdnetlib.wavutils as wavutils
import datetime
import socketserver
import argparse
from contextlib import redirect_stdout, redirect_stderr
import io
import logging
TODAY = datetime.date.today()
YEAR = TODAY.year
MONTH = TODAY.month
DAY = TODAY.day
logging.basicConfig(
filename="sndid.log", encoding="utf-8", format="%(message)s", level=logging.DEBUG
)
parser = argparse.ArgumentParser(description="Run sndid-server")
parser.add_argument(
"-i",
"--ip",
help="Server IP address (default 127.0.0.1)",
type=str,
required=False,
default="127.0.0.1",
)
parser.add_argument(
"-p",
"--port",
help="Server network port (default 9988)",
type=int,
required=False,
default="9988",
)
parser.add_argument(
"-t",
"--latitude",
help="Latitude (default 40.57)",
type=str,
required=False,
default="40.57",
)
parser.add_argument(
"-n",
"--longitude",
help="Longitude (default -105.23)",
type=str,
required=False,
default="-105.23",
)
parser.add_argument(
"-y",
"--year",
help="Year (default today)",
type=int,
required=False,
default=YEAR,
)
parser.add_argument(
"-m",
"--month",
help="Month (default today)",
type=int,
required=False,
default=MONTH,
)
parser.add_argument(
"-d",
"--day",
help="Day (default today)",
type=int,
required=False,
default=DAY,
)
parser.add_argument(
"-c",
"--confidence",
help="Minimum Confidence (default 0.25)",
type=float,
required=False,
default="0.25",
)
args = parser.parse_args()
LAT = args.latitude
LON = args.longitude
IP = args.ip
PORT = args.port
YEAR = args.year
MONTH = args.month
DAY = args.day
CONFIDENCE = args.confidence
f = io.StringIO()
class TCPHandler(socketserver.StreamRequestHandler):
def handle(self):
with redirect_stdout(f), redirect_stderr(f):
analyzer = Analyzer()
# Read WAV data from the socket
for rate, data in wavutils.bufferwavs(self.rfile):
with redirect_stdout(f), redirect_stderr(f):
# Make a RecordingBuffer with buffer and rate
recording = RecordingBuffer(
analyzer,
data,
rate,
lat=LAT,
lon=LON,
date=datetime.datetime(year=YEAR, month=MONTH, day=DAY),
min_conf=CONFIDENCE,
)
with redirect_stdout(f), redirect_stderr(f):
recording.analyze()
i = 0
detections_sort = ""
for i in range(0, len(recording.detections)):
detections_sort = detections_sort + (
recording.detections[i]["common_name"]
+ ", "
+ recording.detections[i]["scientific_name"]
+ ", "
+ str(recording.detections[i]["confidence"])
+ "\n"
)
detections_out = sorted(detections_sort.split("\n"))
i = 0
for i in range(1, len(detections_out)):
n = datetime.datetime.now(datetime.timezone.utc).astimezone()
print(n, detections_out[i])
logging.info(str(n) + " " + str(detections_out[i]))
if __name__ == "__main__":
try:
with socketserver.TCPServer((IP, PORT), TCPHandler) as server:
n = datetime.datetime.now(datetime.timezone.utc).astimezone()
print(n, "sndid-server started " + IP + ":" + str(PORT))
logging.info(str(n) + " sndid-server started " + IP + ":" + str(PORT))
server.serve_forever()
except KeyboardInterrupt:
server.server_close()