@@ -141,6 +141,12 @@ DB_PWD=changeme
|
|||||||
|
|
||||||
ICE_PWD=changeme
|
ICE_PWD=changeme
|
||||||
|
|
||||||
|
#--------------------- BirdWeather Station Information -----------------------#
|
||||||
|
#_____________The variable below can be set to have your BirdNET-Pi____________#
|
||||||
|
#__________________also act as a BirdWeather listening station_________________#
|
||||||
|
|
||||||
|
BIRDWEATHER_ID=${BIRDWEATHER_ID}
|
||||||
|
|
||||||
#----------------------- Web-hosting/Caddy File-server -----------------------#
|
#----------------------- Web-hosting/Caddy File-server -----------------------#
|
||||||
#________The four variables below can be set to enable internet access_________#
|
#________The four variables below can be set to enable internet access_________#
|
||||||
#____________to your data,(e.g., extractions, raw data, live___________________#
|
#____________to your data,(e.g., extractions, raw data, live___________________#
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
# Birders Guide Installer Configuration File
|
# Birders Guide Installer Configuration File
|
||||||
|
|
||||||
###########################################################################
|
################################################################################
|
||||||
# Fill this out in order to install BirdNET-Lite
|
# Fill this out in order to install BirdNET-Lite
|
||||||
# Follow the instructions for each section.
|
# Follow the instructions for each section.
|
||||||
###########################################################################
|
################################################################################
|
||||||
|
|
||||||
|
|
||||||
# 1. To find your latitude and longitude, you can go to https://maps.google.com
|
# 1. To find your latitude and longitude, you can go to https://maps.google.com
|
||||||
# 1a. Find the location on the map where you will be putting the BirdNET-Lite
|
# 1a. Find the location on the map where you will be putting the BirdNET-Lite
|
||||||
# 1b. Right-click the location to view the latitude and longitude and click them to
|
# 1b. Right-click the location to view the latitude and longitude and click
|
||||||
# copy them to your clip-board.
|
# them to copy them to your clip-board.
|
||||||
# 2. Enter the latitude and longitude here. Be certain not to mix them up and
|
# 2. Enter the latitude and longitude here. Be certain not to mix them up.
|
||||||
# only go to the thousandth's decimal place. The first number is the latitude,
|
# The first number is the latitude, and the second is longitude. See the
|
||||||
# and the second is longitude. See the example below.
|
# example below.
|
||||||
|
#
|
||||||
# Example: these coordinates would indicate the Eiffel Tower in Paris, France.
|
# Example: these coordinates would indicate the Eiffel Tower in Paris, France.
|
||||||
# LATITUDE=48.858
|
# LATITUDE=48.858
|
||||||
# LONGITUDE=2.294
|
# LONGITUDE=2.294
|
||||||
@@ -22,17 +23,17 @@ LONGITUDE=
|
|||||||
|
|
||||||
# 1. CADDY_PWD is the password you will use to access your live audio stream and
|
# 1. CADDY_PWD is the password you will use to access your live audio stream and
|
||||||
# maintenance tools. You can set this to anything, but keep it alpha-numeric.
|
# maintenance tools. You can set this to anything, but keep it alpha-numeric.
|
||||||
# You will probably also want to write this one down if you ever plan to listen
|
# You will probably also want to write this one down if you ever plan to
|
||||||
# to the live stream.
|
# listen to the live stream.
|
||||||
# 2. ICE_PWD is the password that IceCast2 will use to authenticate the stream source.
|
# 2. ICE_PWD is the password that IceCast2 will use to authenticate the stream
|
||||||
# You can set this to anything also, but keep it alpha-numeric. You will never use
|
# source.You can set this to anything also, but keep it alpha-numeric. You
|
||||||
# this again, so just set it to your favorite word.
|
# will never use this again, so just set it to your favorite word.
|
||||||
|
|
||||||
CADDY_PWD=
|
CADDY_PWD=
|
||||||
ICE_PWD=
|
ICE_PWD=
|
||||||
|
|
||||||
# DB_PWD is the password that the system will use to access the database. Set this to
|
# DB_PWD is the password that the system will use to access the database. Set
|
||||||
# anything you want.
|
# this to anything you want.
|
||||||
|
|
||||||
DB_PWD=
|
DB_PWD=
|
||||||
|
|
||||||
@@ -49,3 +50,10 @@ PUSHED_APP_KEY=
|
|||||||
BIRDNETPI_URL=
|
BIRDNETPI_URL=
|
||||||
BIRDNETLOG_URL=
|
BIRDNETLOG_URL=
|
||||||
EXTRACTIONLOG_URL=
|
EXTRACTIONLOG_URL=
|
||||||
|
|
||||||
|
# If you would like to POST your BirdNET-Pi detections to
|
||||||
|
# https://app.birdweather.com, reach out to github:@timsterc for a unique and
|
||||||
|
# confidential BirdWeather ID. Place that here if you have one already.
|
||||||
|
# You can always add this later and the system will immediately start POSTing.
|
||||||
|
|
||||||
|
BIRDWEATHER_ID=
|
||||||
|
|||||||
@@ -570,11 +570,11 @@ Caddy, and Adminer use the Apache License Version 2.0
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
=============================================================================
|
=============================================================================
|
||||||
GoTTY use the MIT License
|
GoTTY and autoAP scripts use the MIT License
|
||||||
=============================================================================
|
=============================================================================
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
BirdNET - Copyright (c) 2019 Stefan Kahl
|
autoAP - Copywrite (c) 2021 Benn
|
||||||
GoTTY - Copyright (c) 2015-2017 Iwasaki Yudai
|
GoTTY - Copyright (c) 2015-2017 Iwasaki Yudai
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ Check out birds from around the world
|
|||||||
* Web interface access to all data and logs
|
* Web interface access to all data and logs
|
||||||
* Automatic extraction of detected data (creating audio clips of detected bird sounds)
|
* Automatic extraction of detected data (creating audio clips of detected bird sounds)
|
||||||
* Spectrograms available for all extractions
|
* Spectrograms available for all extractions
|
||||||
|
* [BirdWeather](https://app.birdweather.com) integration (you will need to be issued a BirdWeather ID -- for now, request that from [@timsterc here](https://github.com/mcguirepr89/BirdNET-Pi/discussions/82))
|
||||||
* MariaDB integration
|
* MariaDB integration
|
||||||
* NoMachine remote desktop (for personal use only)
|
* NoMachine remote desktop (for personal use only)
|
||||||
* Live audio stream
|
* Live audio stream
|
||||||
|
|||||||
+109
-46
@@ -1,3 +1,5 @@
|
|||||||
|
# BirdWeather edits by @timsterc
|
||||||
|
# Other edits by @CaiusX and @mcguirepr89
|
||||||
import os
|
import os
|
||||||
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
|
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
|
||||||
os.environ['CUDA_VISIBLE_DEVICES'] = ''
|
os.environ['CUDA_VISIBLE_DEVICES'] = ''
|
||||||
@@ -13,10 +15,17 @@ import librosa
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import math
|
import math
|
||||||
import time
|
import time
|
||||||
|
from decimal import Decimal
|
||||||
|
import json
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
import requests
|
||||||
import mysql.connector
|
import mysql.connector
|
||||||
###############################################################################
|
###############################################################################
|
||||||
from datetime import date, datetime
|
import datetime
|
||||||
|
import pytz
|
||||||
|
from tzlocal import get_localzone
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
def loadModel():
|
def loadModel():
|
||||||
|
|
||||||
global INPUT_LAYER_INDEX
|
global INPUT_LAYER_INDEX
|
||||||
@@ -196,6 +205,7 @@ def main():
|
|||||||
parser.add_argument('--sensitivity', type=float, default=1.0, help='Detection sensitivity; Higher values result in higher sensitivity. Values in [0.5, 1.5]. Defaults to 1.0.')
|
parser.add_argument('--sensitivity', type=float, default=1.0, help='Detection sensitivity; Higher values result in higher sensitivity. Values in [0.5, 1.5]. Defaults to 1.0.')
|
||||||
parser.add_argument('--min_conf', type=float, default=0.1, help='Minimum confidence threshold. Values in [0.01, 0.99]. Defaults to 0.1.')
|
parser.add_argument('--min_conf', type=float, default=0.1, help='Minimum confidence threshold. Values in [0.01, 0.99]. Defaults to 0.1.')
|
||||||
parser.add_argument('--custom_list', default='', help='Path to text file containing a list of species. Not used if not provided.')
|
parser.add_argument('--custom_list', default='', help='Path to text file containing a list of species. Not used if not provided.')
|
||||||
|
parser.add_argument('--birdweather_id', default='99999', help='Private Station ID for BirdWeather.')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
@@ -208,75 +218,128 @@ def main():
|
|||||||
else:
|
else:
|
||||||
WHITE_LIST = []
|
WHITE_LIST = []
|
||||||
|
|
||||||
|
birdweather_id = args.birdweather_id
|
||||||
|
|
||||||
# Read audio data
|
# Read audio data
|
||||||
audioData = readAudioData(args.i, args.overlap)
|
audioData = readAudioData(args.i, args.overlap)
|
||||||
|
|
||||||
# Process audio data and get detections
|
# Get Date/Time from filename in case Pi gets behind
|
||||||
week = max(1, min(args.week, 48))
|
#now = datetime.now()
|
||||||
|
full_file_name = args.i
|
||||||
|
file_name = Path(full_file_name).stem
|
||||||
|
file_date = file_name.split('-birdnet-')[0]
|
||||||
|
file_time = file_name.split('-birdnet-')[1]
|
||||||
|
date_time_str = file_date + ' ' + file_time
|
||||||
|
date_time_obj = datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S')
|
||||||
|
#print('Date:', date_time_obj.date())
|
||||||
|
#print('Time:', date_time_obj.time())
|
||||||
|
print('Date-time:', date_time_obj)
|
||||||
|
now = date_time_obj
|
||||||
|
current_date = now.strftime("%Y/%m/%d")
|
||||||
|
current_time = now.strftime("%H:%M:%S")
|
||||||
|
current_iso8601 = now.astimezone(get_localzone()).isoformat()
|
||||||
|
|
||||||
|
week_number = int(now.strftime("%V"))
|
||||||
|
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
|
||||||
detections = analyzeAudioData(audioData, args.lat, args.lon, week, sensitivity, args.overlap, interpreter)
|
detections = analyzeAudioData(audioData, args.lat, args.lon, week, sensitivity, args.overlap, interpreter)
|
||||||
|
|
||||||
# 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)
|
||||||
now = datetime.now()
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
soundscape_uploaded = False
|
||||||
|
|
||||||
# Write detections to Database
|
# Write detections to Database
|
||||||
for i in detections:
|
for i in detections:
|
||||||
print("\n", detections[i][0],"\n")
|
print("\n", detections[i][0],"\n")
|
||||||
with open('BirdDB.txt', 'a') as rfile:
|
with open('BirdDB.txt', 'a') as rfile:
|
||||||
for d in detections:
|
for d in detections:
|
||||||
print("\n", "Database Entry", "\n")
|
print("\n", "Database Entry", "\n")
|
||||||
for entry in detections[d]:
|
for entry in detections[d]:
|
||||||
if entry[1] >= min_conf and (entry[0] in WHITE_LIST or len(WHITE_LIST) == 0):
|
if entry[1] >= min_conf and (entry[0] in WHITE_LIST or len(WHITE_LIST) == 0):
|
||||||
current_date = now.strftime("%Y/%m/%d")
|
rfile.write(str(current_date) + ';' + str(current_time) + ';' + entry[0].replace('_', ';') + ';' \
|
||||||
current_time = now.strftime("%H:%M:%S")
|
+ 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(sensitivity) +';' + str(args.overlap) + '\n')
|
||||||
+ str(entry[1]) +";" + str(args.lat) + ';' + str(args.lon) + ';' + str(min_conf) + ';' + str(week) + ';' \
|
|
||||||
+ str(sensitivity) +';' + str(args.overlap) + '\n')
|
|
||||||
|
|
||||||
def insert_variables_into_table(Date, Time, Sci_Name, Com_Name, Confidence, Lat, Lon, Cutoff, Week, Sens, Overlap):
|
def insert_variables_into_table(Date, Time, Sci_Name, Com_Name, Confidence, Lat, Lon, Cutoff, Week, Sens, Overlap):
|
||||||
try:
|
try:
|
||||||
connection = mysql.connector.connect(host='localhost',
|
connection = mysql.connector.connect(host='localhost',
|
||||||
database='birds',
|
database='birds',
|
||||||
user='birder',
|
user='birder',
|
||||||
password='databasepassword')
|
password='databasepassword')
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
mySql_insert_query = """INSERT INTO detections (Date, Time, Sci_Name, Com_Name, Confidence, Lat, Lon, Cutoff, Week, Sens, Overlap)
|
mySql_insert_query = """INSERT INTO detections (Date, Time, Sci_Name, Com_Name, Confidence, Lat, Lon, Cutoff, Week, Sens, Overlap)
|
||||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) """
|
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) """
|
||||||
|
|
||||||
|
record = (Date, Time, Sci_Name, Com_Name, Confidence, Lat, Lon, Cutoff, Week, Sens, Overlap)
|
||||||
|
|
||||||
|
cursor.execute(mySql_insert_query, record)
|
||||||
|
connection.commit()
|
||||||
|
print("Record inserted successfully into detections table")
|
||||||
|
|
||||||
|
|
||||||
|
except mysql.connector.Error as error:
|
||||||
|
print("Failed to insert record into detections table {}".format(error))
|
||||||
|
|
||||||
record = (Date, Time, Sci_Name, Com_Name, Confidence, Lat, Lon, Cutoff, Week, Sens, Overlap)
|
finally:
|
||||||
|
if connection.is_connected():
|
||||||
|
connection.close()
|
||||||
|
print("MySQL connection is closed")
|
||||||
|
|
||||||
cursor.execute(mySql_insert_query, record)
|
species = entry[0]
|
||||||
connection.commit()
|
sci_name,com_name = species.split('_')
|
||||||
print("Record inserted successfully into detections table")
|
insert_variables_into_table(str(current_date), str(current_time), sci_name, com_name, \
|
||||||
|
str(entry[1]), str(args.lat), str(args.lon), str(min_conf), str(week), \
|
||||||
|
str(args.sensitivity), str(args.overlap))
|
||||||
|
|
||||||
|
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) + '\n')
|
||||||
except mysql.connector.Error as error:
|
|
||||||
print("Failed to insert record into detections table {}".format(error))
|
|
||||||
|
|
||||||
finally:
|
|
||||||
if connection.is_connected():
|
|
||||||
connection.close()
|
|
||||||
print("MySQL connection is closed")
|
|
||||||
|
|
||||||
species = entry[0]
|
if birdweather_id != "99999":
|
||||||
sci_name,com_name = species.split('_')
|
|
||||||
insert_variables_into_table(str(current_date), str(current_time), sci_name, com_name, \
|
|
||||||
str(entry[1]), str(args.lat), str(args.lon), str(min_conf), str(week), \
|
|
||||||
str(args.sensitivity), str(args.overlap))
|
|
||||||
|
|
||||||
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) + '\n')
|
if soundscape_uploaded is False:
|
||||||
|
# POST soundscape to server
|
||||||
|
soundscape_url = "https://app.birdweather.com/api/v1/stations/" + birdweather_id + "/soundscapes" + "?timestamp=" + current_iso8601
|
||||||
|
|
||||||
time.sleep(3)
|
with open(args.i, 'rb') as f:
|
||||||
|
wav_data = f.read()
|
||||||
|
response = requests.post(url=soundscape_url, data=wav_data, headers={'Content-Type': 'application/octet-stream'})
|
||||||
|
print("Soundscape POST Response Status - ", response.status_code)
|
||||||
|
sdata = response.json()
|
||||||
|
soundscape_id = sdata['soundscape']['id']
|
||||||
|
soundscape_uploaded = True
|
||||||
|
|
||||||
now = datetime.now()
|
# POST detection to server
|
||||||
|
detection_url = "https://app.birdweather.com/api/v1/stations/" + birdweather_id + "/detections"
|
||||||
|
start_time = d.split(';')[0]
|
||||||
|
end_time = d.split(';')[1]
|
||||||
|
post_begin = "{ "
|
||||||
|
now_p_start = now + datetime.timedelta(seconds=float(start_time))
|
||||||
|
current_iso8601 = now_p_start.astimezone(get_localzone()).isoformat()
|
||||||
|
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_end_time = "\"soundscapeEndTime\": " + end_time + ","
|
||||||
|
post_commonName = "\"commonName\": \"" + entry[0].split('_')[1] + "\","
|
||||||
|
post_scientificName = "\"scientificName\": \"" + entry[0].split('_')[0] + "\","
|
||||||
|
post_algorithm = "\"algorithm\": " + "\"alpha\"" + ","
|
||||||
|
post_confidence = "\"confidence\": " + str(entry[1])
|
||||||
|
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)
|
||||||
|
response = requests.post(detection_url, json=json.loads(post_json))
|
||||||
|
print("Detection POST Response Status - ", response.status_code)
|
||||||
|
|
||||||
|
#time.sleep(3)
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|||||||
@@ -53,6 +53,12 @@ DB_PWD=changeme
|
|||||||
|
|
||||||
ICE_PWD=changeme
|
ICE_PWD=changeme
|
||||||
|
|
||||||
|
#--------------------- BirdWeather Station Information -----------------------#
|
||||||
|
#_____________The variable below can be set to have your BirdNET-Pi____________#
|
||||||
|
#__________________also act as a BirdWeather listening station_________________#
|
||||||
|
|
||||||
|
BIRDWEATHER_ID=
|
||||||
|
|
||||||
#----------------------- Web-hosting/Caddy File-server -----------------------#
|
#----------------------- Web-hosting/Caddy File-server -----------------------#
|
||||||
#________The four variables below can be set to enable internet access_________#
|
#________The four variables below can be set to enable internet access_________#
|
||||||
#____________to your data,(e.g., extractions, raw data, live___________________#
|
#____________to your data,(e.g., extractions, raw data, live___________________#
|
||||||
|
|||||||
+34
-37
@@ -1,45 +1,42 @@
|
|||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>BirdNET-Pi</title>
|
<title>BirdNET-Pi</title>
|
||||||
<style>
|
<style>
|
||||||
* {
|
* {
|
||||||
background-color: background-color: rgb(119, 196, 135);
|
background-color: background-color: rgb(119, 196, 135);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<!--
|
<!--
|
||||||
Note the following:
|
Note the following:
|
||||||
1. Each frame has it's own 'frame' tag.
|
1. Each frame has it's own 'frame' tag.
|
||||||
2. Each frame has a name (eg, name="menu"). This is used for when you need to load one frame from another. For example, your left frame might have links that, when clicked on, loads a new page in the right frame. This is acheived by using 'target="content"' within your links/anchor tags.
|
2. Each frame has a name (eg, name="menu"). This is used for when you need to load one frame from another. For example, your left frame might have links that, when clicked on, loads a new page in the right frame. This is acheived by using 'target="content"' within your links/anchor tags.
|
||||||
3. Each 'frame' tag has a 'src' attribute. This is where you specify the name of the file to be loaded into that frame when the page first loads.
|
3. Each 'frame' tag has a 'src' attribute. This is where you specify the name of the file to be loaded into that frame when the page first loads.
|
||||||
4. You can change the size of the frames by changing the value of the 'cols' and/or 'rows' attribute. A value of "200" sets the frame at 200 pixels. An asterisk (*) specifies that the frame should use up whatever space is left over from the other frames. You can also use percentage values if desired (i.e. 20%,80%)
|
4. You can change the size of the frames by changing the value of the 'cols' and/or 'rows' attribute. A value of "200" sets the frame at 200 pixels. An asterisk (*) specifies that the frame should use up whatever space is left over from the other frames. You can also use percentage values if desired (i.e. 20%,80%)
|
||||||
5. To specify a border, set 'frameborder' and 'border' to "1". I included both attributes for maximum browser compatibility.
|
5. To specify a border, set 'frameborder' and 'border' to "1". I included both attributes for maximum browser compatibility.
|
||||||
6. The 'framespacing' attribute doesn't work in all browsers, but you can set any numeric value you like here.
|
6. The 'framespacing' attribute doesn't work in all browsers, but you can set any numeric value you like here.
|
||||||
7. To learn more about HTML frames, check out: http://www.quackit.com/html/tutorial/html_frames.cfm
|
7. To learn more about HTML frames, check out: http://www.quackit.com/html/tutorial/html_frames.cfm
|
||||||
-->
|
-->
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
if (screen.width <= 699) {
|
if (screen.width <= 699) {
|
||||||
document.location = "/mobile.html";
|
document.location = "/mobile.html";
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<frameset rows="100,*" frameborder="0" border="0" framespacing="0">
|
<frameset rows="100,*" frameborder="0" border="0" framespacing="0">
|
||||||
<frameset style="background-color: rgb(119, 196, 135);" cols="150,*,150" frameborder="0" border="0" framespacing="0">
|
<frameset style="background-color: rgb(119, 196, 135);" cols="*,150" frameborder="0" border="0" framespacing="0" />
|
||||||
<frame style="fill: none;background: rgb(119, 196, 135);padding-top: 15px;padding-left: 32.5px;padding-right: 32.5px;"src="images/bird.png" class="ribbon"/>
|
<frame name="topNav" src="top.html" scrolling="off">
|
||||||
<frame name="topNav" src="top.html" scrolling="off">
|
<frame name="footer" src="footer.html" scrolling="off">
|
||||||
<frame name="footer" src="footer.html" scrolling="off">
|
</frameset>
|
||||||
</frameset>
|
<frameset cols="150,*" frameborder="0" border="0" framespacing="0">
|
||||||
<frameset cols="150,*" frameborder="0" border="0" framespacing="0">
|
<frame name="menu" src="menu.html" marginheight="0" marginwidth="0" scrolling="auto" noresize>
|
||||||
<frame name="menu" src="menu.html" marginheight="0" marginwidth="0" scrolling="off" noresize>
|
<frame name="content" src="/overview.php" marginheight="0" marginwidth="0" scrolling="auto" noresize>
|
||||||
<frame name="content" src="/viewdb.php" marginheight="0" marginwidth="0" scrolling="auto" noresize>
|
|
||||||
|
|
||||||
<! -- <frame name="footer" src="footer.html" scrolling="off"> -->
|
<noframes>
|
||||||
|
<p>This section (everything between the 'noframes' tags) will only be displayed if the users' browser doesn't support frames. You can provide a link to a non-frames version of the website here. Feel free to use HTML tags within this section.</p>
|
||||||
|
</noframes>
|
||||||
|
|
||||||
<noframes>
|
</frameset>
|
||||||
<p>This section (everything between the 'noframes' tags) will only be displayed if the users' browser doesn't support frames. You can provide a link to a non-frames version of the website here. Feel free to use HTML tags within this section.</p>
|
|
||||||
</noframes>
|
|
||||||
|
|
||||||
</frameset>
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+59
-54
@@ -1,74 +1,79 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>HTML Frames Example - Menu</title>
|
<title>HTML Frames Example - Menu</title>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
a {
|
a {
|
||||||
text-decoration:none;
|
text-decoration:none;
|
||||||
margin: 0px 0px 0px 0px;
|
margin: 0px 0px 0px 0px;
|
||||||
color:black;
|
color:black;
|
||||||
|
font-size: small;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
font-family:verdana,arial,sans-serif;
|
font-family:verdana,arial,sans-serif;
|
||||||
font-size:medium;
|
font-size:medium;
|
||||||
margin:10px;
|
margin:10px;
|
||||||
background-color: rgb(119, 196, 135);
|
background-color: rgb(119, 196, 135);
|
||||||
|
text-align: left;
|
||||||
|
padding-bottom: 30px;
|
||||||
}
|
}
|
||||||
h3 {
|
h3 {
|
||||||
margin: 0px 0px -15px 0px;
|
margin: 0px 0px -15px 0px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
h4,h5 {
|
h4,h5 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 0px 0px 5px 0px;
|
margin: 0px 0px 5px 0px;
|
||||||
}
|
}
|
||||||
footer {
|
footer {
|
||||||
position:absolute;
|
background: rgb(119, 196, 135);
|
||||||
bottom:0;
|
position: fixed;
|
||||||
left:0;
|
padding-top: 10px;
|
||||||
width:100%;
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width:100%;
|
||||||
}
|
}
|
||||||
hr {
|
hr {
|
||||||
border-bottom: 1px solid black;
|
border-bottom: 1px solid black;
|
||||||
}
|
}
|
||||||
</style>
|
body::-webkit-scrollbar {
|
||||||
</head>
|
display:none
|
||||||
<body>
|
}
|
||||||
<h5>Extractions</h5>
|
</style>
|
||||||
<p style="font-size: small;text-align: center">
|
</head>
|
||||||
<a href="http://birdnetpi.local/By_Date/" target="content">By Date</a><br>
|
<body>
|
||||||
<a href="http://birdnetpi.local/By_Common_Name/" target="content">By Common Name</a><br>
|
|
||||||
<a href="http://birdnetpi.local/By_Scientific_Name/" target="content">By Scientific Name</a><br>
|
|
||||||
<a href="http://birdnetpi.local/Processed/" target="content">Processed</a><br>
|
|
||||||
|
|
||||||
</p>
|
<h5>Extractions</h5>
|
||||||
<hr class="solid">
|
- <a href="http://birdnetpi.local/By_Date/" target="content">By Date</a><br>
|
||||||
<h5>System Links</h5>
|
- <a href="http://birdnetpi.local/By_Common_Name/" target="content">By Common Name</a><br>
|
||||||
<p style="font-size: small;text-align: center">
|
- <a href="http://birdnetpi.local/By_Scientific_Name/" target="content">By Scientific Name</a><br>
|
||||||
<a href="http://birdnetpi.local/scripts/" target="content">Tools</a><br>
|
- <a href="http://birdnetpi.local/Processed/" target="content">Processed</a><br>
|
||||||
|
|
||||||
<a href="http://birdnetpi.local/phpsysinfo/" target="content">System Info</a><br>
|
<hr class="solid">
|
||||||
|
|
||||||
<a href="http://birdnetpi.local:8080/" target="content">BirdNET-Lite Log</a><br>
|
<h5>System Links</h5>
|
||||||
|
- <a href="http://birdnetpi.local/scripts/" target="content">Tools</a><br>
|
||||||
|
- <a href="http://birdnetpi.local/phpsysinfo/" target="content">System Info</a><br>
|
||||||
|
- <a href="http://birdnetpi.local:8080" target="content">BirdNET-Lite Log</a><br>
|
||||||
|
- <a href="http://birdnetpi.local:8888" target="content">Extraction Log</a><br>
|
||||||
|
|
||||||
<a href="http://birdnetpi.local:8888/" target="content">Extraction Log</a><br>
|
<hr class="solid">
|
||||||
|
|
||||||
</p>
|
<h5>External Links</h5>
|
||||||
<hr class="solid">
|
- <a href="https://app.birdweather.com" target="_content">BirdWeather</a><br>
|
||||||
<h5>External Links</h5>
|
- <a href="https://github.com/mcguirepr89/BirdNET-Pi" target="_content">Repository</a><br>
|
||||||
<p style="font-size: small;text-align: center">
|
- <a href="https://github.com/mcguirepr89/BirdNET-Pi/wiki" target="_content">Wiki Help Page</a><br>
|
||||||
<a href="https://github.com/mcguirepr89/BirdNET-Pi" target="_content">Repository</a><br>
|
- <a href="https://v2.wttr.in/" target="content">Wttr.in Report</a><br>
|
||||||
<a href="https://github.com/mcguirepr89/BirdNET-Pi/wiki" target="_content">Wiki Help Page</a><br>
|
- <a href="https://www.birds.cornell.edu" target="_content">Cornell Lab of Ornithology</a><br>
|
||||||
<a href="https://wttr.in/" target="content">Wttr.in Report</a><br>
|
<hr class="solid">
|
||||||
<a href="https://www.birds.cornell.edu" target="_content">Cornell Lab of Ornithology</a><br>
|
|
||||||
</p>
|
<h5>Other<br>BirdNET-Pis</h5>
|
||||||
<hr class="solid">
|
- <a href="https://birdnetpi.pmcgui.xyz" target="_content">United States</a><br>
|
||||||
<h5>Other<br>BirdNET-Pis</h5>
|
- <a href="https://birds.naturestation.net" target="_content">South Africa</a><br>
|
||||||
<a style="font-size: small;" href="https://birdnetpi.pmcgui.xyz" target="_content">United States,</a>
|
- <a href="https://birdnetpigermany.hopto.org" target="_content">Germany</a>
|
||||||
<a style="font-size: small;" href="https://birds.naturestation.net" target="_content">South Africa,</a>
|
|
||||||
<a style="font-size: small;" href="https://birdnetpigermany.hopto.org" target="_content">Germany</a>
|
</body>
|
||||||
</body>
|
<footer style="font-size: small;">
|
||||||
<footer style="font-size: small;">
|
Icon by <a target="_content" style="font-weight: bold" href="https://www.freepik.com" title="Freepik">Freepik</a> from <a target="_content" style="font-weight: bold" href="https://www.flaticon.com/" title="Flaticon">Flaticon.com</a>
|
||||||
Icon by <a style="font-weight: bold" href="https://www.freepik.com" title="Freepik">Freepik</a> from <a style="font-weight: bold" href="https://www.flaticon.com/" title="Flaticon">Flaticon.com</a>
|
</footer>
|
||||||
</footer>
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-1
@@ -324,9 +324,21 @@ footer {
|
|||||||
</h1>
|
</h1>
|
||||||
</header>
|
</header>
|
||||||
<hr>
|
<hr>
|
||||||
|
<h2>
|
||||||
|
<a href="/overview.php">
|
||||||
|
<span class="name">🐦 Overview</span>
|
||||||
|
</a>
|
||||||
|
</h2>
|
||||||
|
<hr style="border-top: dotted 2px #ccc;">
|
||||||
|
<h2>
|
||||||
|
<a href="/viewday.php">
|
||||||
|
<span class="name">🐦 Today's Top 10</span>
|
||||||
|
</a>
|
||||||
|
</h2>
|
||||||
|
<hr style="border-top: dotted 2px #ccc;">
|
||||||
<h2>
|
<h2>
|
||||||
<a href="/viewdb.php">
|
<a href="/viewdb.php">
|
||||||
<span class="name">🐦 Recognized Birds</span>
|
<span class="name">🐦 View the Database</span>
|
||||||
</a>
|
</a>
|
||||||
</h2>
|
</h2>
|
||||||
<hr style="border-top: dotted 2px #ccc;">
|
<hr style="border-top: dotted 2px #ccc;">
|
||||||
|
|||||||
+61
-68
@@ -1,18 +1,34 @@
|
|||||||
/* style sheet */
|
/* style sheet */
|
||||||
* {
|
* {
|
||||||
|
font-family: 'Arial', 'Gill Sans', 'Gill Sans MT',
|
||||||
|
' Calibri', 'Trebuchet MS', 'sans-serif';
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.row {
|
/* Create two equal columns that floats next to each other */
|
||||||
display: flex;
|
.column2 {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 75%;
|
||||||
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create two equal columns that floats next to each other */
|
||||||
.column {
|
.column {
|
||||||
flex: 50%;
|
float: left;
|
||||||
padding-right: 5px;
|
width: 50%;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear floats after the columns */
|
||||||
|
.row:after {
|
||||||
|
content: "";
|
||||||
|
display: table;
|
||||||
|
clear: both;
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
|
background-color: rgb(219, 255, 235);
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
font-size: large;
|
font-size: large;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
@@ -22,82 +38,59 @@ table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: black;
|
color: black;
|
||||||
font-size: xx-large;
|
font-size: xx-large;
|
||||||
font-family: 'Gill Sans', 'Gill Sans MT',
|
|
||||||
' Calibri', 'Trebuchet MS', 'sans-serif';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
text-align: center;
|
margin-left: -150px;
|
||||||
color: black;
|
text-align: center;
|
||||||
font-size: large;
|
color: black;
|
||||||
font-family: 'Gill Sans', 'Gill Sans MT',
|
font-size: large;
|
||||||
' Calibri', 'Trebuchet MS', 'sans-serif';
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
text-align: center;
|
||||||
|
color: black;
|
||||||
|
font-size: large;
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
background-color: rgb(119, 196, 135);
|
background-color: rgb(219, 255, 235);
|
||||||
border: 1px solid black;
|
font-weight: lighter;
|
||||||
|
border: 1px solid black;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
th,
|
th {
|
||||||
td {
|
background-color: rgb(219, 255, 235);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: rgb(219, 296, 235);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 800px) {
|
@media screen and (max-width: 600px) {
|
||||||
.column {
|
|
||||||
float: none;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
table {
|
|
||||||
margin: 0 auto;
|
|
||||||
font-size: medium;
|
|
||||||
border-collapse: collapse;
|
|
||||||
border-spacing: 1;
|
|
||||||
width: 100%;
|
|
||||||
border: 1px solid black;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
text-align: center;
|
|
||||||
color: black;
|
|
||||||
font-size: large;
|
|
||||||
font-family: 'Gill Sans', 'Gill Sans MT',
|
|
||||||
' Calibri', 'Trebuchet MS', 'sans-serif';
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
text-align: center;
|
margin-left: 0;
|
||||||
color: black;
|
text-align: center;
|
||||||
font-size: large;
|
color: black;
|
||||||
font-family: 'Gill Sans', 'Gill Sans MT',
|
font-size: large;
|
||||||
' Calibri', 'Trebuchet MS', 'sans-serif';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
|
||||||
background-color: rgb(119, 196, 135);
|
|
||||||
border: 1px solid black;
|
|
||||||
}
|
|
||||||
|
|
||||||
th,
|
|
||||||
td {
|
|
||||||
font-weight: bold;
|
|
||||||
border: 1px solid black;
|
|
||||||
padding: 10px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
.column {
|
||||||
font-weight: lighter;
|
width: 100%;
|
||||||
|
}
|
||||||
|
/* Create two equal columns that floats next to each other */
|
||||||
|
.column2 {
|
||||||
|
float: center;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
body::-webkit-scrollbar {
|
body::-webkit-scrollbar {
|
||||||
display:none
|
display:none
|
||||||
}
|
|
||||||
|
|||||||
+37
-32
@@ -1,45 +1,50 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>BirdNET-Pi</title>
|
<title>BirdNET-Pi</title>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
a {
|
a {
|
||||||
font-weight:bold;
|
font-weight:bold;
|
||||||
text-decoration:none;
|
text-decoration:none;
|
||||||
color:black;
|
color:black;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
text-align:center;
|
text-align:center;
|
||||||
font-family:verdana,arial,sans-serif;
|
font-family:verdana,arial,sans-serif;
|
||||||
font-size:medium;
|
font-size:medium;
|
||||||
margin:10px;
|
margin:10px;
|
||||||
background-color: rgb(119, 196, 135);
|
background-color: rgb(119, 196, 135);
|
||||||
}
|
}
|
||||||
#content {
|
#content {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
#content img {
|
#content img {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
}
|
}
|
||||||
footer {
|
footer {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>BirdNET-Pi<img style="padding-left: 5px" src="images/version.svg" class="ribbon"/></h1>
|
<a href="https://github.com/mcguirepr89/BirdNET-Pi" target="_content">
|
||||||
</div>
|
<img alt="BirdNET-Pi" src="images/bird.png" style="position:absolute;left:32.5px;top:15px;">
|
||||||
<p>
|
</a>
|
||||||
<a href="/viewdb.php" target="content">Database View</a> |
|
<h1 style="padding-left:150px">BirdNET-Pi<img style="padding-left: 5px" src="images/version.svg" class="ribbon"/></h1>
|
||||||
<a href="/spectrogram.php" target="content">Spectrogram View</a>
|
</div>
|
||||||
</p>
|
<p style="padding-left:150px;">
|
||||||
</body>
|
<a href="/overview.php" target="content">Overview</a> |
|
||||||
|
<a href="/viewdb.php" target="content">Database View</a> |
|
||||||
|
<a href="/viewday.php" target="content">Today View</a> |
|
||||||
|
<a href="/spectrogram.php" target="content">Spectrogram View</a>
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
appdirs
|
||||||
|
audioread
|
||||||
|
certifi
|
||||||
|
cffi
|
||||||
|
charset-normalizer
|
||||||
|
colorama
|
||||||
|
cycler
|
||||||
|
decorator
|
||||||
|
idna
|
||||||
|
joblib
|
||||||
|
kiwisolver
|
||||||
|
librosa
|
||||||
|
llvmlite
|
||||||
|
matplotlib
|
||||||
|
mysql-connector-python
|
||||||
|
numba
|
||||||
|
numpy
|
||||||
|
packaging
|
||||||
|
pandas
|
||||||
|
Pillow
|
||||||
|
pip
|
||||||
|
pkg_resources
|
||||||
|
pooch
|
||||||
|
protobuf
|
||||||
|
pycparser
|
||||||
|
pyparsing
|
||||||
|
python-dateutil
|
||||||
|
pytz
|
||||||
|
requests
|
||||||
|
resampy
|
||||||
|
scikit-learn
|
||||||
|
scipy
|
||||||
|
seaborn
|
||||||
|
setuptools
|
||||||
|
six
|
||||||
|
SoundFile
|
||||||
|
tflite-runtime
|
||||||
|
threadpoolctl
|
||||||
|
tzlocal
|
||||||
|
urllib3
|
||||||
|
wheel
|
||||||
+54
-10
@@ -91,18 +91,18 @@ run_analysis() {
|
|||||||
if [ "${RECORDING_LENGTH}" == "01:00" ];then
|
if [ "${RECORDING_LENGTH}" == "01:00" ];then
|
||||||
until [ "$(ffmpeg -i ${1}/${i} 2>&1 | awk -F. '/Duration/ {print $1}' | cut -d':' -f3-4)" == "${RECORDING_LENGTH}" ];do
|
until [ "$(ffmpeg -i ${1}/${i} 2>&1 | awk -F. '/Duration/ {print $1}' | cut -d':' -f3-4)" == "${RECORDING_LENGTH}" ];do
|
||||||
sleep 1
|
sleep 1
|
||||||
[ $a -ge 60 ] && sudo rm -f ${1}/${i} && break
|
[ $a -ge 60 ] && sudo rm -f ${1}/${i} && break
|
||||||
a=$((a+1))
|
a=$((a+1))
|
||||||
done
|
done
|
||||||
else
|
else
|
||||||
until [ "$(ffmpeg -i ${1}/${i} 2>&1 | awk -F. '/Duration/ {print $1}' | cut -d':' -f3-4)" == "00:${RECORDING_LENGTH}" ];do
|
until [ "$(ffmpeg -i ${1}/${i} 2>&1 | awk -F. '/Duration/ {print $1}' | cut -d':' -f3-4)" == "00:${RECORDING_LENGTH}" ];do
|
||||||
sleep 1
|
sleep 1
|
||||||
[ $a -ge ${RECORDING_LENGTH} ] && sudo rm -f ${1}/${i} && break
|
[ $a -ge ${RECORDING_LENGTH} ] && sudo rm -f ${1}/${i} && break
|
||||||
a=$((a+1))
|
a=$((a+1))
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -f ${1}/${i} ] && [ ! -f ${CUSTOM_LIST} ];then
|
if [ -f ${1}/${i} ] && [ ! -f ${CUSTOM_LIST} ] && [ -z $BIRDWEATHER_ID ];then
|
||||||
echo "python3 analyze.py \
|
echo "python3 analyze.py \
|
||||||
--i "${1}/${i}" \
|
--i "${1}/${i}" \
|
||||||
--o "${1}/${i}.csv" \
|
--o "${1}/${i}.csv" \
|
||||||
@@ -119,9 +119,9 @@ run_analysis() {
|
|||||||
--lon "${LONGITUDE}" \
|
--lon "${LONGITUDE}" \
|
||||||
--week "${WEEK}" \
|
--week "${WEEK}" \
|
||||||
--overlap "${OVERLAP}" \
|
--overlap "${OVERLAP}" \
|
||||||
--sensitivity "${SENSITIVITY}" \
|
--sensitivity "${SENSITIVITY}" \
|
||||||
--min_conf "${CONFIDENCE}"
|
--min_conf "${CONFIDENCE}"
|
||||||
elif [ -f ${1}/${i} ] && [ -f ${CUSTOM_LIST} ];then
|
elif [ -f ${1}/${i} ] && [ -f ${CUSTOM_LIST} ] && [ -z $BIRDWEATHER_ID ];then
|
||||||
echo "python3 analyze.py \
|
echo "python3 analyze.py \
|
||||||
--i "${1}/${i}" \
|
--i "${1}/${i}" \
|
||||||
--o "${1}/${i}.csv" \
|
--o "${1}/${i}.csv" \
|
||||||
@@ -139,10 +139,54 @@ run_analysis() {
|
|||||||
--lon "${LONGITUDE}" \
|
--lon "${LONGITUDE}" \
|
||||||
--week "${WEEK}" \
|
--week "${WEEK}" \
|
||||||
--overlap "${OVERLAP}" \
|
--overlap "${OVERLAP}" \
|
||||||
--sensitivity "${SENSITIVITY}" \
|
--sensitivity "${SENSITIVITY}" \
|
||||||
--min_conf "${CONFIDENCE}" \
|
--min_conf "${CONFIDENCE}" \
|
||||||
--custom_list "${CUSTOM_LIST}"
|
--custom_list "${CUSTOM_LIST}"
|
||||||
fi
|
elif [ -f ${1}/${i} ] && [ ! -f ${CUSTOM_LIST} ] && [ ! -z $BIRDWEATHER_ID ];then
|
||||||
|
echo "python3 analyze.py \
|
||||||
|
--i "${1}/${i}" \
|
||||||
|
--o "${1}/${i}.csv" \
|
||||||
|
--lat "${LATITUDE}" \
|
||||||
|
--lon "${LONGITUDE}" \
|
||||||
|
--week "${WEEK}" \
|
||||||
|
--overlap "${OVERLAP}" \
|
||||||
|
--sensitivity "${SENSITIVITY}" \
|
||||||
|
--min_conf "${CONFIDENCE}" \
|
||||||
|
--birdweather_id IN_USE"
|
||||||
|
"${VENV}"/bin/python analyze.py \
|
||||||
|
--i "${1}/${i}" \
|
||||||
|
--o "${1}/${i}.csv" \
|
||||||
|
--lat "${LATITUDE}" \
|
||||||
|
--lon "${LONGITUDE}" \
|
||||||
|
--week "${WEEK}" \
|
||||||
|
--overlap "${OVERLAP}" \
|
||||||
|
--sensitivity "${SENSITIVITY}" \
|
||||||
|
--min_conf "${CONFIDENCE}" \
|
||||||
|
--birdweather_id "${BIRDWEATHER_ID}"
|
||||||
|
elif [ -f ${1}/${i} ] && [ -f ${CUSTOM_LIST} ] && [ ! -z $BIRDWEATHER_ID ];then
|
||||||
|
echo "python3 analyze.py \
|
||||||
|
--i "${1}/${i}" \
|
||||||
|
--o "${1}/${i}.csv" \
|
||||||
|
--lat "${LATITUDE}" \
|
||||||
|
--lon "${LONGITUDE}" \
|
||||||
|
--week "${WEEK}" \
|
||||||
|
--overlap "${OVERLAP}" \
|
||||||
|
--sensitivity "${SENSITIVITY}" \
|
||||||
|
--min_conf "${CONFIDENCE}" \
|
||||||
|
--custom_list "${CUSTOM_LIST}" \
|
||||||
|
--birdweather_id IN_USE"
|
||||||
|
"${VENV}"/bin/python analyze.py \
|
||||||
|
--i "${1}/${i}" \
|
||||||
|
--o "${1}/${i}.csv" \
|
||||||
|
--lat "${LATITUDE}" \
|
||||||
|
--lon "${LONGITUDE}" \
|
||||||
|
--week "${WEEK}" \
|
||||||
|
--overlap "${OVERLAP}" \
|
||||||
|
--sensitivity "${SENSITIVITY}" \
|
||||||
|
--min_conf "${CONFIDENCE}" \
|
||||||
|
--custom_list "${CUSTOM_LIST}" \
|
||||||
|
--birdweather_id "${BIRDWEATHER_ID}"
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,12 +12,13 @@ sudo systemctl stop birdnet_recording.service
|
|||||||
echo "Removing all data . . . "
|
echo "Removing all data . . . "
|
||||||
sudo rm -drf "${RECS_DIR}"
|
sudo rm -drf "${RECS_DIR}"
|
||||||
sudo rm -f "${IDFILE}"
|
sudo rm -f "${IDFILE}"
|
||||||
|
sudo rm -f $(dirname ${my_dir})/BirdDB.txt
|
||||||
echo "Recreating necessary directories"
|
echo "Recreating necessary directories"
|
||||||
echo "Creating necessary directories"
|
|
||||||
[ -d ${EXTRACTED} ] || sudo -u ${USER} mkdir -p ${EXTRACTED}
|
[ -d ${EXTRACTED} ] || sudo -u ${USER} mkdir -p ${EXTRACTED}
|
||||||
[ -d ${EXTRACTED}/By_Date ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Date
|
[ -d ${EXTRACTED}/By_Date ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Date
|
||||||
[ -d ${EXTRACTED}/By_Common_Name ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Common_Name
|
[ -d ${EXTRACTED}/By_Common_Name ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Common_Name
|
||||||
[ -d ${EXTRACTED}/By_Scientific_Name ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Scientific_Name
|
[ -d ${EXTRACTED}/By_Scientific_Name ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Scientific_Name
|
||||||
|
[ -d ${EXTRACTED}/Charts ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/Charts
|
||||||
[ -d ${PROCESSED} ] || sudo -u ${USER} mkdir -p ${PROCESSED}
|
[ -d ${PROCESSED} ] || sudo -u ${USER} mkdir -p ${PROCESSED}
|
||||||
|
|
||||||
sudo -u ${USER} ln -fs $(dirname ${my_dir})/homepage/* ${EXTRACTED}
|
sudo -u ${USER} ln -fs $(dirname ${my_dir})/homepage/* ${EXTRACTED}
|
||||||
@@ -49,13 +50,20 @@ if [ ! -z ${BIRDNETPI_URL} ];then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/spectrogram.php ${EXTRACTED}
|
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/spectrogram.php ${EXTRACTED}
|
||||||
|
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/overview.php ${EXTRACTED}
|
||||||
|
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/viewday.php ${EXTRACTED}
|
||||||
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/viewdb.php ${EXTRACTED}
|
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/viewdb.php ${EXTRACTED}
|
||||||
sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED}
|
sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED}
|
||||||
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/phpsysinfo.ini ${HOME}/phpsysinfo/
|
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/phpsysinfo.ini ${HOME}/phpsysinfo/
|
||||||
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/green_bootstrap.css ${HOME}/phpsysinfo/templates/
|
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/green_bootstrap.css ${HOME}/phpsysinfo/templates/
|
||||||
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/index_bootstrap.html ${HOME}/phpsysinfo/templates/html
|
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/index_bootstrap.html ${HOME}/phpsysinfo/templates/html
|
||||||
|
|
||||||
|
echo "Setting Wttr.in URL to "${LATITUDE}", "${LONGITUDE}""
|
||||||
|
sudo -u${USER} sed -i "s/https:\/\/v2.wttr.in\//https:\/\/v2.wttr.in\/"${LATITUDE},${LONGITUDE}"/g" $(dirname ${my_dir})/homepage/menu.html
|
||||||
|
|
||||||
|
echo "Generating BirdDB.txt"
|
||||||
|
[ -f $(dirname ${my_dir})/BirdDB.txt ] || sudo -u ${USER} touch $(dirname ${my_dir})/BirdDB.txt
|
||||||
|
echo "Date;Time;Sci_Name;Com_Name;Confidence;Lat;Lon;Cutoff;Week;Sens;Overlap" | sudo -u ${BIRDNET_USER} tee -a $(dirname ${my_dir})/BirdDB.txt
|
||||||
|
|
||||||
sudo -u ${BIRDNET_USER} cp -f ${HOME}/BirdNET-Pi/homepage/index.html ${EXTRACTED}/
|
sudo -u ${BIRDNET_USER} cp -f ${HOME}/BirdNET-Pi/homepage/index.html ${EXTRACTED}/
|
||||||
echo "Dropping and re-creating database"
|
echo "Dropping and re-creating database"
|
||||||
|
|||||||
@@ -39,5 +39,7 @@ GRANT ALL ON birds.* TO 'birder'@'localhost' IDENTIFIED BY '${DB_PWD}' WITH GRAN
|
|||||||
FLUSH PRIVILEGES;
|
FLUSH PRIVILEGES;
|
||||||
exit
|
exit
|
||||||
EOF
|
EOF
|
||||||
sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/analyze.py
|
sudo -u${USER} sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/analyze.py
|
||||||
sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/viewdb.php
|
sudo -u${USER} sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/viewdb.php
|
||||||
|
sudo -u${USER} sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/overview.php
|
||||||
|
sudo -u${USER} sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/viewday.php
|
||||||
|
|||||||
@@ -40,5 +40,7 @@ GRANT ALL ON birds.* TO 'birder'@'localhost' IDENTIFIED BY '${DB_PWD}' WITH GRAN
|
|||||||
FLUSH PRIVILEGES;
|
FLUSH PRIVILEGES;
|
||||||
exit
|
exit
|
||||||
EOF
|
EOF
|
||||||
sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/analyze.py
|
sudo -u${USER} sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/analyze.py
|
||||||
sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/viewdb.php
|
sudo -u${USER} sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/viewdb.php
|
||||||
|
sudo -u${USER} sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/viewday.php
|
||||||
|
sudo -u${USER} sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/overview.php
|
||||||
|
|||||||
Executable
+154
@@ -0,0 +1,154 @@
|
|||||||
|
#!/home/pi/BirdNET-Pi/birdnet/bin/python3
|
||||||
|
import pandas as pd
|
||||||
|
import seaborn as sns
|
||||||
|
# import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from matplotlib.colors import LogNorm
|
||||||
|
from datetime import datetime
|
||||||
|
import textwrap
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#Read database into Pandas dataframe
|
||||||
|
df = pd.read_csv('~/BirdNET-Pi/BirdDB.txt', sep=';')
|
||||||
|
|
||||||
|
#Convert Date and Time Fields to Panda's format
|
||||||
|
df['Date']=pd.to_datetime(df['Date'])
|
||||||
|
df['Time']=pd.to_datetime(df['Time'])
|
||||||
|
|
||||||
|
#Add round hours to dataframe
|
||||||
|
df['Hour of Day'] = [r.hour for r in df.Time]
|
||||||
|
|
||||||
|
#Create separate dataframes for separate locations
|
||||||
|
df_jhb=df[df.Lat > -32]
|
||||||
|
df_ec = df[df.Lat < -32]
|
||||||
|
|
||||||
|
#Get todays readings for Joburg
|
||||||
|
now = datetime.now()
|
||||||
|
df_jhb_today = df_jhb[df_jhb['Date']==now.strftime("%Y-%m-%d")]
|
||||||
|
|
||||||
|
# Definition to start getting top N detections - work in process
|
||||||
|
def filter_by_freq(df: pd.DataFrame, column: str, min_freq: int) -> pd.DataFrame:
|
||||||
|
"""Filters the DataFrame based on the value frequency in the specified column.
|
||||||
|
|
||||||
|
:param df: DataFrame to be filtered.
|
||||||
|
:param column: Column name that should be frequency filtered.
|
||||||
|
:param min_freq: Minimal value frequency for the row to be accepted.
|
||||||
|
:return: Frequency filtered DataFrame.
|
||||||
|
"""
|
||||||
|
# Frequencies of each value in the column.
|
||||||
|
freq = df[column].value_counts()
|
||||||
|
# Select frequent values. Value is in the index.
|
||||||
|
frequent_values = freq[freq >= min_freq].index
|
||||||
|
# Return only rows with value frequency above threshold.
|
||||||
|
return df[df[column].isin(frequent_values)]
|
||||||
|
|
||||||
|
#Get top readings today
|
||||||
|
min_valuecounts = 2
|
||||||
|
|
||||||
|
|
||||||
|
jhb_gt_min = filter_by_freq (df_jhb_today,'Com_Name', min_valuecounts)
|
||||||
|
|
||||||
|
jhb_gt_min_counts = jhb_gt_min['Com_Name'].value_counts()
|
||||||
|
print(jhb_gt_min_counts)
|
||||||
|
|
||||||
|
|
||||||
|
jhb_top10_today = (df_jhb_today['Com_Name'].value_counts()[:10])
|
||||||
|
df_jhb_top10_today = df_jhb_today[df_jhb_today.Com_Name.isin(jhb_top10_today.index)]
|
||||||
|
|
||||||
|
#Get bottom 10 today
|
||||||
|
jhb_bot10_today=(df_jhb_today['Com_Name'].value_counts()[-10:])
|
||||||
|
df_jhb_bot10_today = df_jhb_today[df_jhb_today.Com_Name.isin(jhb_bot10_today.index)]
|
||||||
|
|
||||||
|
#Set Palette for graphics
|
||||||
|
pal = "Greens"
|
||||||
|
|
||||||
|
#Set up plot axes and titles
|
||||||
|
f, axs = plt.subplots(1, 2, figsize = (10, 4), gridspec_kw=dict(width_ratios=[3, 5]))
|
||||||
|
plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0, hspace=None)
|
||||||
|
|
||||||
|
|
||||||
|
#Generate frequency plot
|
||||||
|
plot=sns.countplot(y='Com_Name', data = df_jhb_top10_today, palette = pal+"_r", order=pd.value_counts(df_jhb_top10_today['Com_Name']).iloc[:20].index, ax=axs[0])
|
||||||
|
|
||||||
|
#Try plot grid lines between bars - problem at the moment plots grid lines on bars - want between bars
|
||||||
|
# plot.grid(True, axis='y')
|
||||||
|
|
||||||
|
plot.set_yticklabels(['\n'.join(textwrap.wrap(ticklabel.get_text(),15)) for ticklabel in plot.get_yticklabels()])
|
||||||
|
plot.set(ylabel=None)
|
||||||
|
plot.set(xlabel="Detections")
|
||||||
|
|
||||||
|
#Generate crosstab matrix for heatmap plot
|
||||||
|
|
||||||
|
heat = pd.crosstab(df_jhb_top10_today['Com_Name'],df_jhb_top10_today['Hour of Day'])
|
||||||
|
#Order heatmap Birds by frequency of occurrance
|
||||||
|
heat.index = pd.CategoricalIndex(heat.index, categories = pd.value_counts(df_jhb_top10_today['Com_Name']).iloc[:10].index)
|
||||||
|
heat.sort_index(level=0, inplace=True)
|
||||||
|
|
||||||
|
|
||||||
|
hours_in_day = pd.Series(data = range(0,24))
|
||||||
|
heat_frame = pd.DataFrame(data=0, index=heat.index, columns = hours_in_day)
|
||||||
|
heat=(heat+heat_frame).fillna(0)
|
||||||
|
|
||||||
|
#Generatie heatmap plot
|
||||||
|
plot = sns.heatmap(heat, norm=LogNorm(), annot=True, annot_kws={"fontsize":7}, cmap = pal , square = False, cbar=False, linewidths = 0.5, linecolor = "Grey", ax=axs[1], yticklabels = False)
|
||||||
|
|
||||||
|
# Set heatmap border
|
||||||
|
for _, spine in plot.spines.items():
|
||||||
|
spine.set_visible(True)
|
||||||
|
|
||||||
|
plot.set(ylabel=None)
|
||||||
|
plot.set(xlabel="Hour of Day")
|
||||||
|
#Set combined plot layout and titles
|
||||||
|
plt.tight_layout()
|
||||||
|
f.subplots_adjust(top=0.9)
|
||||||
|
plt.suptitle("Last Updated: "+ str(now.strftime("%B, %d at %I:%M%P")))
|
||||||
|
|
||||||
|
#Save combined plot
|
||||||
|
savename='/home/pi/BirdSongs/Extracted/Charts/Combo-'+str(now.strftime("%d-%m-%Y"))+'.png'
|
||||||
|
plt.savefig(savename)
|
||||||
|
plt.close()
|
||||||
|
|
||||||
|
|
||||||
|
#Get bottom 10 today
|
||||||
|
jhb_bot10_today=(df_jhb_today['Com_Name'].value_counts()[-10:])
|
||||||
|
df_jhb_bot10_today = df_jhb_today[df_jhb_today.Com_Name.isin(jhb_bot10_today.index)]
|
||||||
|
|
||||||
|
#Set Palette for graphics
|
||||||
|
pal = "Reds"
|
||||||
|
|
||||||
|
#Set up plot axes and titles
|
||||||
|
f, axs = plt.subplots(1, 2, figsize = (8, 4), gridspec_kw=dict(width_ratios=[3, 5]))
|
||||||
|
|
||||||
|
#Generate frequency plot
|
||||||
|
plot=sns.countplot(y='Com_Name', data = df_jhb_bot10_today, palette = pal+"_r", order=pd.value_counts(df_jhb_bot10_today['Com_Name']).iloc[:10].index, ax=axs[0])
|
||||||
|
plot.set_yticklabels(['\n'.join(textwrap.wrap(ticklabel.get_text(),17)) for ticklabel in plot.get_yticklabels()])
|
||||||
|
plot.set(ylabel=None)
|
||||||
|
plot.set(xlabel="no. of detections")
|
||||||
|
#Generate crosstab matrix for heatmap plot
|
||||||
|
heat = pd.crosstab(df_jhb_bot10_today['Com_Name'],df_jhb_bot10_today['Hour of Day'])
|
||||||
|
|
||||||
|
#Order heatmap Birds by frequency of occurrance
|
||||||
|
heat.index = pd.CategoricalIndex(heat.index, categories = pd.value_counts(df_jhb_bot10_today['Com_Name']).iloc[:10].index)
|
||||||
|
heat.sort_index(level=0, inplace=True)
|
||||||
|
heat_frame = pd.DataFrame(data=0, index=heat.index, columns = hours_in_day)
|
||||||
|
heat=(heat+heat_frame).fillna(0)
|
||||||
|
|
||||||
|
#Generate heatmap plot
|
||||||
|
plot = sns.heatmap(heat, norm=LogNorm(), annot=True, annot_kws={"fontsize":7}, cmap = pal , square = False, cbar=False, linewidths = 0.5, linecolor = "Grey", ax=axs[1], yticklabels = False)
|
||||||
|
|
||||||
|
# Set heatmap border
|
||||||
|
for _, spine in plot.spines.items():
|
||||||
|
spine.set_visible(True)
|
||||||
|
plot.set(ylabel=None)
|
||||||
|
|
||||||
|
#Set combined plot layout and titles
|
||||||
|
plt.tight_layout()
|
||||||
|
f.subplots_adjust(top=0.9)
|
||||||
|
plt.suptitle("Bottom 10 Detected: "+ str(now.strftime("%d-%h-%Y %H:%M")))
|
||||||
|
plot.set(xlabel="Hour of Day")
|
||||||
|
#Save combined plot
|
||||||
|
savename='/home/pi/BirdSongs/Extracted/Charts/Combo2-'+str(now.strftime("%d-%m-%Y"))+'.png'
|
||||||
|
plt.savefig(savename)
|
||||||
|
|
||||||
|
plt.close()
|
||||||
@@ -52,7 +52,6 @@ install_birdnet() {
|
|||||||
source ./birdnet/bin/activate
|
source ./birdnet/bin/activate
|
||||||
echo "Upgrading pip, wheel, and setuptools"
|
echo "Upgrading pip, wheel, and setuptools"
|
||||||
pip3 install --upgrade pip wheel setuptools
|
pip3 install --upgrade pip wheel setuptools
|
||||||
set -x
|
|
||||||
python_version="$(awk -F. '{print $2}' <(ls -l $(which /usr/bin/python3)))"
|
python_version="$(awk -F. '{print $2}' <(ls -l $(which /usr/bin/python3)))"
|
||||||
echo "python_version=${python_version}"
|
echo "python_version=${python_version}"
|
||||||
# TFLite Pre-built binaires from https://github.com/PINTO0309/TensorflowLite-bin
|
# TFLite Pre-built binaires from https://github.com/PINTO0309/TensorflowLite-bin
|
||||||
@@ -67,13 +66,14 @@ set -x
|
|||||||
echo "Installing the TFLite bin wheel"
|
echo "Installing the TFLite bin wheel"
|
||||||
pip3 install --upgrade tflite_runtime-2.6.0-cp39-none-linux_aarch64.whl
|
pip3 install --upgrade tflite_runtime-2.6.0-cp39-none-linux_aarch64.whl
|
||||||
fi
|
fi
|
||||||
set +x
|
|
||||||
echo "Installing colorama==0.4.4"
|
echo "Installing colorama==0.4.4"
|
||||||
pip3 install colorama==0.4.4
|
pip3 install colorama==0.4.4
|
||||||
echo "Installing librosa"
|
echo "Installing librosa"
|
||||||
pip3 install librosa
|
pip3 install librosa
|
||||||
echo "Installing mysql-connector-python"
|
echo "Installing mysql-connector-python"
|
||||||
pip3 install mysql-connector-python
|
pip3 install mysql-connector-python
|
||||||
|
echo "Making sure everything else is installed"
|
||||||
|
pip3 install -U -r /home/pi/BirdNET-Pi/requirements.txt
|
||||||
}
|
}
|
||||||
|
|
||||||
read -sp "\
|
read -sp "\
|
||||||
|
|||||||
@@ -5,5 +5,6 @@ tar -vzxf noip-duc-linux.tar.gz
|
|||||||
cd noip-2*
|
cd noip-2*
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
sed '/^exit 0$/i \/usr\/local\/bin\/noip2' /etc/rc.local
|
chmod a+wr /usr/local/etc/no-ip2.conf
|
||||||
|
sed -i '/^exit 0$/i \/usr\/local\/bin\/noip2' /etc/rc.local
|
||||||
noip2 -S
|
noip2 -S
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ install_mariadb() {
|
|||||||
echo "Initializing the database"
|
echo "Initializing the database"
|
||||||
source /etc/os-release
|
source /etc/os-release
|
||||||
if [[ "${VERSION_CODENAME}" == "buster" ]];then
|
if [[ "${VERSION_CODENAME}" == "buster" ]];then
|
||||||
${my_dir}/createdb_buster.sh
|
USER=${USER} ${my_dir}/createdb_buster.sh
|
||||||
elif [[ "${VERSION_CODENAME}" == "bullseye" ]];then
|
elif [[ "${VERSION_CODENAME}" == "bullseye" ]];then
|
||||||
${my_dir}/createdb_bullseye.sh
|
USER=${USER} ${my_dir}/createdb_bullseye.sh
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,6 +113,7 @@ create_necessary_dirs() {
|
|||||||
[ -d ${EXTRACTED}/By_Date ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Date
|
[ -d ${EXTRACTED}/By_Date ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Date
|
||||||
[ -d ${EXTRACTED}/By_Common_Name ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Common_Name
|
[ -d ${EXTRACTED}/By_Common_Name ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Common_Name
|
||||||
[ -d ${EXTRACTED}/By_Scientific_Name ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Scientific_Name
|
[ -d ${EXTRACTED}/By_Scientific_Name ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Scientific_Name
|
||||||
|
[ -d ${EXTRACTED}/Charts ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/Charts
|
||||||
[ -d ${PROCESSED} ] || sudo -u ${USER} mkdir -p ${PROCESSED}
|
[ -d ${PROCESSED} ] || sudo -u ${USER} mkdir -p ${PROCESSED}
|
||||||
|
|
||||||
sudo -u ${USER} ln -fs $(dirname ${my_dir})/homepage/* ${EXTRACTED}
|
sudo -u ${USER} ln -fs $(dirname ${my_dir})/homepage/* ${EXTRACTED}
|
||||||
@@ -144,15 +145,29 @@ create_necessary_dirs() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/spectrogram.php ${EXTRACTED}
|
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/spectrogram.php ${EXTRACTED}
|
||||||
|
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/viewday.php ${EXTRACTED}
|
||||||
|
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/overview.php ${EXTRACTED}
|
||||||
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/viewdb.php ${EXTRACTED}
|
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/viewdb.php ${EXTRACTED}
|
||||||
sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED}
|
sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED}
|
||||||
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/phpsysinfo.ini ${HOME}/phpsysinfo/
|
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/phpsysinfo.ini ${HOME}/phpsysinfo/
|
||||||
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/green_bootstrap.css ${HOME}/phpsysinfo/templates/
|
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/green_bootstrap.css ${HOME}/phpsysinfo/templates/
|
||||||
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/index_bootstrap.html ${HOME}/phpsysinfo/templates/html
|
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/index_bootstrap.html ${HOME}/phpsysinfo/templates/html
|
||||||
|
|
||||||
|
echo "Setting Wttr.in URL to "${LATITUDE}", "${LONGITUDE}""
|
||||||
|
sudo -u${USER} sed -i "s/https:\/\/v2.wttr.in\//https:\/\/v2.wttr.in\/"${LATITUDE},${LONGITUDE}"/g" $(dirname ${my_dir})/homepage/menu.html
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generate_BirdDB() {
|
||||||
|
echo "Generating BirdDB.txt"
|
||||||
|
if ! [ -f $(dirname ${my_dir})/BirdDB.txt ];then
|
||||||
|
sudo -u ${USER} touch $(dirname ${my_dir})/BirdDB.txt
|
||||||
|
echo "Date;Time;Sci_Name;Com_Name;Confidence;Lat;Lon;Cutoff;Week;Sens;Overlap" | sudo -u ${USER} tee -a $(dirname ${my_dir})/BirdDB.txt
|
||||||
|
elif ! grep Date $(dirname ${my_dir})/BirdDB.txt;then
|
||||||
|
sudo -u ${USER} sed -i '1 i\Date;Time;Sci_Name;Com_Name;Confidence;Lat;Lon;Cutoff;Week;Sens;Overlap' $(dirname ${my_dir})/BirdDB.txt
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
install_alsa() {
|
install_alsa() {
|
||||||
echo "Checking for alsa-utils and pulseaudio"
|
echo "Checking for alsa-utils and pulseaudio"
|
||||||
if which arecord &> /dev/null ;then
|
if which arecord &> /dev/null ;then
|
||||||
@@ -302,6 +317,24 @@ EOF
|
|||||||
systemctl enable spectrogram_viewer.service
|
systemctl enable spectrogram_viewer.service
|
||||||
}
|
}
|
||||||
|
|
||||||
|
install_chart_viewer_service() {
|
||||||
|
echo "Installing the chart_viewer.service"
|
||||||
|
cat << EOF > /etc/systemd/system/chart_viewer.service
|
||||||
|
[Unit]
|
||||||
|
Description=BirdNET-Pi Chart Viewer Service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
RestartSec=300
|
||||||
|
Type=simple
|
||||||
|
User=pi
|
||||||
|
ExecStart=/usr/local/bin/daily_plot.py
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable chart_viewer.service
|
||||||
|
}
|
||||||
|
|
||||||
install_gotty_logs() {
|
install_gotty_logs() {
|
||||||
echo "Installing GoTTY logging"
|
echo "Installing GoTTY logging"
|
||||||
if ! which gotty &> /dev/null;then
|
if ! which gotty &> /dev/null;then
|
||||||
@@ -492,6 +525,7 @@ install_selected_services() {
|
|||||||
install_sox
|
install_sox
|
||||||
install_mariadb
|
install_mariadb
|
||||||
install_spectrogram_service
|
install_spectrogram_service
|
||||||
|
install_chart_viewer_service
|
||||||
install_edit_birdnet_conf
|
install_edit_birdnet_conf
|
||||||
install_pushed_notifications
|
install_pushed_notifications
|
||||||
|
|
||||||
@@ -505,6 +539,7 @@ install_selected_services() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
create_necessary_dirs
|
create_necessary_dirs
|
||||||
|
generate_BirdDB
|
||||||
install_cleanup_cron
|
install_cleanup_cron
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
<?php
|
||||||
|
header("refresh: 300;");
|
||||||
|
$myDate = date('d-m-Y');
|
||||||
|
$user = 'birder';
|
||||||
|
$password = 'databasepassword';
|
||||||
|
$database = 'birds';
|
||||||
|
$servername='localhost';
|
||||||
|
$mysqli = new mysqli($servername, $user, $password, $database);
|
||||||
|
|
||||||
|
if ($mysqli->connect_error) {
|
||||||
|
die('Connect Error (' .
|
||||||
|
$mysqli->connect_errno . ') '.
|
||||||
|
$mysqli->connect_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SQL query to select data from database
|
||||||
|
$sql0 = "SELECT * FROM detections";
|
||||||
|
$fulltable = $mysqli->query($sql0);
|
||||||
|
$totalcount = mysqli_num_rows($fulltable);
|
||||||
|
|
||||||
|
$sql1 = "SELECT Com_Name, Date, Time FROM detections
|
||||||
|
ORDER BY Date DESC, Time DESC LIMIT 1";
|
||||||
|
$mostrecent = $mysqli->query($sql1);
|
||||||
|
|
||||||
|
$sql2 = "SELECT * FROM detections
|
||||||
|
WHERE Date = CURDATE()";
|
||||||
|
$todaystable = $mysqli->query($sql2);
|
||||||
|
$todayscount = mysqli_num_rows($todaystable);
|
||||||
|
|
||||||
|
|
||||||
|
$sql3 = "SELECT * FROM detections
|
||||||
|
WHERE Date = CURDATE()
|
||||||
|
AND Time >= DATE_SUB(NOW(),INTERVAL 1 HOUR)";
|
||||||
|
$lasthourtable = $mysqli->query($sql3);
|
||||||
|
$lasthourcount = mysqli_num_rows($lasthourtable);
|
||||||
|
|
||||||
|
$sql4 = "SELECT Com_Name, Date, Time, MAX(Confidence)
|
||||||
|
FROM detections
|
||||||
|
WHERE Date = CURDATE()
|
||||||
|
GROUP BY Com_Name
|
||||||
|
ORDER BY MAX(Confidence) DESC";
|
||||||
|
$specieslist = $mysqli->query($sql4);
|
||||||
|
$speciescount = mysqli_num_rows($specieslist);
|
||||||
|
|
||||||
|
$mysqli->close();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Overview</title>
|
||||||
|
<!-- CSS FOR STYLING THE PAGE -->
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.center {
|
||||||
|
display: block;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
width: 90%;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
.center2 {
|
||||||
|
display: block;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body style="background-color: rgb(119, 196, 135);">
|
||||||
|
<h2>Overview</h2>
|
||||||
|
<div class="row">
|
||||||
|
<div class="column2">
|
||||||
|
<?php // LOOP TILL END OF DATA
|
||||||
|
while($rows=$mostrecent ->fetch_assoc())
|
||||||
|
{
|
||||||
|
?>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Most Recent Detection</th>
|
||||||
|
<td><?php echo $rows['Com_Name'];?></td>
|
||||||
|
<td><?php echo $rows['Date'];?></td>
|
||||||
|
<td><?php echo $rows['Time'];?></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="column">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th>Total</th>
|
||||||
|
<th>Today</th>
|
||||||
|
<th>Last Hour</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Number of Detections</th>
|
||||||
|
<td><?php echo $totalcount;?></td>
|
||||||
|
<td><?php echo $todayscount;?></td>
|
||||||
|
<td><?php echo $lasthourcount;?></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Species Detected Today</th>
|
||||||
|
<td><?php echo $speciescount;?></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h2>Today's Top 10 Species</h2>
|
||||||
|
<img src='/Charts/Combo-<?php echo $myDate;?>.png?nocache=<?php echo time();?>' style="width: 100%;padding: 5px;margin-left: auto;margin-right: auto;display: block;">
|
||||||
|
<h2>Currently Analyzing</h2>
|
||||||
|
<img src='/spectrogram.png?nocache=<?php echo time();?>' style="width: 100%;padding: 5px;">
|
||||||
|
</html>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
header("refresh: 15;");
|
header("refresh: 15;");
|
||||||
echo "<body style='background-color:rgb(119, 196, 135)'>";
|
echo "<body style='background-color:rgb(119, 196, 135)'>";
|
||||||
echo "<img src='/spectrogram.png' >";
|
|
||||||
?>
|
?>
|
||||||
|
<img src='/spectrogram.png?nocache=<?php echo time();?>' style='display: block;margin-left: auto;margin-right: auto; height: 100%;'>
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
services=(birdnet_recording.service
|
services=(birdnet_recording.service
|
||||||
birdnet_analysis.service
|
birdnet_analysis.service
|
||||||
extraction.timer)
|
chart_viewer.service
|
||||||
|
extraction.timer
|
||||||
|
spectrogram_viewer.service)
|
||||||
|
|
||||||
for i in "${services[@]}";do
|
for i in "${services[@]}";do
|
||||||
sudo systemctl stop ${i}
|
sudo systemctl stop ${i}
|
||||||
|
|||||||
@@ -9,3 +9,5 @@ git -C /home/pi/BirdNET-Pi checkout -f analyze.py
|
|||||||
git -C /home/pi/BirdNET-Pi checkout -f scripts/viewdb.php
|
git -C /home/pi/BirdNET-Pi checkout -f scripts/viewdb.php
|
||||||
sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/analyze.py
|
sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/analyze.py
|
||||||
sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/viewdb.php
|
sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/viewdb.php
|
||||||
|
sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/overview.php
|
||||||
|
sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/viewday.php
|
||||||
|
|||||||
@@ -12,3 +12,5 @@ git -C /home/pi/BirdNET-Pi checkout -f analyze.py
|
|||||||
git -C /home/pi/BirdNET-Pi checkout -f scripts/viewdb.php
|
git -C /home/pi/BirdNET-Pi checkout -f scripts/viewdb.php
|
||||||
sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/analyze.py
|
sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/analyze.py
|
||||||
sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/viewdb.php
|
sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/viewdb.php
|
||||||
|
sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/overview.php
|
||||||
|
sed -i "s/databasepassword/${DB_PWD}/g" /home/pi/BirdNET-Pi/scripts/viewday.php
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ USER=pi
|
|||||||
HOME=/home/pi
|
HOME=/home/pi
|
||||||
my_dir=${HOME}/BirdNET-Pi/scripts
|
my_dir=${HOME}/BirdNET-Pi/scripts
|
||||||
tmpfile=$(mktemp)
|
tmpfile=$(mktemp)
|
||||||
nomachine_url="https://download.nomachine.com/download/7.6/Arm/nomachine_7.6.2_3_arm64.deb"
|
nomachine_url="https://download.nomachine.com/download/7.7/Arm/nomachine_7.7.4_1_arm64.deb"
|
||||||
gotty_url="https://github.com/yudai/gotty/releases/download/v1.0.1/gotty_linux_arm.tar.gz"
|
gotty_url="https://github.com/yudai/gotty/releases/download/v1.0.1/gotty_linux_arm.tar.gz"
|
||||||
config_file="$(dirname ${my_dir})/birdnet.conf"
|
config_file="$(dirname ${my_dir})/birdnet.conf"
|
||||||
|
|
||||||
@@ -35,9 +35,9 @@ install_mariadb() {
|
|||||||
fi
|
fi
|
||||||
source /etc/os-release
|
source /etc/os-release
|
||||||
if [[ "${VERSION_CODENAME}" == "buster" ]];then
|
if [[ "${VERSION_CODENAME}" == "buster" ]];then
|
||||||
${my_dir}/update_db_pwd_buster.sh
|
USER=${USER} ${my_dir}/update_db_pwd_buster.sh
|
||||||
elif [[ "${VERSION_CODENAME}" == "bullseye" ]];then
|
elif [[ "${VERSION_CODENAME}" == "bullseye" ]];then
|
||||||
${my_dir}/update_db_pwd_bullseye.sh
|
USER=${USER} ${my_dir}/update_db_pwd_bullseye.sh
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,6 +112,7 @@ create_necessary_dirs() {
|
|||||||
[ -d ${EXTRACTED}/By_Date ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Date
|
[ -d ${EXTRACTED}/By_Date ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Date
|
||||||
[ -d ${EXTRACTED}/By_Common_Name ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Common_Name
|
[ -d ${EXTRACTED}/By_Common_Name ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Common_Name
|
||||||
[ -d ${EXTRACTED}/By_Scientific_Name ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Scientific_Name
|
[ -d ${EXTRACTED}/By_Scientific_Name ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/By_Scientific_Name
|
||||||
|
[ -d ${EXTRACTED}/Charts ] || sudo -u ${USER} mkdir -p ${EXTRACTED}/Charts
|
||||||
[ -d ${PROCESSED} ] || sudo -u ${USER} mkdir -p ${PROCESSED}
|
[ -d ${PROCESSED} ] || sudo -u ${USER} mkdir -p ${PROCESSED}
|
||||||
|
|
||||||
sudo -u ${USER} ln -fs $(dirname ${my_dir})/homepage/* ${EXTRACTED}
|
sudo -u ${USER} ln -fs $(dirname ${my_dir})/homepage/* ${EXTRACTED}
|
||||||
@@ -143,12 +144,26 @@ create_necessary_dirs() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/spectrogram.php ${EXTRACTED}
|
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/spectrogram.php ${EXTRACTED}
|
||||||
|
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/viewday.php ${EXTRACTED}
|
||||||
|
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/overview.php ${EXTRACTED}
|
||||||
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/viewdb.php ${EXTRACTED}
|
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/viewdb.php ${EXTRACTED}
|
||||||
sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED}
|
sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED}
|
||||||
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/phpsysinfo.ini ${HOME}/phpsysinfo/
|
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/phpsysinfo.ini ${HOME}/phpsysinfo/
|
||||||
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/green_bootstrap.css ${HOME}/phpsysinfo/templates/
|
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/green_bootstrap.css ${HOME}/phpsysinfo/templates/
|
||||||
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/index_bootstrap.html ${HOME}/phpsysinfo/templates/html
|
sudo -u ${USER} cp -f $(dirname ${my_dir})/templates/index_bootstrap.html ${HOME}/phpsysinfo/templates/html
|
||||||
|
|
||||||
|
echo "Setting Wttr.in URL to "${LATITUDE}", "${LONGITUDE}""
|
||||||
|
sudo -u${USER} sed -i "s/https:\/\/v2.wttr.in\//https:\/\/v2.wttr.in\/"${LATITUDE},${LONGITUDE}"/g" $(dirname ${my_dir})/homepage/menu.html
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_BirdDB() {
|
||||||
|
echo "Generating BirdDB.txt"
|
||||||
|
if ! [ -f $(dirname ${my_dir})/BirdDB.txt ];then
|
||||||
|
sudo -u ${USER} touch $(dirname ${my_dir})/BirdDB.txt
|
||||||
|
echo "Date;Time;Sci_Name;Com_Name;Confidence;Lat;Lon;Cutoff;Week;Sens;Overlap" | sudo -u ${USER} tee -a $(dirname ${my_dir})/BirdDB.txt
|
||||||
|
elif ! grep Date $(dirname ${my_dir})/BirdDB.txt;then
|
||||||
|
sudo -u ${USER} sed -i '1 i\Date;Time;Sci_Name;Com_Name;Confidence;Lat;Lon;Cutoff;Week;Sens;Overlap' $(dirname ${my_dir})/BirdDB.txt
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
install_alsa() {
|
install_alsa() {
|
||||||
@@ -300,6 +315,24 @@ EOF
|
|||||||
systemctl enable spectrogram_viewer.service
|
systemctl enable spectrogram_viewer.service
|
||||||
}
|
}
|
||||||
|
|
||||||
|
install_chart_viewer_service() {
|
||||||
|
echo "Installing the chart_viewer.service"
|
||||||
|
cat << EOF > /etc/systemd/system/chart_viewer.service
|
||||||
|
[Unit]
|
||||||
|
Description=BirdNET-Pi Chart Viewer Service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
RestartSec=300
|
||||||
|
Type=simple
|
||||||
|
User=pi
|
||||||
|
ExecStart=/usr/local/bin/daily_plot.py
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable chart_viewer.service
|
||||||
|
}
|
||||||
|
|
||||||
install_gotty_logs() {
|
install_gotty_logs() {
|
||||||
echo "Installing GoTTY logging"
|
echo "Installing GoTTY logging"
|
||||||
if ! which gotty &> /dev/null;then
|
if ! which gotty &> /dev/null;then
|
||||||
@@ -489,6 +522,7 @@ install_selected_services() {
|
|||||||
install_sox
|
install_sox
|
||||||
install_mariadb
|
install_mariadb
|
||||||
install_spectrogram_service
|
install_spectrogram_service
|
||||||
|
install_chart_viewer_service
|
||||||
install_edit_birdnet_conf
|
install_edit_birdnet_conf
|
||||||
install_pushed_notifications
|
install_pushed_notifications
|
||||||
|
|
||||||
@@ -502,6 +536,7 @@ install_selected_services() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
create_necessary_dirs
|
create_necessary_dirs
|
||||||
|
generate_BirdDB
|
||||||
install_cleanup_cron
|
install_cleanup_cron
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
header("refresh: 300;");
|
||||||
|
$myDate = date('d-m-Y');
|
||||||
|
$user = 'birder';
|
||||||
|
$password = 'databasepassword';
|
||||||
|
$database = 'birds';
|
||||||
|
$servername='localhost';
|
||||||
|
$mysqli = new mysqli($servername, $user, $password, $database);
|
||||||
|
|
||||||
|
if ($mysqli->connect_error) {
|
||||||
|
die('Connect Error (' .
|
||||||
|
$mysqli->connect_errno . ') '.
|
||||||
|
$mysqli->connect_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SQL query to select data from database
|
||||||
|
|
||||||
|
$sql1 = "SELECT * FROM detections
|
||||||
|
WHERE Date = CURDATE()
|
||||||
|
ORDER BY Date DESC, Time DESC";
|
||||||
|
$mosttable = $mysqli->query($sql1);
|
||||||
|
|
||||||
|
$sql2 = "SELECT * FROM detections
|
||||||
|
WHERE Date = CURDATE()";
|
||||||
|
$todaystable = $mysqli->query($sql2);
|
||||||
|
$todayscount=mysqli_num_rows($todaystable);
|
||||||
|
|
||||||
|
|
||||||
|
$sql3 = "SELECT * FROM detections
|
||||||
|
WHERE Date = CURDATE()
|
||||||
|
AND Time >= DATE_SUB(NOW(),INTERVAL 1 HOUR)";
|
||||||
|
$lasthourtable = $mysqli->query($sql3);
|
||||||
|
$lasthourcount=mysqli_num_rows($lasthourtable);
|
||||||
|
|
||||||
|
$sql4 = "SELECT Com_Name, Date, Time, MAX(Confidence)
|
||||||
|
FROM detections
|
||||||
|
WHERE Date = CURDATE()
|
||||||
|
GROUP BY Com_Name
|
||||||
|
ORDER BY MAX(Confidence) DESC";
|
||||||
|
$specieslist = $mysqli->query($sql4);
|
||||||
|
$speciescount=mysqli_num_rows($specieslist);
|
||||||
|
|
||||||
|
$mysqli->close();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<!-- <meta name="viewport" content="width=device-width, initial-scale=1"> -->
|
||||||
|
<title>Today's View</title>
|
||||||
|
<!-- CSS FOR STYLING THE PAGE -->
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.center {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
table,th,td {
|
||||||
|
background-color: rgb(219, 255, 235);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<img src='/Charts/Combo-<?php echo $myDate;?>.png?nocache=<?php echo time();?>' class="center">
|
||||||
|
<body style="background-color: rgb(119, 196, 135);">
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<div class="row">
|
||||||
|
<div class="column2">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th>Today</th>
|
||||||
|
<th>Last Hour</th>
|
||||||
|
<th>Number of Unique Species Today</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
|
||||||
|
<th>Number of Detections</th>
|
||||||
|
<td><?php echo $todayscount;?></td>
|
||||||
|
<td><?php echo $lasthourcount;?></td>
|
||||||
|
<td><?php echo $speciescount;?></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</html>
|
||||||
+115
-120
@@ -10,45 +10,45 @@ $servername='localhost';
|
|||||||
$mysqli = new mysqli($servername, $user, $password, $database);
|
$mysqli = new mysqli($servername, $user, $password, $database);
|
||||||
|
|
||||||
if ($mysqli->connect_error) {
|
if ($mysqli->connect_error) {
|
||||||
die('Connect Error (' .
|
die('Connect Error (' .
|
||||||
$mysqli->connect_errno . ') '.
|
$mysqli->connect_errno . ') '.
|
||||||
$mysqli->connect_error);
|
$mysqli->connect_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SQL query to select data from database
|
// SQL query to select data from database
|
||||||
$sql = "SELECT * FROM detections
|
$sql = "SELECT * FROM detections
|
||||||
ORDER BY Date DESC, Time DESC";
|
ORDER BY Date DESC, Time DESC";
|
||||||
$fulltable = $mysqli->query($sql);
|
$fulltable = $mysqli->query($sql);
|
||||||
$totalcount=mysqli_num_rows($fulltable);
|
$totalcount=mysqli_num_rows($fulltable);
|
||||||
|
|
||||||
$sql1 = "SELECT * FROM detections
|
$sql1 = "SELECT * FROM detections
|
||||||
WHERE Date = CURDATE()
|
WHERE Date = CURDATE()
|
||||||
ORDER BY Date DESC, Time DESC";
|
ORDER BY Date DESC, Time DESC";
|
||||||
$mosttable = $mysqli->query($sql1);
|
$mosttable = $mysqli->query($sql1);
|
||||||
|
|
||||||
$sql2 = "SELECT * FROM detections
|
$sql2 = "SELECT * FROM detections
|
||||||
WHERE Date = CURDATE()";
|
WHERE Date = CURDATE()";
|
||||||
$todaystable = $mysqli->query($sql2);
|
$todaystable = $mysqli->query($sql2);
|
||||||
$todayscount=mysqli_num_rows($todaystable);
|
$todayscount=mysqli_num_rows($todaystable);
|
||||||
|
|
||||||
$sql3 = "SELECT * FROM detections
|
$sql3 = "SELECT * FROM detections
|
||||||
WHERE Date = CURDATE()
|
WHERE Date = CURDATE()
|
||||||
AND Time >= DATE_SUB(NOW(),INTERVAL 1 HOUR)";
|
AND Time >= DATE_SUB(NOW(),INTERVAL 1 HOUR)";
|
||||||
$lasthourtable = $mysqli->query($sql3);
|
$lasthourtable = $mysqli->query($sql3);
|
||||||
$lasthourcount=mysqli_num_rows($lasthourtable);
|
$lasthourcount=mysqli_num_rows($lasthourtable);
|
||||||
|
|
||||||
$sql4 = "SELECT Com_Name, Date, Time, MAX(Confidence)
|
$sql4 = "SELECT Com_Name, Date, Time, MAX(Confidence)
|
||||||
FROM detections
|
FROM detections
|
||||||
GROUP BY Com_Name
|
GROUP BY Com_Name
|
||||||
ORDER BY MAX(Confidence) DESC";
|
ORDER BY MAX(Confidence) DESC";
|
||||||
$specieslist = $mysqli->query($sql4);
|
$specieslist = $mysqli->query($sql4);
|
||||||
$speciescount=mysqli_num_rows($specieslist);
|
$speciescount=mysqli_num_rows($specieslist);
|
||||||
|
|
||||||
$sql5 = "SELECT Com_Name,COUNT(*)
|
$sql5 = "SELECT Com_Name,COUNT(*)
|
||||||
AS Total
|
AS Total
|
||||||
FROM detections
|
FROM detections
|
||||||
GROUP BY Com_Name
|
GROUP BY Com_Name
|
||||||
ORDER BY Total DESC";
|
ORDER BY Total DESC";
|
||||||
$speciestally = $mysqli->query($sql5);
|
$speciestally = $mysqli->query($sql5);
|
||||||
|
|
||||||
$mysqli->close();
|
$mysqli->close();
|
||||||
@@ -58,122 +58,117 @@ $mysqli->close();
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<!-- <meta name="viewport" content="width=device-width, initial-scale=1"> -->
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>BirdNET-Pi DB</title>
|
<title>BirdNET-Pi DB</title>
|
||||||
<!-- CSS FOR STYLING THE PAGE -->
|
<link rel="stylesheet" href="style.css">
|
||||||
<link rel="stylesheet" href="style.css">
|
|
||||||
<style>
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body style="background-color: rgb(119, 196, 135);background-image: linear-gradient(to top, rgb(119, 196, 135),black;">
|
<body style="background-color: rgb(119, 196, 135);">
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
|
<h2>Number of Detections</h2>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div cladd="column" style="width: 75%;padding-left: 15%;">
|
<div class="column2">
|
||||||
<h2>Number of Detections</h2>
|
<table>
|
||||||
<table>
|
<tr>
|
||||||
<tr>
|
<th>Total</th>
|
||||||
<th>Total</th>
|
<th>Today</th>
|
||||||
<th>Today</th>
|
<th>Last Hour</th>
|
||||||
<th>Last Hour</th>
|
<th>Number of Unique Species</th>
|
||||||
<th>Number of Unique Species</th>
|
</tr>
|
||||||
</tr>
|
<tr>
|
||||||
<tr>
|
<td><?php echo $totalcount;?></td>
|
||||||
<td><?php echo $totalcount;?></td>
|
<td><?php echo $todayscount;?></td>
|
||||||
<td><?php echo $todayscount;?></td>
|
<td><?php echo $lasthourcount;?></td>
|
||||||
<td><?php echo $lasthourcount;?></td>
|
<td><?php echo $speciescount;?></td>
|
||||||
<td><?php echo $speciescount;?></td>
|
</tr>
|
||||||
</tr>
|
</table>
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<h2>Today's Detections</h2>
|
||||||
<div class="column">
|
<!-- TABLE CONSTRUCTION-->
|
||||||
<h2>Detected Species</h2>
|
<table>
|
||||||
<table>
|
<tr>
|
||||||
<tr>
|
<th>Time</th>
|
||||||
<th>Species</th>
|
<th>Scientific Name</th>
|
||||||
<th>Date</th>
|
<th>Common Name</th>
|
||||||
<th>Time</th>
|
<th>Confidence</th>
|
||||||
<th>Max Confidence Score</th>
|
<th>Lat</th>
|
||||||
</tr>
|
<th>Lon</th>
|
||||||
<?php // LOOP TILL END OF DATA
|
<th>Cutoff</th>
|
||||||
while($rows=$specieslist ->fetch_assoc())
|
<th>Week</th>
|
||||||
{
|
<th>Sens</th>
|
||||||
?>
|
<th>Overlap</th>
|
||||||
<tr>
|
</tr>
|
||||||
<td><?php echo $rows['Com_Name'];?></td>
|
<!-- PHP CODE TO FETCH DATA FROM ROWS-->
|
||||||
<td><?php echo $rows['Date'];?></td>
|
|
||||||
<td><?php echo $rows['Time'];?></td>
|
|
||||||
<td><?php echo $rows['MAX(Confidence)'];?></td>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
<h2>Species Statistics</h2>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>Species</th>
|
|
||||||
<th>Detections</th>
|
|
||||||
</tr>
|
|
||||||
<?php // LOOP TILL END OF DATA
|
|
||||||
while($rows=$speciestally ->fetch_assoc())
|
|
||||||
{
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td><?php echo $rows['Com_Name'];?></td>
|
|
||||||
<td><?php echo $rows['Total'];?></td>
|
|
||||||
</tr>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<h2>Today's Detections</h2>
|
|
||||||
<!-- TABLE CONSTRUCTION-->
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>Time</th>
|
|
||||||
<th>Scientific Name</th>
|
|
||||||
<th>Common Name</th>
|
|
||||||
<th>Confidence</th>
|
|
||||||
<th>Lat</th>
|
|
||||||
<th>Lon</th>
|
|
||||||
<th>Cutoff</th>
|
|
||||||
<th>Week</th>
|
|
||||||
<th>Sens</th>
|
|
||||||
<th>Overlap</th>
|
|
||||||
</tr>
|
|
||||||
<!-- PHP CODE TO FETCH DATA FROM ROWS-->
|
|
||||||
<?php // LOOP TILL END OF DATA
|
<?php // LOOP TILL END OF DATA
|
||||||
while($rows=$mosttable ->fetch_assoc())
|
while($rows=$mosttable ->fetch_assoc())
|
||||||
{
|
{
|
||||||
?>
|
?>
|
||||||
<tr>
|
<tr>
|
||||||
<!--FETCHING DATA FROM EACH
|
<!--FETCHING DATA FROM EACH
|
||||||
ROW OF EVERY COLUMN-->
|
ROW OF EVERY COLUMN-->
|
||||||
<td><?php echo $rows['Time'];?></td>
|
<td><?php echo $rows['Time'];?></td>
|
||||||
<td><?php echo $rows['Sci_Name'];?></td>
|
<td><?php echo $rows['Sci_Name'];?></td>
|
||||||
<td><?php echo $rows['Com_Name'];?></td>
|
<td><?php echo $rows['Com_Name'];?></td>
|
||||||
<td><?php echo $rows['Confidence'];?></td>
|
<td><?php echo $rows['Confidence'];?></td>
|
||||||
<td><?php echo $rows['Lat'];?></td>
|
<td><?php echo $rows['Lat'];?></td>
|
||||||
<td><?php echo $rows['Lon'];?></td>
|
<td><?php echo $rows['Lon'];?></td>
|
||||||
<td><?php echo $rows['Cutoff'];?></td>
|
<td><?php echo $rows['Cutoff'];?></td>
|
||||||
<td><?php echo $rows['Week'];?></td>
|
<td><?php echo $rows['Week'];?></td>
|
||||||
<td><?php echo $rows['Sens'];?></td>
|
<td><?php echo $rows['Sens'];?></td>
|
||||||
<td><?php echo $rows['Overlap'];?></td>
|
<td><?php echo $rows['Overlap'];?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
</table>
|
</table>
|
||||||
</section>
|
<div class="row">
|
||||||
|
<div class="column">
|
||||||
|
<h3>Detected Species</h3>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Species</th>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Time</th>
|
||||||
|
<th>Max Confidence Score</th>
|
||||||
|
</tr>
|
||||||
|
<?php // LOOP TILL END OF DATA
|
||||||
|
while($rows=$specieslist ->fetch_assoc())
|
||||||
|
{
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo $rows['Com_Name'];?></td>
|
||||||
|
<td><?php echo $rows['Date'];?></td>
|
||||||
|
<td><?php echo $rows['Time'];?></td>
|
||||||
|
<td><?php echo $rows['MAX(Confidence)'];?></td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<h3>Species Statistics</h3>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Species</th>
|
||||||
|
<th>Detections</th>
|
||||||
|
</tr>
|
||||||
|
<?php // LOOP TILL END OF DATA
|
||||||
|
while($rows=$speciestally ->fetch_assoc())
|
||||||
|
{
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo $rows['Com_Name'];?></td>
|
||||||
|
<td><?php echo $rows['Total'];?></td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</section>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ overview() {
|
|||||||
6) Updating the system to use your new birdnet.conf file" --no-wrap --icon-name=red-cardinal
|
6) Updating the system to use your new birdnet.conf file" --no-wrap --icon-name=red-cardinal
|
||||||
|
|
||||||
if [ $? -eq 0 ];then
|
if [ $? -eq 0 ];then
|
||||||
exit 1
|
exit 0
|
||||||
elif [ $? -eq 1 ];then
|
elif [ $? -eq 1 ];then
|
||||||
open_rpi_configuration && change_password
|
open_rpi_configuration && change_password
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -57,8 +57,7 @@ SUDO_COMMANDS=false
|
|||||||
; Example : BLOCKS="vitals,hardware,memory,filesystem,network,voltage,current,temperature,fans,power,other,ups" or BLOCKS=true //default order
|
; Example : BLOCKS="vitals,hardware,memory,filesystem,network,voltage,current,temperature,fans,power,other,ups" or BLOCKS=true //default order
|
||||||
; BLOCKS=false //hide all blocks
|
; BLOCKS=false //hide all blocks
|
||||||
;
|
;
|
||||||
BLOCKS=true
|
BLOCKS="filesystem,memory,vitals,hardware,network,temperature,voltage,current,fans,power,other,ups"
|
||||||
|
|
||||||
; Maximum time in seconds a script is allowed to run before it is terminated by the parser
|
; Maximum time in seconds a script is allowed to run before it is terminated by the parser
|
||||||
;
|
;
|
||||||
;MAX_TIMEOUT=30
|
;MAX_TIMEOUT=30
|
||||||
@@ -105,7 +104,7 @@ BLOCKS=true
|
|||||||
; - Docker - show docker stats
|
; - Docker - show docker stats
|
||||||
; - Viewer - show output of any command or file viewer.tmp contents
|
; - Viewer - show output of any command or file viewer.tmp contents
|
||||||
;
|
;
|
||||||
PLUGINS=false
|
PLUGINS="Viewer,PSStatus"
|
||||||
|
|
||||||
|
|
||||||
; ********************************
|
; ********************************
|
||||||
@@ -248,7 +247,7 @@ SHOW_DEVICES_SERIAL=false
|
|||||||
; - "UTC" shown as UTC string
|
; - "UTC" shown as UTC string
|
||||||
; - "locale" shown as Locale string
|
; - "locale" shown as Locale string
|
||||||
;
|
;
|
||||||
DATETIME_FORMAT="UTC"
|
DATETIME_FORMAT="locale"
|
||||||
|
|
||||||
|
|
||||||
; ********************************
|
; ********************************
|
||||||
@@ -336,7 +335,7 @@ SHOW_INODES=true
|
|||||||
; Hide mounts
|
; Hide mounts
|
||||||
; Example : HIDE_MOUNTS="/home,/usr"
|
; Example : HIDE_MOUNTS="/home,/usr"
|
||||||
;
|
;
|
||||||
HIDE_MOUNTS=""
|
HIDE_MOUNTS="/boot,/run,/run/lock,/run/user/1000,/dev/shm"
|
||||||
|
|
||||||
|
|
||||||
; Filesystem usage warning threshold in percent
|
; Filesystem usage warning threshold in percent
|
||||||
@@ -398,7 +397,7 @@ HIDE_TOTALS=false
|
|||||||
; Example : HIDE_NETWORK_INTERFACE="eth0,sit0"
|
; Example : HIDE_NETWORK_INTERFACE="eth0,sit0"
|
||||||
; HIDE_NETWORK_INTERFACE=true //hide all network interfaces
|
; HIDE_NETWORK_INTERFACE=true //hide all network interfaces
|
||||||
;
|
;
|
||||||
HIDE_NETWORK_INTERFACE=""
|
HIDE_NETWORK_INTERFACE="lo"
|
||||||
|
|
||||||
|
|
||||||
; Use a regular expression in the name of a hidden network interface (e.g. HIDE_NETWORK_INTERFACE="docker.*")
|
; Use a regular expression in the name of a hidden network interface (e.g. HIDE_NETWORK_INTERFACE="docker.*")
|
||||||
@@ -786,7 +785,7 @@ USE_REGEX=false
|
|||||||
;
|
;
|
||||||
; string contains a list of process names that are checked, names are seperated by a comma (on WinNT names must end with '.exe')
|
; string contains a list of process names that are checked, names are seperated by a comma (on WinNT names must end with '.exe')
|
||||||
;
|
;
|
||||||
PROCESSES="mysqld, sshd, explorer.exe"
|
PROCESSES="avahi-daemon,gotty,sshd,mariadbd,ffmpeg,vncserver-x11-serviced,nxd,bash"
|
||||||
|
|
||||||
|
|
||||||
[quotas]
|
[quotas]
|
||||||
@@ -929,11 +928,13 @@ ACCESS="command"
|
|||||||
; - "systeminfo" systeminfo command is run everytime the block gets refreshed or build (WinNT)
|
; - "systeminfo" systeminfo command is run everytime the block gets refreshed or build (WinNT)
|
||||||
;
|
;
|
||||||
|
|
||||||
COMMAND=""
|
COMMAND="curl"
|
||||||
|
#COMMAND="cat"
|
||||||
|
|
||||||
; define COMMAND parameters (for command access)
|
; define COMMAND parameters (for command access)
|
||||||
;
|
;
|
||||||
PARAMS=""
|
PARAMS="-s4 ifconfig.co"
|
||||||
|
#PARAMS="/home/pi/BirdNET-Pi/thisrun.txt"
|
||||||
|
|
||||||
[pingtest]
|
[pingtest]
|
||||||
; PingTest Plugin configuration
|
; PingTest Plugin configuration
|
||||||
|
|||||||
+10
@@ -1,3 +1,13 @@
|
|||||||
|
# main v.10 & pre-installed image notes
|
||||||
|
- New "BirdWeather" Chromium App (Pre-install image)
|
||||||
|
- New Infographics _chart_viewer.service_ (courtesy of @CaiusX)
|
||||||
|
- New "Overview"
|
||||||
|
- BirdWeather Support
|
||||||
|
- Bug Fix for systemd-networkd-wait-online.service
|
||||||
|
- Bug Fix for `install_noip2.sh` for NoIP DUC Support
|
||||||
|
- New `disk_check.sh` utitlity/crontab entry to `stop_core_services.sh`
|
||||||
|
when disk space is greater than 95%
|
||||||
|
|
||||||
# main v0.9 -- pre-installed image
|
# main v0.9 -- pre-installed image
|
||||||
- Bug fix for Auto Access Point
|
- Bug fix for Auto Access Point
|
||||||
- Improved Welcome Wizard
|
- Improved Welcome Wizard
|
||||||
|
|||||||
Reference in New Issue
Block a user