Updating script/privacy_server.py to satisfy pep8 style guide

Used 'autopep8 --in-place --aggressive scripts/privacy_server.py' as initial style fixes.
This commit is contained in:
Jake Herbst
2022-05-11 08:05:54 -04:00
parent f81b2c3014
commit 5f5c320e61
+170 -83
View File
@@ -1,3 +1,18 @@
from pathlib import Path
from tzlocal import get_localzone
import pytz
from time import sleep
import datetime
import sqlite3
import requests
import json
from decimal import Decimal
import time
import math
import numpy as np
import librosa
import operator
import argparse
import socket import socket
import threading import threading
import os import os
@@ -6,25 +21,9 @@ os.environ['CUDA_VISIBLE_DEVICES'] = ''
try: try:
import tflite_runtime.interpreter as tflite import tflite_runtime.interpreter as tflite
except: except BaseException:
from tensorflow import lite as tflite from tensorflow import lite as tflite
import argparse
import operator
import librosa
import numpy as np
import math
import time
from decimal import Decimal
import json
import requests
import sqlite3
import datetime
from time import sleep
import pytz
from tzlocal import get_localzone
from pathlib import Path
HEADER = 64 HEADER = 64
PORT = 5050 PORT = 5050
@@ -36,17 +35,18 @@ DISCONNECT_MESSAGE = "!DISCONNECT"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try: try:
server.bind(ADDR) server.bind(ADDR)
except: except BaseException:
print("Waiting on socket") print("Waiting on socket")
time.sleep(5) time.sleep(5)
# Open most recent Configuration and grab DB_PWD as a python variable # Open most recent Configuration and grab DB_PWD as a python variable
userDir = os.path.expanduser('~') userDir = os.path.expanduser('~')
with open(userDir + '/BirdNET-Pi/scripts/thisrun.txt', 'r') as f: with open(userDir + '/BirdNET-Pi/scripts/thisrun.txt', 'r') as f:
this_run = f.readlines() this_run = f.readlines()
audiofmt = "." + str(str(str([i for i in this_run if i.startswith('AUDIOFMT')]).split('=')[1]).split('\\')[0]) audiofmt = "." + \
str(str(str([i for i in this_run if i.startswith(
'AUDIOFMT')]).split('=')[1]).split('\\')[0])
def loadModel(): def loadModel():
@@ -60,7 +60,7 @@ def loadModel():
# Load TFLite model and allocate tensors. # Load TFLite model and allocate tensors.
modelpath = userDir + '/BirdNET-Pi/model/BirdNET_6K_GLOBAL_MODEL.tflite' modelpath = userDir + '/BirdNET-Pi/model/BirdNET_6K_GLOBAL_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()
# Get input and output tensors. # Get input and output tensors.
@@ -82,6 +82,7 @@ def loadModel():
return myinterpreter return myinterpreter
def loadCustomSpeciesList(path): def loadCustomSpeciesList(path):
slist = [] slist = []
@@ -92,6 +93,7 @@ def loadCustomSpeciesList(path):
return slist return slist
def splitSignal(sig, rate, overlap, seconds=3.0, minlen=1.5): def splitSignal(sig, rate, overlap, seconds=3.0, minlen=1.5):
# Split signal with overlap # Split signal with overlap
@@ -113,12 +115,14 @@ def splitSignal(sig, rate, overlap, seconds=3.0, minlen=1.5):
return sig_splits return sig_splits
def readAudioData(path, overlap, sample_rate=48000): def readAudioData(path, overlap, sample_rate=48000):
print('READING AUDIO DATA...', end=' ', flush=True) print('READING AUDIO DATA...', end=' ', flush=True)
# Open file with librosa (uses ffmpeg or libav) # Open file with librosa (uses ffmpeg or libav)
sig, rate = librosa.load(path, sr=sample_rate, mono=True, res_type='kaiser_fast') sig, rate = librosa.load(
path, sr=sample_rate, mono=True, res_type='kaiser_fast')
# Split audio into 3-second chunks # Split audio into 3-second chunks
chunks = splitSignal(sig, rate, overlap) chunks = splitSignal(sig, rate, overlap)
@@ -127,6 +131,7 @@ def readAudioData(path, overlap, sample_rate=48000):
return chunks return chunks
def convertMetadata(m): def convertMetadata(m):
# Convert week to cosine # Convert week to cosine
@@ -144,14 +149,20 @@ def convertMetadata(m):
return np.concatenate([m, mask]) return np.concatenate([m, mask])
def custom_sigmoid(x, sensitivity=1.0): def custom_sigmoid(x, sensitivity=1.0):
return 1 / (1.0 + np.exp(-sensitivity * x)) return 1 / (1.0 + np.exp(-sensitivity * x))
def predict(sample, sensitivity): def predict(sample, sensitivity):
global INTERPRETER global INTERPRETER
# Make a prediction # Make a prediction
INTERPRETER.set_tensor(INPUT_LAYER_INDEX, np.array(sample[0], dtype='float32')) INTERPRETER.set_tensor(
INTERPRETER.set_tensor(MDATA_INPUT_INDEX, np.array(sample[1], dtype='float32')) INPUT_LAYER_INDEX, np.array(
sample[0], dtype='float32'))
INTERPRETER.set_tensor(
MDATA_INPUT_INDEX, np.array(
sample[1], dtype='float32'))
INTERPRETER.invoke() INTERPRETER.invoke()
prediction = INTERPRETER.get_tensor(OUTPUT_LAYER_INDEX)[0] prediction = INTERPRETER.get_tensor(OUTPUT_LAYER_INDEX)[0]
@@ -162,26 +173,32 @@ def predict(sample, sensitivity):
p_labels = dict(zip(CLASSES, p_sigmoid)) p_labels = dict(zip(CLASSES, p_sigmoid))
# Sort by score # Sort by score
p_sorted = sorted(p_labels.items(), key=operator.itemgetter(1), reverse=True) p_sorted = sorted(
p_labels.items(),
key=operator.itemgetter(1),
reverse=True)
# Remove species that are on blacklist # Remove species that are on blacklist
for i in range(min(10, len(p_sorted))): for i in range(min(10, len(p_sorted))):
if p_sorted[i][0] in ['Non-bird_Non-bird', 'Noise_Noise']: if p_sorted[i][0] in ['Non-bird_Non-bird', 'Noise_Noise']:
p_sorted[i] = (p_sorted[i][0], 0.0) p_sorted[i] = (p_sorted[i][0], 0.0)
if p_sorted[i][0]=='Human_Human': if p_sorted[i][0] == 'Human_Human':
print("HUMAN SCORE:",str(p_sorted[i])) print("HUMAN SCORE:", str(p_sorted[i]))
HUMAN_FLAG=True HUMAN_FLAG = True
with open(userDir + '/BirdNET-Pi/HUMAN.txt', 'a') as rfile: with open(userDir + '/BirdNET-Pi/HUMAN.txt', 'a') as rfile:
rfile.write(str(datetime.datetime.now())+str(p_sorted[i])+ '\n') rfile.write(str(datetime.datetime.now()) +
str(p_sorted[i]) + '\n')
# date_stamp=datetime.datetime.now().strftime("%d_%m_%y_%H:%M:%S") # date_stamp=datetime.datetime.now().strftime("%d_%m_%y_%H:%M:%S")
# #
# sf.write('./home/*/human_sample.wav',np.random.randn(10,2) , 44100) #sample[0] # sf.write('./home/*/human_sample.wav',np.random.randn(10,2) , 44100)
# #sample[0]
# Only return first the top ten results # Only return first the top ten results
#INCREASE THIS TO SEE IF HUMAN IS DETECTED MORE RELIABLY # INCREASE THIS TO SEE IF HUMAN IS DETECTED MORE RELIABLY
# print('P_SORTED-------', p_sorted) # print('P_SORTED-------', p_sorted)
return p_sorted[:100] return p_sorted[:100]
def analyzeAudioData(chunks, lat, lon, week, sensitivity, overlap,): def analyzeAudioData(chunks, lat, lon, week, sensitivity, overlap,):
global INTERPRETER global INTERPRETER
@@ -203,21 +220,21 @@ def analyzeAudioData(chunks, lat, lon, week, sensitivity, overlap,):
# Make prediction # Make prediction
p = predict([sig, mdata], sensitivity) p = predict([sig, mdata], sensitivity)
# print("PPPPP",p) # print("PPPPP",p)
HUMAN_DETECTED=False HUMAN_DETECTED = False
#Catch if Human is recognized # Catch if Human is recognized
for x in range(len(p)): for x in range(len(p)):
if "Human" in p[x][0]: if "Human" in p[x][0]:
# print("HUMAN DETECTED!!",p[x][0]) # print("HUMAN DETECTED!!",p[x][0])
#clear list # clear list
HUMAN_DETECTED=True HUMAN_DETECTED = True
print("CHUNK -----",c) print("CHUNK -----", c)
# Save result and timestamp # Save result and timestamp
pred_end = pred_start + 3.0 pred_end = pred_start + 3.0
if HUMAN_DETECTED == True: if HUMAN_DETECTED == True:
p=[('Human_Human',0.0)]*10 p = [('Human_Human', 0.0)] * 10
print("HUMAN DETECTED!!!",p) print("HUMAN DETECTED!!!", p)
detections[str(pred_start) + ';' + str(pred_end)] = p detections[str(pred_start) + ';' + str(pred_end)] = p
@@ -233,15 +250,23 @@ def writeResultsToFile(detections, min_conf, path):
print('WRITING RESULTS TO', path, '...', end=' ') print('WRITING RESULTS TO', path, '...', end=' ')
rcnt = 0 rcnt = 0
with open(path, 'w') as rfile: with open(path, 'w') as rfile:
rfile.write('Start (s);End (s);Scientific name;Common name;Confidence\n') rfile.write(
'Start (s);End (s);Scientific name;Common name;Confidence\n')
for d in detections: for d in detections:
for entry in detections[d]: for entry in detections[d]:
if entry[1] >= min_conf and ((entry[0] in INCLUDE_LIST or len(INCLUDE_LIST) == 0) and (entry[0] not in EXCLUDE_LIST or len(EXCLUDE_LIST) == 0) ): if entry[1] >= min_conf and ((entry[0] in INCLUDE_LIST or len(
rfile.write(d + ';' + entry[0].replace('_', ';') + ';' + str(entry[1]) + '\n') INCLUDE_LIST) == 0) and (entry[0] not in EXCLUDE_LIST or len(EXCLUDE_LIST) == 0)):
rfile.write(d +
';' +
entry[0].replace('_', ';') +
';' +
str(entry[1]) +
'\n')
rcnt += 1 rcnt += 1
print('DONE! WROTE', rcnt, 'RESULTS.') print('DONE! WROTE', rcnt, 'RESULTS.')
return return
def handle_client(conn, addr): def handle_client(conn, addr):
global INCLUDE_LIST global INCLUDE_LIST
global EXCLUDE_LIST global EXCLUDE_LIST
@@ -270,8 +295,7 @@ def handle_client(conn, addr):
args.sensitivity = 1.25 args.sensitivity = 1.25
args.min_conf = 0.70 args.min_conf = 0.70
args.lat = -1 args.lat = -1
args.lon = -1 args.lon = -1
for line in msg.split('||'): for line in msg.split('||'):
inputvars = line.split('=') inputvars = line.split('=')
@@ -298,8 +322,6 @@ def handle_client(conn, addr):
elif inputvars[0] == 'lon': elif inputvars[0] == 'lon':
args.lon = float(inputvars[1]) args.lon = float(inputvars[1])
# Load custom species lists - INCLUDED and EXCLUDED # Load custom species lists - INCLUDED and EXCLUDED
if not args.include_list == 'null': if not args.include_list == 'null':
INCLUDE_LIST = loadCustomSpeciesList(args.include_list) INCLUDE_LIST = loadCustomSpeciesList(args.include_list)
@@ -324,7 +346,8 @@ def handle_client(conn, addr):
file_date = file_name.split('-birdnet-')[0] file_date = file_name.split('-birdnet-')[0]
file_time = file_name.split('-birdnet-')[1] file_time = file_name.split('-birdnet-')[1]
date_time_str = file_date + ' ' + file_time date_time_str = file_date + ' ' + file_time
date_time_obj = datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S') date_time_obj = datetime.datetime.strptime(
date_time_str, '%Y-%m-%d %H:%M:%S')
#print('Date:', date_time_obj.date()) #print('Date:', date_time_obj.date())
#print('Time:', date_time_obj.time()) #print('Time:', date_time_obj.time())
print('Date-time:', date_time_obj) print('Date-time:', date_time_obj)
@@ -336,40 +359,43 @@ def handle_client(conn, addr):
week_number = int(now.strftime("%V")) week_number = int(now.strftime("%V"))
week = max(1, min(week_number, 48)) week = max(1, min(week_number, 48))
sensitivity = max(0.5, min(1.0 - (args.sensitivity - 1.0), 1.5)) sensitivity = max(
0.5, min(1.0 - (args.sensitivity - 1.0), 1.5))
# Process audio data and get detections # Process audio data and get detections
detections = analyzeAudioData(audioData, args.lat, args.lon, week, sensitivity, args.overlap) detections = analyzeAudioData(
audioData, args.lat, args.lon, week, sensitivity, args.overlap)
# Write detections to output file # Write detections to output file
min_conf = max(0.01, min(args.min_conf, 0.99)) min_conf = max(0.01, min(args.min_conf, 0.99))
writeResultsToFile(detections, min_conf, args.o) writeResultsToFile(detections, min_conf, args.o)
############################################################################### ###################################################################
############################################################################### ###################################################################
soundscape_uploaded = False soundscape_uploaded = False
# Write detections to Database # Write detections to Database
myReturn = '' myReturn = ''
for i in detections: for i in detections:
myReturn += str(i) + '-' + str(detections[i][0]) + '\n' myReturn += str(i) + '-' + str(detections[i][0]) + '\n'
with open(userDir + '/BirdNET-Pi/BirdDB.txt', 'a') as rfile: with open(userDir + '/BirdNET-Pi/BirdDB.txt', 'a') as rfile:
for d in detections: for d in detections:
for entry in detections[d]: for entry in detections[d]:
if entry[1] >= min_conf and ((entry[0] in INCLUDE_LIST or len(INCLUDE_LIST) == 0) and (entry[0] not in EXCLUDE_LIST or len(EXCLUDE_LIST) == 0) ): if entry[1] >= min_conf and ((entry[0] in INCLUDE_LIST or len(
rfile.write(str(current_date) + ';' + str(current_time) + ';' + entry[0].replace('_', ';') + ';' \ INCLUDE_LIST) == 0) and (entry[0] not in EXCLUDE_LIST or len(EXCLUDE_LIST) == 0)):
+ str(entry[1]) +";" + str(args.lat) + ';' + str(args.lon) + ';' + str(min_conf) + ';' + str(week) + ';' \ rfile.write(str(current_date) + ';' + str(current_time) + ';' + entry[0].replace('_', ';') + ';'
+ str(args.sensitivity) +';' + str(args.overlap) + '\n') + str(entry[1]) + ";" + str(args.lat) + ';' + str(
args.lon) + ';' + str(min_conf) + ';' + str(week) + ';'
+ str(args.sensitivity) + ';' + str(args.overlap) + '\n')
Date = str(current_date) Date = str(current_date)
Time = str(current_time) Time = str(current_time)
species = entry[0] species = entry[0]
Sci_Name,Com_Name = species.split('_') Sci_Name, Com_Name = species.split('_')
score = entry[1] score = entry[1]
Confidence = str(round(score*100)) Confidence = str(round(score * 100))
Lat = str(args.lat) Lat = str(args.lat)
Lon = str(args.lon) Lon = str(args.lon)
Cutoff = str(args.min_conf) Cutoff = str(args.min_conf)
@@ -378,67 +404,128 @@ def handle_client(conn, addr):
Overlap = str(args.overlap) Overlap = str(args.overlap)
Com_Name = Com_Name.replace("'", "") Com_Name = Com_Name.replace("'", "")
File_Name = Com_Name.replace(" ", "_") + '-' + Confidence + '-' + \ File_Name = Com_Name.replace(" ", "_") + '-' + Confidence + '-' + \
Date.replace("/", "-") + '-birdnet-' + Time + audiofmt Date.replace(
"/", "-") + '-birdnet-' + Time + audiofmt
#Connect to SQLite Database # Connect to SQLite Database
try: try:
con = sqlite3.connect(userDir + '/BirdNET-Pi/scripts/birds.db') con = sqlite3.connect(
userDir + '/BirdNET-Pi/scripts/birds.db')
cur = con.cursor() cur = con.cursor()
cur.execute("INSERT INTO detections VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", (Date, Time, Sci_Name, Com_Name, str(score), Lat, Lon, Cutoff, Week, Sens, Overlap, File_Name)) cur.execute(
"INSERT INTO detections VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
(Date,
Time,
Sci_Name,
Com_Name,
str(score),
Lat,
Lon,
Cutoff,
Week,
Sens,
Overlap,
File_Name))
con.commit() con.commit()
con.close() con.close()
except: except BaseException:
print("Database busy") print("Database busy")
time.sleep(2) time.sleep(2)
print(str(current_date) + ';' + str(current_time) + ';' + entry[0].replace('_', ';') + ';' + str(entry[1]) + ';' + str(args.lat) + ';' + str(args.lon) + ';' + str(min_conf) + ';' + str(week) + ';' + str(args.sensitivity) +';' + str(args.overlap) + Com_Name.replace(" ", "_") + '-' + str(score) + '-' + str(current_date) + '-birdnet-' + str(current_time) + audiofmt + '\n') print(str(current_date) +
';' +
str(current_time) +
';' +
entry[0].replace('_', ';') +
';' +
str(entry[1]) +
';' +
str(args.lat) +
';' +
str(args.lon) +
';' +
str(min_conf) +
';' +
str(week) +
';' +
str(args.sensitivity) +
';' +
str(args.overlap) +
Com_Name.replace(" ", "_") +
'-' +
str(score) +
'-' +
str(current_date) +
'-birdnet-' +
str(current_time) +
audiofmt +
'\n')
if birdweather_id != "99999": if birdweather_id != "99999":
try: try:
if soundscape_uploaded is False: if soundscape_uploaded is False:
# POST soundscape to server # POST soundscape to server
soundscape_url = "https://app.birdweather.com/api/v1/stations/" + birdweather_id + "/soundscapes" + "?timestamp=" + current_iso8601 soundscape_url = "https://app.birdweather.com/api/v1/stations/" + \
birdweather_id + "/soundscapes" + "?timestamp=" + current_iso8601
with open(args.i, 'rb') as f: with open(args.i, 'rb') as f:
wav_data = f.read() wav_data = f.read()
response = requests.post(url=soundscape_url, data=wav_data, headers={'Content-Type': 'application/octet-stream'}) response = requests.post(
print("Soundscape POST Response Status - ", response.status_code) url=soundscape_url, data=wav_data, headers={
'Content-Type': 'application/octet-stream'})
print(
"Soundscape POST Response Status - ", response.status_code)
sdata = response.json() sdata = response.json()
soundscape_id = sdata['soundscape']['id'] soundscape_id = sdata['soundscape']['id']
soundscape_uploaded = True soundscape_uploaded = True
# POST detection to server # POST detection to server
detection_url = "https://app.birdweather.com/api/v1/stations/" + birdweather_id + "/detections" detection_url = "https://app.birdweather.com/api/v1/stations/" + \
birdweather_id + "/detections"
start_time = d.split(';')[0] start_time = d.split(';')[0]
end_time = d.split(';')[1] end_time = d.split(';')[1]
post_begin = "{ " post_begin = "{ "
now_p_start = now + datetime.timedelta(seconds=float(start_time)) now_p_start = now + \
current_iso8601 = now_p_start.astimezone(get_localzone()).isoformat() datetime.timedelta(
post_timestamp = "\"timestamp\": \"" + current_iso8601 + "\"," seconds=float(start_time))
post_lat = "\"lat\": " + str(args.lat) + "," current_iso8601 = now_p_start.astimezone(
post_lon = "\"lon\": " + str(args.lon) + "," get_localzone()).isoformat()
post_soundscape_id = "\"soundscapeId\": " + str(soundscape_id) + "," post_timestamp = "\"timestamp\": \"" + current_iso8601 + "\","
post_lat = "\"lat\": " + \
str(args.lat) + ","
post_lon = "\"lon\": " + \
str(args.lon) + ","
post_soundscape_id = "\"soundscapeId\": " + \
str(soundscape_id) + ","
post_soundscape_start_time = "\"soundscapeStartTime\": " + start_time + "," post_soundscape_start_time = "\"soundscapeStartTime\": " + start_time + ","
post_soundscape_end_time = "\"soundscapeEndTime\": " + end_time + "," post_soundscape_end_time = "\"soundscapeEndTime\": " + end_time + ","
post_commonName = "\"commonName\": \"" + entry[0].split('_')[1] + "\"," post_commonName = "\"commonName\": \"" + \
post_scientificName = "\"scientificName\": \"" + entry[0].split('_')[0] + "\"," entry[0].split('_')[1] + "\","
post_scientificName = "\"scientificName\": \"" + \
entry[0].split('_')[0] + "\","
post_algorithm = "\"algorithm\": " + "\"alpha\"" + "," post_algorithm = "\"algorithm\": " + "\"alpha\"" + ","
post_confidence = "\"confidence\": " + str(entry[1]) post_confidence = "\"confidence\": " + \
str(entry[1])
post_end = " }" post_end = " }"
post_json = post_begin + post_timestamp + post_lat + post_lon + post_soundscape_id + post_soundscape_start_time + post_soundscape_end_time + post_commonName + post_scientificName + post_algorithm + post_confidence + post_end post_json = post_begin + post_timestamp + post_lat + post_lon + post_soundscape_id + post_soundscape_start_time + \
post_soundscape_end_time + post_commonName + post_scientificName + \
post_algorithm + post_confidence + post_end
print(post_json) print(post_json)
response = requests.post(detection_url, json=json.loads(post_json)) response = requests.post(
print("Detection POST Response Status - ", response.status_code) detection_url, json=json.loads(post_json))
except: print(
"Detection POST Response Status - ", response.status_code)
except BaseException:
print("Cannot POST right now") print("Cannot POST right now")
conn.send(myReturn.encode(FORMAT)) conn.send(myReturn.encode(FORMAT))
#time.sleep(3) # time.sleep(3)
conn.close() conn.close()
def start(): def start():
# Load model # Load model
global INTERPRETER, INCLUDE_LIST, EXCLUDE_LIST global INTERPRETER, INCLUDE_LIST, EXCLUDE_LIST