@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
my_dir=${HOME}/BirdNET-Pi
|
||||
branch=main
|
||||
branch=testing
|
||||
trap '${my_dir}/scripts/dump_logs.sh && exit' EXIT SIGHUP SIGINT
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ stage_2() {
|
||||
if [ ! -d ${my_dir} ];then
|
||||
cd ~ || exit 1
|
||||
echo "Cloning the BirdNET-Pi repository $branch branch into your home directory"
|
||||
git clone -b ${branch} https://github.com/mcguirepr89/BirdNET-Pi.git ~/BirdNET-Pi
|
||||
git clone --depth 1 -b ${branch} https://github.com/mcguirepr89/BirdNET-Pi.git ~/BirdNET-Pi
|
||||
else
|
||||
cd ${my_dir} && git checkout ${branch}
|
||||
fi
|
||||
@@ -232,19 +232,19 @@ DO_RECORDING=y
|
||||
|
||||
################################################################################
|
||||
#----------------------- Web-hosting/Caddy File-server -----------------------#
|
||||
#__________The two variables below can be set to enable web access_____________#
|
||||
#________The four variables below can be set to enable internet access_________#
|
||||
#____________to your data,(e.g., extractions, raw data, live___________________#
|
||||
#______________audio stream, BirdNET.selection.txt files)______________________#
|
||||
|
||||
# Leave these EMPTY if you do not want to enable web access #
|
||||
|
||||
## EXTRACTIONS_URL is the URL where the extractions, data-set, and live-stream
|
||||
## BIRDNETPI_URL is the URL where the extractions, data-set, and live-stream
|
||||
## will be web-hosted. If you do not own a domain, or would just prefer to keep
|
||||
## the BirdNET-Pi on your local network, you can set this to http://localhost.
|
||||
## Setting this (even to http://localhost) will also allow you to enable the
|
||||
## GoTTY web logging features below.
|
||||
## the BirdNET-Pi on your local network, keep this EMPTY.
|
||||
|
||||
EXTRACTIONS_URL=http://raspberrypi.local
|
||||
BIRDNETPI_URL=
|
||||
EXTRACTIONLOG_URL=
|
||||
BIRDNETLOG_URL=
|
||||
|
||||
## CADDY_PWD is the plaintext password (that will be hashed) and used to access
|
||||
## the "Processed" directory and live audio stream. This MUST be set if you
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
# BirdNET-Pi
|
||||

|
||||

|
||||
|
||||
A realtime acoustic bird classification system for the Raspberry Pi 4B
|
||||
|
||||
## Introduction
|
||||
The BirdNET-Pi project is built on the [TFLite version of BirdNET](https://github.com/kahst/BirdNET-Lite). It is able to recognize bird sounds from a USB sound card in realtime.
|
||||
|
||||
[Check out my live system](https://birdnetpi.pmcgui.xyz)<br>
|
||||
[and NatureStation.net](https://birds.naturestation.net)
|
||||
|
||||
## Features
|
||||
* 24/7 recording and BirdNET-Lite analysis
|
||||
* Web interface access to all data and logs
|
||||
@@ -24,6 +27,8 @@ The BirdNET-Pi project is built on the [TFLite version of BirdNET](https://githu
|
||||
* A USB Microphone or Sound Card
|
||||
|
||||
## Installation
|
||||
[Headless installation guide available here](https://github.com/mcguirepr89/BirdNET-Pi/wiki/%22Headless%22-installation-using-VNC)
|
||||
|
||||
The system can be installed with:
|
||||
```
|
||||
curl -s https://raw.githubusercontent.com/mcguirepr89/BirdNET-Pi/main/Birders_Guide_Installer.sh | bash
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
I hope this works:)
|
||||
@@ -53,19 +53,17 @@ DO_RECORDING=
|
||||
|
||||
################################################################################
|
||||
#----------------------- Web-hosting/Caddy File-server -----------------------#
|
||||
#__________The two variables below can be set to enable web access_____________#
|
||||
#_______The two variables below can be set to enable internet access___________#
|
||||
#____________to your data,(e.g., extractions, raw data, live___________________#
|
||||
#______________audio stream, BirdNET.selection.txt files)______________________#
|
||||
|
||||
# Leave these EMPTY if you do not want to enable web access #
|
||||
|
||||
## EXTRACTIONS_URL is the URL where the extractions, data-set, and live-stream
|
||||
## BIRDNETPI_URL is the URL where the extractions, data-set, and live-stream
|
||||
## will be web-hosted. If you do not own a domain, or would just prefer to keep
|
||||
## BirdNET-Pi on your local network, you can set this to http://localhost.
|
||||
## Setting this (even to http://localhost) will also allow you to enable the
|
||||
## GoTTY web logging features below.
|
||||
## BirdNET-Pi on your local network, keep this empty.
|
||||
|
||||
EXTRACTIONS_URL=
|
||||
BIRDNETPI_URL=
|
||||
|
||||
## CADDY_PWD is the plaintext password (that will be hashed) and used to access
|
||||
## the "Processed" directory and live audio stream. This MUST be set if you
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>HTML Frames Example - Content</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family:verdana,arial,sans-serif;
|
||||
font-size:10pt;
|
||||
margin:30px;
|
||||
background-color:#ffcc00;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
tbc....
|
||||
<h1>Thanks</h1>
|
||||
stefan kahl
|
||||
patrick mcguire
|
||||
<h1>Similar Systems</h1>
|
||||
<h1>Technical Details</h1>
|
||||
machine learning
|
||||
deep learning
|
||||
<h1>Used Tools</h1>
|
||||
SoX
|
||||
ffmpeg
|
||||
Python
|
||||
Tensorfflow (Lite)
|
||||
Rasberian OS
|
||||
<h1>Disclaimer</h1>
|
||||
<h1>Other Systems</h1>
|
||||
links to other systems
|
||||
|
||||
|
||||
|
||||
<h1>Content</h1>
|
||||
<h2>Replacing the Contents of the Current Frame</h2>
|
||||
<p>Clicking on these links will open the new page within the current frame.</p>
|
||||
<ul>
|
||||
<li><a href="white.html" target="content">Load white page</a></li>
|
||||
<li><a href="green.html" target="content">Load green page</a></li>
|
||||
</ul>
|
||||
|
||||
<h2>Replacing the Whole Frameset</h2>
|
||||
<p>When you click on any of the following links, the whole frameset is replaced with the new website. This is because we're using <code>target="_top"</code> in the anchor links.</p>
|
||||
<ul>
|
||||
<li><a href="http://www.quackit.com" target="_top">Quackit</a></li>
|
||||
<li><a href="http://www.quackit.com/html/templates/frames/" target="_top">HTML Frames Templates</a></li>
|
||||
<li>Learn more about frames with the <a href="http://www.quackit.com/html/tutorial/html_frames.cfm" target="_top">frames tutorial</a><//li>
|
||||
</ul>
|
||||
|
||||
<h2>Open a New Window</h2>
|
||||
<p>These links open in a new browser window. This is because we use <code>target="_blank"</code>.</p>
|
||||
<ul>
|
||||
<li><a href="http://www.code-generator.net" target="_blank">Code Generator</a></li>
|
||||
<li><a href="http://www.zappyhost.com" target="_blank">ZappyHost</a></li>
|
||||
<li><a href="http://www.natural-environment.com" target="_blank">Natural Environment</a></li>
|
||||
<li><a href="http://www.great-workout.com" target="_blank">Great Workout</a></li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,22 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>HTML Frames Example - Footer</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family:verdana,arial,sans-serif;
|
||||
font-size:medium;
|
||||
margin:10px;
|
||||
text-align:center;
|
||||
background-color:black;
|
||||
color:white;
|
||||
}
|
||||
a {
|
||||
color:white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a href="http://birdnetpi.local/stream" target="footer"><h4>Play Live Audio Stream</h4></a>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
Vendored
BIN
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>BirdNET-Pi</title>
|
||||
</head>
|
||||
<!--
|
||||
Note the following:
|
||||
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.
|
||||
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%)
|
||||
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.
|
||||
7. To learn more about HTML frames, check out: http://www.quackit.com/html/tutorial/html_frames.cfm
|
||||
-->
|
||||
<script type="text/javascript">
|
||||
if (screen.width <= 699) {
|
||||
document.location = "/mobile.html";
|
||||
}
|
||||
</script>
|
||||
|
||||
<frameset rows="100,*" frameborder="0" border="0" framespacing="0">
|
||||
<frame name="topNav" src="top.html" scrolling="off">
|
||||
<frameset cols="150,*" frameborder="0" border="0" framespacing="0">
|
||||
<frameset rows="*,70" frameborder="0" border="0" framespacing="0">
|
||||
<frame name="menu" src="menu.html" marginheight="0" marginwidth="0" scrolling="off" noresize>
|
||||
<frame name="footer" src="footer.html" scrolling="off">
|
||||
</frameset>
|
||||
<frame name="content" src="/viewdb.php" marginheight="0" marginwidth="0" scrolling="auto" noresize>
|
||||
</frameset>
|
||||
|
||||
<! -- <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>
|
||||
|
||||
</frameset>
|
||||
</html>
|
||||
@@ -0,0 +1,36 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>HTML Frames Example - Menu</title>
|
||||
<style type="text/css">
|
||||
a {
|
||||
text-decoration:none;
|
||||
color:black;
|
||||
}
|
||||
body {
|
||||
font-family:verdana,arial,sans-serif;
|
||||
font-size:medium;
|
||||
margin:10px;
|
||||
margin-bottom:50px;
|
||||
background-color: rgb(119, 196, 135);
|
||||
}
|
||||
h4 {
|
||||
text-decoration:underline;
|
||||
}
|
||||
h4,h5 {
|
||||
margin: 15px 0px 0px 0px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h4>Extractions</h4>
|
||||
<a href="http://birdnetpi.local/By_Common_Name/" target="content"><h5>By Common Name</h5></a>
|
||||
<a href="http://birdnetpi.local/By_Date/" target="content"><h5>By Date</h5></a>
|
||||
<a href="http://birdnetpi.local/By_Scientific_Name/" target="content"><h5>By Scientific Name</h5></a>
|
||||
<a href="http://birdnetpi.local/Processed/" target="content"><h5>Processed</h5></a>
|
||||
<h4>External Links</h4>
|
||||
<a href="https://github.com/mcguirepr89/BirdNET-Pi" target="_content"><h5>BirdNET-Pi Repository</h5></a>
|
||||
<a href="https://birdnetwiki.pmcgui.xyz" target="_content"><h5>Wiki Help Page</h5></a>
|
||||
<a href="https://www.accuweather.com" target="content"><h5>Weather</h5></a>
|
||||
<a href="https://www.birds.cornell.edu" target="_content"><h5>The Cornell Lab of Ornithology</h5></a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,42 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>BirdNET-Pi</title>
|
||||
<style type="text/css">
|
||||
a {
|
||||
font-weight:bold;
|
||||
text-decoration:none;
|
||||
color:black;
|
||||
}
|
||||
|
||||
body {
|
||||
text-align:center;
|
||||
font-family:verdana,arial,sans-serif;
|
||||
font-size:medium;
|
||||
margin:10px;
|
||||
background-color: rgb(119, 196, 135);
|
||||
}
|
||||
#content {
|
||||
position: relative;
|
||||
}
|
||||
#content img {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
<img src="images/bird.png" class="ribbon"/>
|
||||
</div>
|
||||
<h1><em>BirdNET</em>-Pi</h1>
|
||||
<p>
|
||||
<a href="/viewdb.php" target="content">Database View</a> |
|
||||
<a href="/spectrogram.php" target="content">Spectrogram View</a> |
|
||||
<a href="http://birdnetpi.local:8080" target="content">BirdNET-Lite Log</a> |
|
||||
<a href="http://birdnetpi.local:8888" target="content">Extraction Log</a> |
|
||||
<a href="http://birdnetpi.local/phpsysinfo" target="content">System Info</a> |
|
||||
<a href="http://birdnetpi.local/scripts/" target="content">Tools</a>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
shell_exec("sudo -u pi /home/pi/BirdNET-Pi/scripts/backup_data.sh > /tmp/birdnetbackup.log 2&>1");
|
||||
header('Location: /backup_inprogress.html');
|
||||
?>
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tar and compress all data
|
||||
source /etc/birdnet/birdnet.conf
|
||||
|
||||
tar -czvf /home/pi/BirdNET-Pi/BirdNET-Pi_Data_Dump_$(date +%F).tar.gz ${EXTRACTED} /home/pi/BirdNET-Pi/BirdDB.txt
|
||||
@@ -0,0 +1,12 @@
|
||||
<html lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<head></head>
|
||||
<body style="background-color: rgb(119, 196, 135);font-size:large;">
|
||||
|
||||
A backup is being made that includes all of<br>
|
||||
your extractions and the BirdDB.txt<br>
|
||||
<br></br>
|
||||
The backup is in /home/pi/BirdNET-Pi
|
||||
</body>
|
||||
</html>
|
||||
Executable
+872
@@ -0,0 +1,872 @@
|
||||
#!/bin/sh
|
||||
# Altered from raspi-config tool below
|
||||
# https://github.com/RPi-Distro/birdnetpi-config
|
||||
#
|
||||
# See LICENSE file for copyright and license details
|
||||
# Copyright (c) 2012 Alex Bradbury <asb@asbradbury.org>
|
||||
|
||||
my_dir=$(realpath $(dirname $0))
|
||||
INTERACTIVE=True
|
||||
ASK_TO_REBOOT=0
|
||||
BLACKLIST=/etc/modprobe.d/raspi-blacklist.conf
|
||||
CONFIG=/boot/config.txt
|
||||
|
||||
USER=${SUDO_USER:-$(who -m | awk '{ print $1 }')}
|
||||
|
||||
is_pi () {
|
||||
ARCH=$(dpkg --print-architecture)
|
||||
if [ "$ARCH" = "armhf" ] || [ "$ARCH" = "arm64" ] ; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
if is_pi ; then
|
||||
CMDLINE=/boot/cmdline.txt
|
||||
else
|
||||
CMDLINE=/proc/cmdline
|
||||
fi
|
||||
|
||||
is_pione() {
|
||||
if grep -q "^Revision\s*:\s*00[0-9a-fA-F][0-9a-fA-F]$" /proc/cpuinfo; then
|
||||
return 0
|
||||
elif grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]0[0-36][0-9a-fA-F]$" /proc/cpuinfo ; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
is_pitwo() {
|
||||
grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]04[0-9a-fA-F]$" /proc/cpuinfo
|
||||
return $?
|
||||
}
|
||||
|
||||
is_pizero() {
|
||||
grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]0[9cC][0-9a-fA-F]$" /proc/cpuinfo
|
||||
return $?
|
||||
}
|
||||
|
||||
is_pifour() {
|
||||
grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F]3[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$" /proc/cpuinfo
|
||||
return $?
|
||||
}
|
||||
|
||||
get_pi_type() {
|
||||
if is_pione; then
|
||||
echo 1
|
||||
elif is_pitwo; then
|
||||
echo 2
|
||||
else
|
||||
echo 0
|
||||
fi
|
||||
}
|
||||
|
||||
is_live() {
|
||||
grep -q "boot=live" $CMDLINE
|
||||
return $?
|
||||
}
|
||||
|
||||
is_ssh() {
|
||||
if pstree -p | egrep --quiet --extended-regexp ".*sshd.*\($$\)"; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
is_fkms() {
|
||||
if grep -s -q okay /proc/device-tree/soc/v3d@7ec00000/status \
|
||||
/proc/device-tree/soc/firmwarekms@7e600000/status \
|
||||
/proc/device-tree/v3dbus/v3d@7ec04000/status; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
is_pulseaudio() {
|
||||
PS=$(ps ax)
|
||||
echo "$PS" | grep -q pulseaudio
|
||||
return $?
|
||||
}
|
||||
|
||||
has_analog() {
|
||||
if [ $(get_leds) -eq -1 ] ; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
is_installed() {
|
||||
if [ "$(dpkg -l "$1" 2> /dev/null | tail -n 1 | cut -d ' ' -f 1)" != "ii" ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
deb_ver () {
|
||||
ver=`cat /etc/debian_version | cut -d . -f 1`
|
||||
echo $ver
|
||||
}
|
||||
|
||||
calc_wt_size() {
|
||||
# NOTE: it's tempting to redirect stderr to /dev/null, so supress error
|
||||
# output from tput. However in this case, tput detects neither stdout or
|
||||
# stderr is a tty and so only gives default 80, 24 values
|
||||
WT_HEIGHT=18
|
||||
WT_WIDTH=$(tput cols)
|
||||
|
||||
if [ -z "$WT_WIDTH" ] || [ "$WT_WIDTH" -lt 60 ]; then
|
||||
WT_WIDTH=80
|
||||
fi
|
||||
if [ "$WT_WIDTH" -gt 178 ]; then
|
||||
WT_WIDTH=120
|
||||
fi
|
||||
WT_MENU_HEIGHT=$(($WT_HEIGHT-7))
|
||||
}
|
||||
|
||||
set_config_var() {
|
||||
lua - "$1" "$2" "$3" <<EOF > "$3.bak"
|
||||
local key=assert(arg[1])
|
||||
local value=assert(arg[2])
|
||||
local fn=assert(arg[3])
|
||||
local file=assert(io.open(fn))
|
||||
local made_change=false
|
||||
for line in file:lines() do
|
||||
if line:match("^#?%s*"..key.."=.*$") then
|
||||
line=key.."="..value
|
||||
made_change=true
|
||||
end
|
||||
print(line)
|
||||
end
|
||||
|
||||
if not made_change then
|
||||
print(key.."="..value)
|
||||
end
|
||||
EOF
|
||||
mv "$3.bak" "$3"
|
||||
}
|
||||
|
||||
clear_config_var() {
|
||||
lua - "$1" "$2" <<EOF > "$2.bak"
|
||||
local key=assert(arg[1])
|
||||
local fn=assert(arg[2])
|
||||
local file=assert(io.open(fn))
|
||||
for line in file:lines() do
|
||||
if line:match("^%s*"..key.."=.*$") then
|
||||
line="#"..line
|
||||
end
|
||||
print(line)
|
||||
end
|
||||
EOF
|
||||
mv "$2.bak" "$2"
|
||||
}
|
||||
|
||||
get_config_var() {
|
||||
lua - "$1" "$2" <<EOF
|
||||
local key=assert(arg[1])
|
||||
local fn=assert(arg[2])
|
||||
local file=assert(io.open(fn))
|
||||
local found=false
|
||||
for line in file:lines() do
|
||||
local val = line:match("^%s*"..key.."=(.*)$")
|
||||
if (val ~= nil) then
|
||||
print(val)
|
||||
found=true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not found then
|
||||
print(0)
|
||||
end
|
||||
EOF
|
||||
}
|
||||
|
||||
is_number() {
|
||||
case $1 in
|
||||
''|*[!0-9]*) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
do_change_pass() {
|
||||
whiptail --msgbox "You will now be asked to enter a new password for the $USER user" 20 60 1
|
||||
passwd $USER &&
|
||||
whiptail --msgbox "Password changed successfully" 20 60 1
|
||||
}
|
||||
|
||||
do_configure_keyboard() {
|
||||
printf "Reloading keymap. This may take a short while\n"
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
dpkg-reconfigure keyboard-configuration
|
||||
else
|
||||
local KEYMAP="$1"
|
||||
sed -i /etc/default/keyboard -e "s/^XKBLAYOUT.*/XKBLAYOUT=\"$KEYMAP\"/"
|
||||
dpkg-reconfigure -f noninteractive keyboard-configuration
|
||||
fi
|
||||
invoke-rc.d keyboard-setup start
|
||||
setsid sh -c 'exec setupcon -k --force <> /dev/tty1 >&0 2>&1'
|
||||
udevadm trigger --subsystem-match=input --action=change
|
||||
return 0
|
||||
}
|
||||
|
||||
do_change_locale() {
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
dpkg-reconfigure locales
|
||||
else
|
||||
local LOCALE="$1"
|
||||
if ! LOCALE_LINE="$(grep "^$LOCALE " /usr/share/i18n/SUPPORTED)"; then
|
||||
return 1
|
||||
fi
|
||||
local ENCODING="$(echo $LOCALE_LINE | cut -f2 -d " ")"
|
||||
echo "$LOCALE $ENCODING" > /etc/locale.gen
|
||||
sed -i "s/^\s*LANG=\S*/LANG=$LOCALE/" /etc/default/locale
|
||||
dpkg-reconfigure -f noninteractive locales
|
||||
fi
|
||||
}
|
||||
|
||||
do_change_timezone() {
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
dpkg-reconfigure tzdata
|
||||
else
|
||||
local TIMEZONE="$1"
|
||||
if [ ! -f "/usr/share/zoneinfo/$TIMEZONE" ]; then
|
||||
return 1;
|
||||
fi
|
||||
rm /etc/localtime
|
||||
echo "$TIMEZONE" > /etc/timezone
|
||||
dpkg-reconfigure -f noninteractive tzdata
|
||||
fi
|
||||
}
|
||||
|
||||
get_wifi_country() {
|
||||
CODE=${1:-0}
|
||||
IFACE="$(list_wlan_interfaces | head -n 1)"
|
||||
if [ -z "$IFACE" ]; then
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
whiptail --msgbox "No wireless interface found" 20 60
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
if ! wpa_cli -i "$IFACE" status > /dev/null 2>&1; then
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
whiptail --msgbox "Could not communicate with wpa_supplicant" 20 60
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
wpa_cli -i "$IFACE" save_config > /dev/null 2>&1
|
||||
COUNTRY="$(wpa_cli -i "$IFACE" get country)"
|
||||
if [ "$COUNTRY" = "FAIL" ]; then
|
||||
return 1
|
||||
fi
|
||||
if [ $CODE = 0 ]; then
|
||||
echo "$COUNTRY"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
do_wifi_country() {
|
||||
IFACE="$(list_wlan_interfaces | head -n 1)"
|
||||
if [ -z "$IFACE" ]; then
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
whiptail --msgbox "No wireless interface found" 20 60
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! wpa_cli -i "$IFACE" status > /dev/null 2>&1; then
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
whiptail --msgbox "Could not communicate with wpa_supplicant" 20 60
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
|
||||
oIFS="$IFS"
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
value=$(cat /usr/share/zoneinfo/iso3166.tab | tail -n +26 | tr '\t' '/' | tr '\n' '/')
|
||||
IFS="/"
|
||||
COUNTRY=$(whiptail --menu "Select the country in which the Pi is to be used" 20 60 10 ${value} 3>&1 1>&2 2>&3)
|
||||
else
|
||||
COUNTRY=$1
|
||||
true
|
||||
fi
|
||||
if [ $? -eq 0 ];then
|
||||
wpa_cli -i "$IFACE" set country "$COUNTRY"
|
||||
wpa_cli -i "$IFACE" save_config > /dev/null 2>&1
|
||||
if iw reg set "$COUNTRY" 2> /dev/null; then
|
||||
ASK_TO_REBOOT=1
|
||||
fi
|
||||
if hash rfkill 2> /dev/null; then
|
||||
rfkill unblock wifi
|
||||
if is_pi ; then
|
||||
for filename in /var/lib/systemd/rfkill/*:wlan ; do
|
||||
echo 0 > $filename
|
||||
done
|
||||
fi
|
||||
fi
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
whiptail --msgbox "Wireless LAN country set to $COUNTRY" 20 60 1
|
||||
fi
|
||||
fi
|
||||
IFS=$oIFS
|
||||
}
|
||||
|
||||
get_ssh() {
|
||||
if service ssh status | grep -q inactive; then
|
||||
echo 1
|
||||
else
|
||||
echo 0
|
||||
fi
|
||||
}
|
||||
|
||||
do_ssh() {
|
||||
if [ -e /var/log/regen_ssh_keys.log ] && ! grep -q "^finished" /var/log/regen_ssh_keys.log; then
|
||||
whiptail --msgbox "Initial ssh key generation still running. Please wait and try again." 20 60 2
|
||||
return 1
|
||||
fi
|
||||
DEFAULT=--defaultno
|
||||
if [ $(get_ssh) -eq 0 ]; then
|
||||
DEFAULT=
|
||||
fi
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
whiptail --yesno \
|
||||
"Would you like the SSH server to be enabled?\n\nCaution: Default and weak passwords are a security risk when SSH is enabled!" \
|
||||
$DEFAULT 20 60 2
|
||||
RET=$?
|
||||
else
|
||||
RET=$1
|
||||
fi
|
||||
if [ $RET -eq 0 ]; then
|
||||
ssh-keygen -A &&
|
||||
update-rc.d ssh enable &&
|
||||
invoke-rc.d ssh start &&
|
||||
STATUS=enabled
|
||||
elif [ $RET -eq 1 ]; then
|
||||
update-rc.d ssh disable &&
|
||||
invoke-rc.d ssh stop &&
|
||||
STATUS=disabled
|
||||
else
|
||||
return $RET
|
||||
fi
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
whiptail --msgbox "The SSH server is $STATUS" 20 60 1
|
||||
fi
|
||||
}
|
||||
|
||||
get_vnc() {
|
||||
if systemctl status vncserver-x11-serviced.service | grep -q -w active; then
|
||||
echo 0
|
||||
else
|
||||
echo 1
|
||||
fi
|
||||
}
|
||||
|
||||
do_vnc() {
|
||||
DEFAULT=--defaultno
|
||||
if [ $(get_vnc) -eq 0 ]; then
|
||||
DEFAULT=
|
||||
fi
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
whiptail --yesno "Would you like the VNC Server to be enabled?" $DEFAULT 20 60 2
|
||||
RET=$?
|
||||
else
|
||||
RET=$1
|
||||
fi
|
||||
if [ $RET -eq 0 ]; then
|
||||
if is_installed realvnc-vnc-server || apt-get install realvnc-vnc-server; then
|
||||
systemctl enable vncserver-x11-serviced.service &&
|
||||
systemctl start vncserver-x11-serviced.service &&
|
||||
STATUS=enabled
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
elif [ $RET -eq 1 ]; then
|
||||
if is_installed realvnc-vnc-server; then
|
||||
systemctl disable vncserver-x11-serviced.service
|
||||
systemctl stop vncserver-x11-serviced.service
|
||||
fi
|
||||
STATUS=disabled
|
||||
else
|
||||
return $RET
|
||||
fi
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
whiptail --msgbox "The VNC Server is $STATUS" 20 60 1
|
||||
fi
|
||||
}
|
||||
|
||||
disable_raspi_config_at_boot() {
|
||||
if [ -e /etc/profile.d/birdnetpi-config.sh ]; then
|
||||
rm -f /etc/profile.d/birdnetpi-config.sh
|
||||
if [ -e /etc/systemd/system/getty@tty1.service.d/birdnetpi-config-override.conf ]; then
|
||||
rm /etc/systemd/system/getty@tty1.service.d/birdnetpi-config-override.conf
|
||||
fi
|
||||
telinit q
|
||||
fi
|
||||
}
|
||||
|
||||
get_boot_cli() {
|
||||
if systemctl get-default | grep -q multi-user ; then
|
||||
echo 0
|
||||
else
|
||||
echo 1
|
||||
fi
|
||||
}
|
||||
|
||||
get_autologin() {
|
||||
if [ $(get_boot_cli) -eq 0 ]; then
|
||||
# booting to CLI
|
||||
# stretch or buster - is there an autologin conf file?
|
||||
if [ -e /etc/systemd/system/getty@tty1.service.d/autologin.conf ] ; then
|
||||
echo 0
|
||||
else
|
||||
# stretch or earlier - check the getty service symlink for autologin
|
||||
if [ $(deb_ver) -le 9 ] && grep -q autologin /etc/systemd/system/getty.target.wants/getty@tty1.service ; then
|
||||
echo 0
|
||||
else
|
||||
echo 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# booting to desktop - check the autologin for lightdm
|
||||
if grep -q "^autologin-user=" /etc/lightdm/lightdm.conf ; then
|
||||
echo 0
|
||||
else
|
||||
echo 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
do_update() {
|
||||
apt-get update &&
|
||||
apt-get install birdnetpi-config &&
|
||||
printf "Sleeping 5 seconds before reloading birdnetpi-config\n" &&
|
||||
sleep 5 &&
|
||||
exec birdnetpi-config
|
||||
}
|
||||
|
||||
do_audio() {
|
||||
if is_pulseaudio ; then
|
||||
oIFS="$IFS"
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
list=$(sudo -u $SUDO_USER XDG_RUNTIME_DIR=/run/user/$SUDO_UID pacmd list-sinks | grep -e index -e alsa.name | sed s/*//g | sed s/^[' '\\t]*//g | sed s/'index: '//g | sed s/'alsa.name = '//g | sed s/'bcm2835 '//g | sed s/\"//g | tr '\n' '/')
|
||||
if ! [ -z "$list" ] ; then
|
||||
IFS="/"
|
||||
AUDIO_OUT=$(whiptail --menu "Choose the audio output" 20 60 10 ${list} 3>&1 1>&2 2>&3)
|
||||
else
|
||||
whiptail --msgbox "No internal audio devices found" 20 60 1
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
AUDIO_OUT=$1
|
||||
true
|
||||
fi
|
||||
if [ $? -eq 0 ]; then
|
||||
sudo -u $SUDO_USER XDG_RUNTIME_DIR=/run/user/$SUDO_UID pactl set-default-sink $AUDIO_OUT
|
||||
fi
|
||||
IFS=$oIFS
|
||||
else
|
||||
if aplay -l | grep -q "bcm2835 ALSA"; then
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
AUDIO_OUT=$(whiptail --menu "Choose the audio output" 20 60 10 \
|
||||
"0" "Auto" \
|
||||
"1" "Force 3.5mm ('headphone') jack" \
|
||||
"2" "Force HDMI" \
|
||||
3>&1 1>&2 2>&3)
|
||||
else
|
||||
AUDIO_OUT=$1
|
||||
fi
|
||||
if [ $? -eq 0 ]; then
|
||||
amixer cset numid=3 "$AUDIO_OUT"
|
||||
fi
|
||||
else
|
||||
ASPATH=$(getent passwd $USER | cut -d : -f 6)/.asoundrc
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
CARD0=$(LC_ALL=C aplay -l | grep bcm2835 | grep "card 0" | cut -d [ -f 3 | cut -d ] -f 1 | cut -d ' ' -f 2-)
|
||||
CARD1=$(LC_ALL=C aplay -l | grep bcm2835 | grep "card 1" | cut -d [ -f 3 | cut -d ] -f 1 | cut -d ' ' -f 2-)
|
||||
CARD2=$(LC_ALL=C aplay -l | grep bcm2835 | grep "card 2" | cut -d [ -f 3 | cut -d ] -f 1 | cut -d ' ' -f 2-)
|
||||
if ! [ -z "$CARD2" ]; then
|
||||
AUDIO_OUT=$(whiptail --menu "Choose the audio output" 20 60 10 \
|
||||
"0" "$CARD0" \
|
||||
"1" "$CARD1" \
|
||||
"2" "$CARD2" \
|
||||
3>&1 1>&2 2>&3)
|
||||
elif ! [ -z "$CARD1" ]; then
|
||||
AUDIO_OUT=$(whiptail --menu "Choose the audio output" 20 60 10 \
|
||||
"0" "$CARD0" \
|
||||
"1" "$CARD1" \
|
||||
3>&1 1>&2 2>&3)
|
||||
elif ! [ -z "$CARD0" ]; then
|
||||
AUDIO_OUT=$(whiptail --menu "Choose the audio output" 20 60 10 \
|
||||
"0" "$CARD0" \
|
||||
3>&1 1>&2 2>&3)
|
||||
else
|
||||
whiptail --msgbox "No internal audio devices found" 20 60 1
|
||||
false
|
||||
fi
|
||||
else
|
||||
AUDIO_OUT=$1
|
||||
fi
|
||||
if [ $? -eq 0 ]; then
|
||||
cat << EOF > $ASPATH
|
||||
pcm.!default {
|
||||
type asym
|
||||
playback.pcm {
|
||||
type plug
|
||||
slave.pcm "output"
|
||||
}
|
||||
capture.pcm {
|
||||
type plug
|
||||
slave.pcm "input"
|
||||
}
|
||||
}
|
||||
|
||||
pcm.output {
|
||||
type hw
|
||||
card $AUDIO_OUT
|
||||
}
|
||||
|
||||
ctl.!default {
|
||||
type hw
|
||||
card $AUDIO_OUT
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
do_resolution() {
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
CMODE=$(get_config_var hdmi_mode $CONFIG)
|
||||
CGROUP=$(get_config_var hdmi_group $CONFIG)
|
||||
if [ $CMODE -eq 0 ] ; then
|
||||
CSET="Default"
|
||||
elif [ $CGROUP -eq 2 ] ; then
|
||||
CSET="DMT Mode "$CMODE
|
||||
else
|
||||
CSET="CEA Mode "$CMODE
|
||||
fi
|
||||
oIFS="$IFS"
|
||||
IFS="/"
|
||||
if tvservice -d /dev/null | grep -q Nothing ; then
|
||||
value="Default/720x480/DMT Mode 4/640x480 60Hz 4:3/DMT Mode 9/800x600 60Hz 4:3/DMT Mode 16/1024x768 60Hz 4:3/DMT Mode 85/1280x720 60Hz 16:9/DMT Mode 35/1280x1024 60Hz 5:4/DMT Mode 51/1600x1200 60Hz 4:3/DMT Mode 82/1920x1080 60Hz 16:9/"
|
||||
else
|
||||
value="Default/Monitor preferred resolution/"
|
||||
value=$value$(tvservice -m CEA | grep progressive | cut -b 12- | sed 's/mode \([0-9]\+\): \([0-9]\+\)x\([0-9]\+\) @ \([0-9]\+\)Hz \([0-9]\+\):\([0-9]\+\), clock:[0-9]\+MHz progressive/CEA Mode \1\/\2x\3 \4Hz \5:\6/' | tr '\n' '/')
|
||||
value=$value$(tvservice -m DMT | grep progressive | cut -b 12- | sed 's/mode \([0-9]\+\): \([0-9]\+\)x\([0-9]\+\) @ \([0-9]\+\)Hz \([0-9]\+\):\([0-9]\+\), clock:[0-9]\+MHz progressive/DMT Mode \1\/\2x\3 \4Hz \5:\6/' | tr '\n' '/')
|
||||
fi
|
||||
RES=$(whiptail --default-item $CSET --menu "Choose screen resolution" 20 60 10 ${value} 3>&1 1>&2 2>&3)
|
||||
STATUS=$?
|
||||
IFS=$oIFS
|
||||
if [ $STATUS -eq 0 ] ; then
|
||||
GRS=$(echo "$RES" | cut -d ' ' -f 1)
|
||||
MODE=$(echo "$RES" | cut -d ' ' -f 3)
|
||||
if [ $GRS = "Default" ] ; then
|
||||
MODE=0
|
||||
elif [ $GRS = "DMT" ] ; then
|
||||
GROUP=2
|
||||
else
|
||||
GROUP=1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
GROUP=$1
|
||||
MODE=$2
|
||||
STATUS=0
|
||||
fi
|
||||
if [ $STATUS -eq 0 ]; then
|
||||
if [ $MODE -eq 0 ]; then
|
||||
clear_config_var hdmi_force_hotplug $CONFIG
|
||||
clear_config_var hdmi_group $CONFIG
|
||||
clear_config_var hdmi_mode $CONFIG
|
||||
else
|
||||
set_config_var hdmi_force_hotplug 1 $CONFIG
|
||||
set_config_var hdmi_group $GROUP $CONFIG
|
||||
set_config_var hdmi_mode $MODE $CONFIG
|
||||
fi
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
if [ $MODE -eq 0 ] ; then
|
||||
whiptail --msgbox "The resolution is set to default" 20 60 1
|
||||
else
|
||||
whiptail --msgbox "The resolution is set to $GRS mode $MODE" 20 60 1
|
||||
fi
|
||||
fi
|
||||
if [ $MODE -eq 0 ] ; then
|
||||
TSET="Default"
|
||||
elif [ $GROUP -eq 2 ] ; then
|
||||
TSET="DMT Mode "$MODE
|
||||
else
|
||||
TSET="CEA Mode "$MODE
|
||||
fi
|
||||
if [ "$TSET" != "$CSET" ] ; then
|
||||
ASK_TO_REBOOT=1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
list_wlan_interfaces() {
|
||||
for dir in /sys/class/net/*/wireless; do
|
||||
if [ -d "$dir" ]; then
|
||||
basename "$(dirname "$dir")"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
do_wifi_ssid_passphrase() {
|
||||
RET=0
|
||||
IFACE_LIST="$(list_wlan_interfaces)"
|
||||
IFACE="$(echo "$IFACE_LIST" | head -n 1)"
|
||||
|
||||
if [ -z "$IFACE" ]; then
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
whiptail --msgbox "No wireless interface found" 20 60
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! wpa_cli -i "$IFACE" status > /dev/null 2>&1; then
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
whiptail --msgbox "Could not communicate with wpa_supplicant" 20 60
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$INTERACTIVE" = True ] && [ -z "$(get_wifi_country)" ]; then
|
||||
do_wifi_country
|
||||
fi
|
||||
|
||||
SSID="$1"
|
||||
while [ -z "$SSID" ] && [ "$INTERACTIVE" = True ]; do
|
||||
SSID=$(whiptail --inputbox "Please enter SSID" 20 60 3>&1 1>&2 2>&3)
|
||||
if [ $? -ne 0 ]; then
|
||||
return 0
|
||||
elif [ -z "$SSID" ]; then
|
||||
whiptail --msgbox "SSID cannot be empty. Please try again." 20 60
|
||||
fi
|
||||
done
|
||||
|
||||
PASSPHRASE="$2"
|
||||
while [ "$INTERACTIVE" = True ]; do
|
||||
PASSPHRASE=$(whiptail --passwordbox "Please enter passphrase. Leave it empty if none." 20 60 3>&1 1>&2 2>&3)
|
||||
if [ $? -ne 0 ]; then
|
||||
return 0
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Escape special characters for embedding in regex below
|
||||
local ssid="$(echo "$SSID" \
|
||||
| sed 's;\\;\\\\;g' \
|
||||
| sed -e 's;\.;\\\.;g' \
|
||||
-e 's;\*;\\\*;g' \
|
||||
-e 's;\+;\\\+;g' \
|
||||
-e 's;\?;\\\?;g' \
|
||||
-e 's;\^;\\\^;g' \
|
||||
-e 's;\$;\\\$;g' \
|
||||
-e 's;\/;\\\/;g' \
|
||||
-e 's;\[;\\\[;g' \
|
||||
-e 's;\];\\\];g' \
|
||||
-e 's;{;\\{;g' \
|
||||
-e 's;};\\};g' \
|
||||
-e 's;(;\\(;g' \
|
||||
-e 's;);\\);g' \
|
||||
-e 's;";\\\\\";g')"
|
||||
|
||||
wpa_cli -i "$IFACE" list_networks \
|
||||
| tail -n +2 | cut -f -2 | grep -P "\t$ssid$" | cut -f1 \
|
||||
| while read ID; do
|
||||
wpa_cli -i "$IFACE" remove_network "$ID" > /dev/null 2>&1
|
||||
done
|
||||
|
||||
ID="$(wpa_cli -i "$IFACE" add_network)"
|
||||
wpa_cli -i "$IFACE" set_network "$ID" ssid "\"$SSID\"" 2>&1 | grep -q "OK"
|
||||
RET=$((RET + $?))
|
||||
|
||||
if [ -z "$PASSPHRASE" ]; then
|
||||
wpa_cli -i "$IFACE" set_network "$ID" key_mgmt NONE 2>&1 | grep -q "OK"
|
||||
RET=$((RET + $?))
|
||||
else
|
||||
wpa_cli -i "$IFACE" set_network "$ID" psk "\"$PASSPHRASE\"" 2>&1 | grep -q "OK"
|
||||
RET=$((RET + $?))
|
||||
fi
|
||||
|
||||
if [ $RET -eq 0 ]; then
|
||||
wpa_cli -i "$IFACE" enable_network "$ID" > /dev/null 2>&1
|
||||
else
|
||||
wpa_cli -i "$IFACE" remove_network "$ID" > /dev/null 2>&1
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
whiptail --msgbox "Failed to set SSID or passphrase" 20 60
|
||||
fi
|
||||
fi
|
||||
wpa_cli -i "$IFACE" save_config > /dev/null 2>&1
|
||||
|
||||
echo "$IFACE_LIST" | while read IFACE; do
|
||||
wpa_cli -i "$IFACE" reconfigure > /dev/null 2>&1
|
||||
done
|
||||
|
||||
return $RET
|
||||
}
|
||||
|
||||
do_update() {
|
||||
apt update && apt -y full-upgrade
|
||||
ASK_TO_REBOOT=1
|
||||
}
|
||||
|
||||
do_install_birdnet() {
|
||||
${my_dir}/Birders_Guide_Installer.sh
|
||||
ASK_TO_REBOOT=1
|
||||
}
|
||||
|
||||
do_finish() {
|
||||
disable_raspi_config_at_boot
|
||||
if [ $ASK_TO_REBOOT -eq 1 ]; then
|
||||
whiptail --yesno "Would you like to reboot now?" 20 60 2
|
||||
if [ $? -eq 0 ]; then # yes
|
||||
sync
|
||||
reboot
|
||||
fi
|
||||
fi
|
||||
exit 0
|
||||
}
|
||||
# Everything else needs to be run as root
|
||||
if [ $(id -u) -ne 0 ]; then
|
||||
printf "Script must be run as root. Try 'sudo birdnetpi-config'\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "${OPT_MEMORY_SPLIT:-}" ]; then
|
||||
set -e # Fail when a command errors
|
||||
set_memory_split "${OPT_MEMORY_SPLIT}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
do_system_menu() {
|
||||
if is_pi ; then
|
||||
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnetpi-config)" --menu "System Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
|
||||
"Password" "Change password for the '$USER' user" \
|
||||
"Audio" "Select audio device you'd like BirdNET-Pi to use" \
|
||||
"Wireless LAN" "Enter SSID and passphrase" \
|
||||
3>&1 1>&2 2>&3)
|
||||
else
|
||||
exit
|
||||
fi
|
||||
RET=$?
|
||||
if [ $RET -eq 1 ]; then
|
||||
return 0
|
||||
elif [ $RET -eq 0 ]; then
|
||||
case "$FUN" in
|
||||
Password*) do_change_pass ;;
|
||||
Audio*) do_audio ;;
|
||||
Wireless*) do_wifi_ssid_passphrase ;;
|
||||
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
|
||||
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
|
||||
fi
|
||||
}
|
||||
|
||||
do_display_menu() {
|
||||
if is_pi ; then
|
||||
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnetpi-config)" --menu "Display Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
|
||||
"Resolution" "Set a specific screen resolution" \
|
||||
3>&1 1>&2 2>&3)
|
||||
else
|
||||
exit
|
||||
fi
|
||||
RET=$?
|
||||
if [ $RET -eq 1 ]; then
|
||||
return 0
|
||||
elif [ $RET -eq 0 ]; then
|
||||
case "$FUN" in
|
||||
Resolution*) do_resolution ;;
|
||||
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
|
||||
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
|
||||
fi
|
||||
}
|
||||
|
||||
do_interface_menu() {
|
||||
if is_pi ; then
|
||||
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnetpi-config)" --menu "Interfacing Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
|
||||
"SSH" "Enable/disable remote command line access using SSH" \
|
||||
"VNC" "Enable/disable graphical remote access using RealVNC" \
|
||||
3>&1 1>&2 2>&3)
|
||||
else
|
||||
exit
|
||||
fi
|
||||
RET=$?
|
||||
if [ $RET -eq 1 ]; then
|
||||
return 0
|
||||
elif [ $RET -eq 0 ]; then
|
||||
case "$FUN" in
|
||||
SSH*) do_ssh ;;
|
||||
VNC*) do_vnc ;;
|
||||
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
|
||||
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
|
||||
fi
|
||||
}
|
||||
|
||||
do_internationalisation_menu() {
|
||||
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnetpi-config)" --menu "Localisation Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \
|
||||
"Locale" "Configure language and regional settings" \
|
||||
"Timezone" "Configure time zone" \
|
||||
"Keyboard" "Set keyboard layout to match your keyboard" \
|
||||
"WLAN Country" "Set legal wireless channels for your country" \
|
||||
3>&1 1>&2 2>&3)
|
||||
RET=$?
|
||||
if [ $RET -eq 1 ]; then
|
||||
return 0
|
||||
elif [ $RET -eq 0 ]; then
|
||||
case "$FUN" in
|
||||
Locale*) do_change_locale ;;
|
||||
Time*) do_change_timezone ;;
|
||||
Key*) do_configure_keyboard ;;
|
||||
WLAN*) do_wifi_country ;;
|
||||
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
|
||||
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
|
||||
fi
|
||||
}
|
||||
#
|
||||
# Interactive use loop
|
||||
#
|
||||
if [ "$INTERACTIVE" = True ]; then
|
||||
[ -e $CONFIG ] || touch $CONFIG
|
||||
calc_wt_size
|
||||
while [ "$USER" = "root" ] || [ -z "$USER" ]; do
|
||||
if ! USER=$(whiptail --inputbox "birdnetpi-config could not determine the default user.\\n\\nWhat user should these settings apply to?" 20 60 pi 3>&1 1>&2 2>&3); then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
while true; do
|
||||
if is_pi ; then
|
||||
FUN=$(whiptail --title "BirdNET-Pi Software Configuration Tool (birdnetpi-config)" --backtitle "$(cat /proc/device-tree/model)" --menu "Setup Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Finish --ok-button Select \
|
||||
"System Options" "Configure system settings" \
|
||||
"Display Options" "Configure display settings" \
|
||||
"Interface Options" "Configure connections to peripherals" \
|
||||
"Localisation Options" "Configure language and regional settings" \
|
||||
"Update the OS" "Update the underlying operating system" \
|
||||
"Install BirdNET-PI" "Install BirdNET-Pi" \
|
||||
3>&1 1>&2 2>&3)
|
||||
else
|
||||
exit
|
||||
fi
|
||||
RET=$?
|
||||
if [ $RET -eq 1 ]; then
|
||||
do_finish
|
||||
elif [ $RET -eq 0 ]; then
|
||||
case "$FUN" in
|
||||
System*) do_system_menu ;;
|
||||
Display*) do_display_menu ;;
|
||||
Interface*) do_interface_menu ;;
|
||||
Localisation*) do_internationalisation_menu ;;
|
||||
Update*) do_update;;
|
||||
Install*) do_install_birdnet;;
|
||||
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
|
||||
esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
fi
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
shell_exec("/home/pi/BirdNET-Pi/scripts/clear_all_data.sh");
|
||||
header('Location: http://birdnetpi.local/scripts/index.html?success=true');
|
||||
header('Location: /viewdb.php');
|
||||
?>
|
||||
|
||||
+3
-14
@@ -3,25 +3,14 @@
|
||||
# set -x # Uncomment to debug
|
||||
source /etc/birdnet/birdnet.conf &> /dev/null
|
||||
LOG_DIR="${HOME}/BirdNET-Pi/logs"
|
||||
SERVICES=(avahi-alias@.service
|
||||
birdnet_analysis.service
|
||||
birdnet_log.service
|
||||
birdnet_recording.service
|
||||
birdstats.service
|
||||
birdterminal.service
|
||||
caddy.service
|
||||
extraction_log.service
|
||||
extraction.service
|
||||
extraction.timer
|
||||
icecast2.service
|
||||
livestream.service
|
||||
${SYSTEMD_MOUNT})
|
||||
|
||||
services=$(awk '/service/ && /systemctl/ && !/php/ {print $3}' ${my_dir}/install_services.sh | sort)
|
||||
|
||||
# Create logs directory
|
||||
[ -d ${LOG_DIR} ] || mkdir ${LOG_DIR}
|
||||
|
||||
# Create services logs
|
||||
for i in "${SERVICES[@]}";do
|
||||
for i in "${services[@]}";do
|
||||
if [ -L /etc/systemd/system/multi-user.target.wants/${i} ];then
|
||||
journalctl -u ${i} -n 100 --no-pager > ${LOG_DIR}/${i}.log
|
||||
cp -L /etc/systemd/system/multi-user.target.wants/${i} ${LOG_DIR}/${i}
|
||||
|
||||
+4
-1
@@ -27,12 +27,15 @@
|
||||
<input type="submit" value="Restart Caddy">
|
||||
</form>
|
||||
|
||||
<form action="/scripts/backup_data.php" onclick="return confirm('Backup ALL Data? Warning: This could take a long time.')">
|
||||
<input type="submit" value="Backup ALL data">
|
||||
</form>
|
||||
|
||||
<form action="/scripts/clear_all_data.php" onclick="return confirm('Clear ALL Data? This cannot be undone.')">
|
||||
<input type="submit" value="Clear ALL data">
|
||||
</form>
|
||||
|
||||
<form action="/scripts/update_birdnet.php" onclick="return confirm('Are you sure you want to update?')">
|
||||
<form action="/scripts/update_birdnet.php" onclick="return confirm('BE SURE TO STASH ANY LOCAL CHANGES YOU HAVE MADE TO THE SYSTEM BEFORE UPDATING!!!')">
|
||||
<input type="submit" value="Update BirdNET-Pi">
|
||||
</form>
|
||||
|
||||
|
||||
@@ -98,10 +98,7 @@ echo " BirdNet is installed!!
|
||||
'sudo systemctl disable --now birdnet_analysis.service'
|
||||
|
||||
Visit
|
||||
http://birdnetpi.local to see your extractions,
|
||||
http://birdlog.local to see the log output of the birdnet_analysis.service,
|
||||
http://extractionlog.local to see the log output of the extraction.service, and
|
||||
http://birdstats.local to see the BirdNET-Pi Report"
|
||||
the BirdNET-Pi homepage at http://birdnetpi.local"
|
||||
echo
|
||||
read -n1 -p " Would you like to run the birdnet_analysis.service now?" YN
|
||||
echo
|
||||
|
||||
@@ -43,7 +43,7 @@ get_DO_RECORDING() {
|
||||
done
|
||||
}
|
||||
|
||||
get_EXTRACTIONS_URL() {
|
||||
get_BIRDNETPI_URL() {
|
||||
while true;do
|
||||
read -n1 -p "Would you like to access the extractions via a web browser?
|
||||
|
||||
@@ -56,11 +56,11 @@ get_EXTRACTIONS_URL() {
|
||||
case $CADDY_SERVICE in
|
||||
[Yy] ) read -p "What URL would you like to publish the extractions to?
|
||||
*Note: Set this to http://localhost if you do not want to make the
|
||||
extractions publically available: " EXTRACTIONS_URL
|
||||
extractions publically available: " BIRDNETPI_URL
|
||||
get_CADDY_PWD
|
||||
get_ICE_PWD
|
||||
break;;
|
||||
[Nn] ) EXTRACTIONS_URL= CADDY_PWD= ICE_PWD=;break;;
|
||||
[Nn] ) BIRDNETPI_URL= CADDY_PWD= ICE_PWD=;break;;
|
||||
* ) echo "Please answer Yes or No";;
|
||||
esac
|
||||
done
|
||||
@@ -165,7 +165,7 @@ configure() {
|
||||
get_DB_PWDS
|
||||
get_DO_EXTRACTIONS
|
||||
get_DO_RECORDING
|
||||
get_EXTRACTIONS_URL
|
||||
get_BIRDNETPI_URL
|
||||
get_PUSHED
|
||||
get_INSTALL_NOMACHINE
|
||||
get_CHANNELS
|
||||
@@ -226,19 +226,21 @@ DO_RECORDING=${DO_RECORDING}
|
||||
|
||||
################################################################################
|
||||
#----------------------- Web-hosting/Caddy File-server -----------------------#
|
||||
#__________The two variables below can be set to enable web access_____________#
|
||||
#________The four variables below can be set to enable internet access_________#
|
||||
#____________to your data,(e.g., extractions, raw data, live___________________#
|
||||
#______________audio stream, BirdNET.selection.txt files)______________________#
|
||||
|
||||
# Leave these EMPTY if you do not want to enable web access #
|
||||
|
||||
## EXTRACTIONS_URL is the URL where the extractions, data-set, and live-stream
|
||||
## BIRDNETPI_URL is the URL where the extractions, data-set, and live-stream
|
||||
## will be web-hosted. If you do not own a domain, or would just prefer to keep
|
||||
## BirdNET-Pi on your local network, you can set this to http://localhost.
|
||||
## Setting this (even to http://localhost) will also allow you to enable the
|
||||
## GoTTY web logging features below.
|
||||
|
||||
EXTRACTIONS_URL=${EXTRACTIONS_URL}
|
||||
BIRDNETPI_URL=${BIRDNETPI_URL}
|
||||
EXTRACTIONLOG_URL=${EXTRACTIONLOG_URL}
|
||||
BIRDNETLOG_URL=${BIRDNETLOG_URL}
|
||||
|
||||
## CADDY_PWD is the plaintext password (that will be hashed) and used to access
|
||||
## the "Processed" directory and live audio stream. This MUST be set if you
|
||||
|
||||
+59
-37
@@ -11,6 +11,14 @@ nomachine_url="https://download.nomachine.com/download/7.6/Arm/nomachine_7.6.2_3
|
||||
gotty_url="https://github.com/yudai/gotty/releases/download/v1.0.1/gotty_linux_arm.tar.gz"
|
||||
config_file="$(dirname ${my_dir})/birdnet.conf"
|
||||
|
||||
set_hostname() {
|
||||
if [ "$(hostname)" != "birdnetpi" ];then
|
||||
echo "Setting hostname to 'birdnetpi'"
|
||||
hostnamectl set-hostname birdnetpi
|
||||
sed -i 's/raspberrypi/birdnetpi/g' /etc/hosts
|
||||
fi
|
||||
}
|
||||
|
||||
install_scripts() {
|
||||
echo "Installing BirdNET-Pi scripts to /usr/local/bin"
|
||||
ln -sf ${my_dir}/* /usr/local/bin/
|
||||
@@ -90,7 +98,7 @@ ExecStart=/usr/local/bin/species_notifier.sh
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable --now pushed_notifications
|
||||
systemctl enable pushed_notifications.service
|
||||
}
|
||||
|
||||
create_necessary_dirs() {
|
||||
@@ -100,15 +108,33 @@ create_necessary_dirs() {
|
||||
[ -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 ${PROCESSED} ] || sudo -u ${USER} mkdir -p ${PROCESSED}
|
||||
[ -L ${EXTRACTED}/index.html ] || sudo -u ${USER} ln -s $(dirname ${my_dir})/templates/index.html ${EXTRACTED}
|
||||
[ -L ${EXTRACTED}/scripts ] || sudo -u ${USER} ln -s $(dirname ${my_dir})/scripts ${EXTRACTED}
|
||||
[ -L ${EXTRACTED}/spectrogram.php ] || sudo -u ${USER} ln -s $(dirname ${my_dir})/scripts/spectrogram.* ${EXTRACTED}
|
||||
[ -L ${EXTRACTED}/viewdb.php ] || sudo -u ${USER} ln -s $(dirname ${my_dir})/scripts/viewdb.php ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED}
|
||||
[ -L ${EXTRACTED}/phpsysinfo.ini ] || sudo -u ${USER} cp ${HOME}/phpsysinfo/phpsysinfo.ini.new ${HOME}/phpsysinfo/phpsysinfo.ini
|
||||
|
||||
sudo -u ${USER} ln -fs $(dirname ${my_dir})/homepage/* ${EXTRACTED}
|
||||
if [ ! -z ${BIRDNETLOG_URL} ];then
|
||||
BIRDNETLOG_URL="$(echo ${BIRDNETLOG_URL} | sed 's/\/\//\\\/\\\//g')"
|
||||
sudo -u${USER} sed -i "s/http:\/\/birdnetpi.local:8080/"${BIRDNETLOG_URL}"/g" $(dirname ${my_dir})/homepage/*.html
|
||||
fi
|
||||
if [ ! -z ${EXTRACTIONLOG_URL} ];then
|
||||
EXTRACTIONLOG_URL="$(echo ${EXTRACTIONLOG_URL} | sed 's/\/\//\\\/\\\//g')"
|
||||
sudo -u${USER} sed -i "s/http:\/\/birdnetpi.local:8888/"${EXTRACTIONLOG_URL}"/g" $(dirname ${my_dir})/homepage/*.html
|
||||
fi
|
||||
|
||||
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts ${EXTRACTED}
|
||||
if [ ! -z ${BIRDNETPI_URL} ];then
|
||||
BIRDNETPI_URL="$(echo ${BIRDNETPI_URL} | sed 's/\/\//\\\/\\\//g')"
|
||||
sudo -u${USER} sed -i "s/http:\/\/birdnetpi.local/"${BIRDNETPI_URL}"/g" $(dirname ${my_dir})/homepage/*.html
|
||||
phpfiles="$(grep -l birdnetpi.local ${my_dir}/*.php)"
|
||||
for i in "${phpfiles[@]}";do
|
||||
sudo -u${USER} sed -i "s/http:\/\/birdnetpi.local/"${BIRDNETPI_URL}"/g" ${i}
|
||||
done
|
||||
fi
|
||||
|
||||
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/spectrogram.php ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/viewdb.php ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED}
|
||||
[ -L ${EXTRACTED}/phpsysinfo/phpsysinfo.ini ] || sudo -u ${USER} cp ${HOME}/phpsysinfo/phpsysinfo.ini.new ${HOME}/phpsysinfo/phpsysinfo.ini
|
||||
}
|
||||
|
||||
|
||||
install_alsa() {
|
||||
echo "Checking for alsa-utils and pulseaudio"
|
||||
if which arecord &> /dev/null ;then
|
||||
@@ -172,26 +198,7 @@ install_Caddyfile() {
|
||||
fi
|
||||
HASHWORD=$(caddy hash-password -plaintext ${CADDY_PWD})
|
||||
cat << EOF > /etc/caddy/Caddyfile
|
||||
${EXTRACTIONS_URL} {
|
||||
root * ${EXTRACTED}
|
||||
file_server browse
|
||||
basicauth /Processed* {
|
||||
birdnet ${HASHWORD}
|
||||
}
|
||||
basicauth /scripts* {
|
||||
birdnet ${HASHWORD}
|
||||
}
|
||||
basicauth /stream {
|
||||
birdnet ${HASHWORD}
|
||||
}
|
||||
basicauth /phpsysinfo* {
|
||||
birdnet ${HASHWORD}
|
||||
}
|
||||
reverse_proxy /stream localhost:8000
|
||||
php_fastcgi unix//run/php/php7.3-fpm.sock
|
||||
}
|
||||
|
||||
http://birdnetpi.local {
|
||||
http://localhost http://birdnetpi.local ${BIRDNETPI_URL} {
|
||||
root * ${EXTRACTED}
|
||||
file_server browse
|
||||
basicauth /Processed* {
|
||||
@@ -210,6 +217,22 @@ http://birdnetpi.local {
|
||||
php_fastcgi unix//run/php/php7.3-fpm.sock
|
||||
}
|
||||
EOF
|
||||
if [ ! -z ${EXTRACTIONLOG_URL} ];then
|
||||
cat << EOF >> /etc/caddy/Caddyfile
|
||||
|
||||
${EXTRACTIONLOG_URL} {
|
||||
reverse_proxy localhost:8888
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
if [ ! -z ${BIRDNETLOG_URL} ];then
|
||||
cat << EOF >> /etc/caddy/Caddyfile
|
||||
|
||||
${BIRDNETLOG_URL} {
|
||||
reverse_proxy localhost:8080
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
systemctl reload caddy
|
||||
}
|
||||
|
||||
@@ -234,7 +257,7 @@ ExecStart=/bin/bash -c "/usr/bin/avahi-publish -a -R %I $(avahi-resolve -4 -n %H
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable --now avahi-alias@birdnetpi.local.service
|
||||
systemctl enable avahi-alias@birdnetpi.local.service
|
||||
}
|
||||
|
||||
install_spectrogram_service() {
|
||||
@@ -250,7 +273,7 @@ ExecStart=/usr/local/bin/spectrogram.sh
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable --now spectrogram_viewer.service
|
||||
systemctl enable spectrogram_viewer.service
|
||||
}
|
||||
|
||||
install_gotty_logs() {
|
||||
@@ -277,7 +300,7 @@ ExecStart=/usr/local/bin/gotty -p 8080 --title-format "BirdNET-Pi Log" journalct
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable --now birdnet_log.service
|
||||
systemctl enable birdnet_log.service
|
||||
echo "Installing the extraction_log.service"
|
||||
cat << EOF > /etc/systemd/system/extraction_log.service
|
||||
[Unit]
|
||||
@@ -294,7 +317,7 @@ ExecStart=/usr/local/bin/gotty -p 8888 --title-format "Extractions Log" journalc
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable --now extraction_log.service
|
||||
systemctl enable extraction_log.service
|
||||
}
|
||||
|
||||
install_sox() {
|
||||
@@ -357,12 +380,12 @@ install_icecast() {
|
||||
echo "icecast2 icecast2/icecast-setup boolean false" | debconf-set-selections
|
||||
apt install -qqy icecast2
|
||||
config_icecast
|
||||
systemctl enable --now icecast2
|
||||
systemctl enable icecast2.service
|
||||
/etc/init.d/icecast2 start
|
||||
else
|
||||
echo "Icecast2 is installed"
|
||||
config_icecast
|
||||
systemctl enable --now icecast2
|
||||
systemctl enable icecast2.service
|
||||
/etc/init.d/icecast2 start
|
||||
fi
|
||||
}
|
||||
@@ -395,7 +418,7 @@ ExecStart=/usr/local/bin/livestream.sh
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable --now livestream.service
|
||||
systemctl enable livestream.service
|
||||
}
|
||||
|
||||
install_nomachine() {
|
||||
@@ -419,6 +442,7 @@ install_cleanup_cron() {
|
||||
}
|
||||
|
||||
install_selected_services() {
|
||||
set_hostname
|
||||
install_scripts
|
||||
install_birdnet_analysis
|
||||
|
||||
@@ -431,7 +455,6 @@ install_selected_services() {
|
||||
install_recording_service
|
||||
fi
|
||||
|
||||
if [ ! -z "${EXTRACTIONS_URL}" ];then
|
||||
install_caddy
|
||||
install_Caddyfile
|
||||
install_avahi_aliases
|
||||
@@ -442,7 +465,6 @@ install_selected_services() {
|
||||
install_spectrogram_service
|
||||
install_edit_birdnet_conf
|
||||
install_pushed_notifications
|
||||
fi
|
||||
|
||||
if [ ! -z "${ICE_PWD}" ];then
|
||||
install_icecast
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# This script installs a web-based terminal @ http://birdterminal.local
|
||||
# ONLY run this additional script if you trust everyone on your
|
||||
# local network completely as the credentials are sent WITHOUT
|
||||
# any SSL/TLS encryption. For a secure remote connection to your
|
||||
# BirdNET-Pi command line, consider enabling SSH on the
|
||||
# Raspberry Pi and using another Linux machine or an SSH
|
||||
# client software, or you can alternately add the 'tls internal'
|
||||
# directive to the Caddyfile to add a self-signed certificate for TLS/SSL
|
||||
# encryption. For remote desktop access, NoMachine can be installed.
|
||||
source /etc/birdnet/birdnet.conf
|
||||
my_dir=$(realpath $(dirname $0))
|
||||
|
||||
# Install tmux from version control
|
||||
install_tmux() {
|
||||
DEPENDS=(
|
||||
automake
|
||||
autoconf
|
||||
libevent-2*
|
||||
libevent-dev
|
||||
ncurses-bin
|
||||
ncurses-base
|
||||
ncurses-term
|
||||
libncurses-dev
|
||||
build-essential
|
||||
bison
|
||||
pkg-config
|
||||
gcc
|
||||
)
|
||||
|
||||
if which tmux &>/dev/null; then
|
||||
echo "tmux is installed"
|
||||
else
|
||||
|
||||
sudo apt update && sudo apt -y install "${DEPENDS[@]}"
|
||||
|
||||
cd ${HOME} && git clone https://github.com/tmux/tmux.git
|
||||
cd tmux
|
||||
sh autogen.sh
|
||||
./configure && make && sudo make install
|
||||
cd && rm -drf ./tmux
|
||||
sudo ln -sf "$(dirname ${my_dir})/templates/tmux.conf" /etc/tmux.conf
|
||||
fi
|
||||
}
|
||||
|
||||
install_web_terminal() {
|
||||
cat << EOF | sudo tee /etc/systemd/system/birdterminal.service
|
||||
[Unit]
|
||||
Description=A BirdNET-Pi Web Terminal
|
||||
|
||||
[Service]
|
||||
Restart=on-failure
|
||||
RestartSec=3
|
||||
Type=simple
|
||||
User=${BIRDNET_USER}
|
||||
Environment=TERM=xterm-256color
|
||||
ExecStart=/usr/local/bin/gotty -w --title-format "Login!" -p 9111 tmux new -A -s Login sudo bash -c login
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
HASHWORD="$(caddy hash-password -plaintext "${CADDY_PWD}")"
|
||||
cat << EOF | sudo tee -a /etc/caddy/Caddyfile
|
||||
http://birdterminal.local {
|
||||
reverse_proxy localhost:9111
|
||||
basicauth {
|
||||
birdnet "${HASHWORD}"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
sudo systemctl enable --now birdterminal.service
|
||||
sudo systemctl enable --now avahi-alias@birdterminal.local.service
|
||||
sudo systemctl restart caddy
|
||||
}
|
||||
install_tmux
|
||||
install_web_terminal
|
||||
@@ -1,4 +1,3 @@
|
||||
<?php
|
||||
shell_exec("/home/pi/BirdNET-Pi/scripts/reboot_system.sh");
|
||||
header('Location: http://birdnetpi.local/scripts/index.html?success=true');
|
||||
?>
|
||||
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
# Rebuild DB from BirdDB.txt
|
||||
source /etc/birdnet/birdnet.conf
|
||||
BIRDNET_DIR=/home/pi/BirdNET-Pi
|
||||
sudo ${BIRDNET_DIR}/scripts/createdb.sh
|
||||
sudo mysql birds -e "
|
||||
LOAD DATA LOCAL INFILE '/home/pi/BirdNET-Pi/BirdDB.txt'
|
||||
INTO TABLE detections
|
||||
FIELDS TERMINATED BY ';'"
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
shell_exec("/home/pi/BirdNET-Pi/scripts/restart_birdnet_analysis.sh");
|
||||
header('Location: http://birdnetpi.local/scripts/index.html?success=true');
|
||||
header('Location: /viewdb.php');
|
||||
?>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
shell_exec("/home/pi/BirdNET-Pi/scripts/restart_birdnet_recording.sh");
|
||||
header('Location: http://birdnetpi.local/scripts/index.html?success=true');
|
||||
header('Location: /viewdb.php');
|
||||
?>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
shell_exec("/home/pi/BirdNET-Pi/scripts/restart_caddy.sh");
|
||||
header('Location: http://birdnetpi.local/scripts/index.html?success=true');
|
||||
header('Location: /viewdb.php');
|
||||
?>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
shell_exec("/home/pi/BirdNET-Pi/scripts/restart_extraction.sh");
|
||||
header('Location: http://birdnetpi.local/scripts/index.html?success=true');
|
||||
header('Location: http://birdnetpi.local:8888');
|
||||
?>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
shell_exec("/home/pi/BirdNET-Pi/scripts/restart_services.sh");
|
||||
header('Location: http://birdnetpi.local/scripts/index.html?success=true');
|
||||
header('Location: /viewdb.php');
|
||||
?>
|
||||
|
||||
@@ -1,23 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
# Restarts ALL services and removes ALL unprocessed audio
|
||||
source /etc/birdnet/birdnet.conf
|
||||
my_dir=/home/pi/BirdNET-Pi/scripts
|
||||
|
||||
sudo systemctl stop birdnet_recording.service
|
||||
sudo rm -rf ${RECS_DIR}/$(date +%B-%Y/%d-%A)/*
|
||||
sudo systemctl start birdnet_recording.service
|
||||
|
||||
SERVICES=(avahi-alias@birdlog.local.service
|
||||
avahi-alias@birdnetpi.local.service
|
||||
avahi-alias@birdstats.local.service
|
||||
avahi-alias@extractionlog.local.service
|
||||
birdnet_analysis.service
|
||||
birdnet_log.service
|
||||
birdstats.service
|
||||
extraction.timer
|
||||
extractionlog.service
|
||||
livestream.service)
|
||||
services=($(awk '/service/ && /systemctl/ && !/php/ {print $3}' ${my_dir}/install_services.sh | sort))
|
||||
|
||||
for i in "${SERVICES[@]}";do
|
||||
sudo systemctl restart ${i}
|
||||
for i in "${services[@]}";do
|
||||
sudo systemctl restart "${i}"
|
||||
done
|
||||
|
||||
sudo systemctl restart extraction.timer
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
<?php
|
||||
shell_exec("/home/pi/BirdNET-Pi/scripts/shutdown_system.sh");
|
||||
header('Location: http://birdnetpi.local/scripts/index.html?success=true');
|
||||
?>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
shell_exec("/home/pi/BirdSongs/Extracted/spectrogram.sh");
|
||||
header('Location: http://birdnetpi.local/spectrogram.png');
|
||||
header("refresh: 15;");
|
||||
echo "<body style='background-color:rgb(119, 196, 135)'>";
|
||||
echo "<img src='/spectrogram.png' >";
|
||||
?>
|
||||
|
||||
+2
-22
@@ -45,30 +45,10 @@ uninstall.sh
|
||||
update_species.sh
|
||||
${HOME}/.gotty)
|
||||
|
||||
|
||||
SERVICES=(avahi-alias@birdlog.local.service
|
||||
avahi-alias@birdnetpi.local.service
|
||||
avahi-alias@birdstats.local.service
|
||||
avahi-alias@extractionlog.local.service
|
||||
avahi-alias@birdterminal.local.service
|
||||
birdnet_analysis.service
|
||||
birdnet_log.service
|
||||
birdnet_recording.d
|
||||
birdnet_recording.service
|
||||
birdstats.service
|
||||
birdterminal.service
|
||||
caddy.service
|
||||
edit_birdnet_conf.service
|
||||
extraction_log.service
|
||||
extraction.service
|
||||
extraction.timer
|
||||
livestream.service
|
||||
pushed_notifications.service
|
||||
spectrogram_viewer.service
|
||||
${SYSTEMD_MOUNT})
|
||||
services=$(awk '/service/ && /systemctl/ && !/php/ {print $3}' ${my_dir}/install_services.sh | sort)
|
||||
|
||||
remove_services() {
|
||||
for i in "${SERVICES[@]}"; do
|
||||
for i in "${services[@]}"; do
|
||||
if [ -L /etc/systemd/system/multi-user.target.wants/"${i}" ];then
|
||||
sudo systemctl disable --now "${i}"
|
||||
fi
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
shell_exec("sudo -u pi /home/pi/BirdNET-Pi/scripts/update_birdnet.sh > /tmp/phpupdate.log 2&>1");
|
||||
header('Location: http://birdnetpi.local/index.html?success=true');
|
||||
header('Location: http://birdnetpi.local/scripts/update_inprogress.php');
|
||||
?>
|
||||
|
||||
@@ -8,69 +8,7 @@ HOME=/home/pi
|
||||
my_dir=${HOME}/BirdNET-Pi/scripts
|
||||
tmpfile=$(mktemp)
|
||||
|
||||
scripts=(birdnet_analysis.sh
|
||||
birdnet_recording.sh
|
||||
birdnet_stats.sh
|
||||
cleanup.sh
|
||||
clear_all_data.php
|
||||
clear_all_data.sh
|
||||
createdb.sh
|
||||
disk_usage.sh
|
||||
dump_logs.sh
|
||||
edit_birdnet.conf.php
|
||||
edit_birdnet.conf.sh
|
||||
extract_new_birdsounds.sh
|
||||
install_birdnet.sh
|
||||
install_config.sh
|
||||
install_services.sh
|
||||
install_tmux_services.sh
|
||||
install_zram_service.sh
|
||||
livestream.sh
|
||||
pretty_date.sh
|
||||
reboot_system.php
|
||||
reboot_system.sh
|
||||
reconfigure_birdnet.sh
|
||||
restart_birdnet_analysis.php
|
||||
restart_birdnet_analysis.sh
|
||||
restart_birdnet_recording.php
|
||||
restart_birdnet_recording.sh
|
||||
restart_caddy.php
|
||||
restart_caddy.sh
|
||||
restart_extraction.php
|
||||
restart_extraction.sh
|
||||
restart_services.php
|
||||
restart_services.sh
|
||||
shutdown_system.php
|
||||
shutdown_system.sh
|
||||
species_notifier.sh
|
||||
spectrogram.php
|
||||
spectrogram.sh
|
||||
tmux
|
||||
uninstall.sh
|
||||
update_species.sh
|
||||
${HOME}/.gotty)
|
||||
|
||||
|
||||
# Change this to sourcing from current uninstall.sh
|
||||
# Create a pre-update services array for disabling
|
||||
# Create a post-update services array for restarting
|
||||
services=(avahi-alias@birdlog.local.service
|
||||
avahi-alias@birdnetpi.local.service
|
||||
avahi-alias@birdstats.local.service
|
||||
avahi-alias@extractionlog.local.service
|
||||
avahi-alias@birdterminal.local.service
|
||||
birdnet_analysis.service
|
||||
birdnet_log.service
|
||||
birdnet_recording.service
|
||||
birdstats.service
|
||||
birdterminal.service
|
||||
edit_birdnet_conf.service
|
||||
extraction_log.service
|
||||
extraction.service
|
||||
extraction.timer
|
||||
livestream.service
|
||||
pushed_notifications.service
|
||||
spectrogram_viewer.service)
|
||||
services=$(awk '/service/ && /systemctl/ && !/php/ {print $3}' ${my_dir}/install_services.sh | sort)
|
||||
|
||||
remove_services() {
|
||||
for i in "${services[@]}"; do
|
||||
@@ -109,34 +47,13 @@ remove_scripts() {
|
||||
done
|
||||
}
|
||||
|
||||
restart_services() {
|
||||
for i in ${services[@]};do
|
||||
sudo systemctl restart ${i}
|
||||
done
|
||||
}
|
||||
|
||||
# Stage 1 removes old stuff
|
||||
remove_services
|
||||
remove_scripts
|
||||
|
||||
# Stage 2 does a git pull to fetch new things
|
||||
sudo -u${USER} git -C ${HOME}/BirdNET-Pi pull || exit 1
|
||||
|
||||
# Stage 3 updates the services
|
||||
sudo ${my_dir}/update_services.sh
|
||||
|
||||
# Stage 4 restarts the services
|
||||
services=(avahi-alias@birdnetpi.local.service
|
||||
birdnet_analysis.service
|
||||
birdnet_log.service
|
||||
birdnet_recording.service
|
||||
edit_birdnet_conf.service
|
||||
extraction_log.service
|
||||
extraction.service
|
||||
extraction.timer
|
||||
livestream.service
|
||||
pushed_notifications.service
|
||||
spectrogram_viewer.service)
|
||||
|
||||
restart_services
|
||||
sudo -u${USER} git -C ${HOME}/BirdNET-Pi checkout -f || exit 1
|
||||
sudo -u${USER} git -C ${HOME}/BirdNET-Pi pull -f || exit 1
|
||||
|
||||
# Trigger the new update_birdnet2.sh
|
||||
sudo -u${USER} ${my_dir}/update_birdnet2.sh
|
||||
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
# Second stage of update
|
||||
birdnet_conf=/home/pi/BirdNET-Pi/birdnet.conf
|
||||
|
||||
# Stage 1 updates the birdnet.conf
|
||||
sudo -upi sed -i 's/EXTRACTIONS_URL/BIRDNETPI_URL/g'
|
||||
if ! grep EXTRACTIONLOG ${birdnet_conf} &> /dev/null;then
|
||||
echo "EXTRACTIONLOG_URL=" >> ${birdnet_conf}
|
||||
echo "BIRDNETLOG_URL=" >> ${birdnet_conf}
|
||||
fi
|
||||
sudo -upi sed -i 's/=http:\/\/birdnetpi.local/=/g' ${birdnet_conf}
|
||||
|
||||
# Stage 2 updates the services
|
||||
my_dir=${HOME}/BirdNET-Pi/scripts
|
||||
sudo ${my_dir}/update_services.sh
|
||||
|
||||
# Stage 2 restarts the services
|
||||
newservices=$(awk '/service/ && /systemctl/ && !/php/ {print $3}' ${my_dir}/install_services.sh | sort)
|
||||
|
||||
restart_newservices() {
|
||||
for i in ${newservices[@]};do
|
||||
sudo systemctl restart ${i}
|
||||
done
|
||||
}
|
||||
|
||||
restart_newservices
|
||||
sudo systemctl restart extraction.timer
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
# Update database password
|
||||
source /etc/birdnet/birdnet.conf
|
||||
|
||||
sudo mysql -e "
|
||||
UPDATE mysql.user
|
||||
SET Password=PASSWORD('${DB_PWD}')
|
||||
WHERE USER='birder'
|
||||
AND Host='localhost';
|
||||
FLUSH PRIVILEGES";
|
||||
git -C /home/pi/BirdNET-Pi checkout -f analyze.py
|
||||
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/scripts/viewdb.php
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
$timer=60;
|
||||
header( "refresh:$timer;url=http://birdnetpi.local" );
|
||||
?>
|
||||
<html lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<head></head>
|
||||
<body style="background-color: rgb(119, 196, 135)">
|
||||
<script>
|
||||
|
||||
function countDown(secs,elem) {
|
||||
|
||||
var element = document.getElementById(elem);
|
||||
|
||||
element.innerHTML = "Update in progress. Please allow another "+secs+" seconds for it to complete.";
|
||||
|
||||
if(secs < 1) {
|
||||
|
||||
clearTimeout(timer);
|
||||
|
||||
element.innerHTML = '<h4>Let\'s see</h4>';
|
||||
|
||||
element.innerHTML += '<a href="http://birdnetpi.local"></a>';
|
||||
|
||||
}
|
||||
|
||||
secs--;
|
||||
|
||||
var timer = setTimeout('countDown('+secs+',"'+elem+'")',1000);
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div id="status"style="font-size:30px;"></div>
|
||||
|
||||
<script>countDown(<?php echo $timer;?>,"status");</script>
|
||||
</body>
|
||||
</html>
|
||||
+64
-38
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# This installs the services that have been selected
|
||||
# This reinstalls the services
|
||||
#set -x # Uncomment to enable debugging
|
||||
trap 'rm -f ${tmpfile}' EXIT
|
||||
trap 'exit 1' SIGINT SIGHUP
|
||||
@@ -11,6 +11,14 @@ nomachine_url="https://download.nomachine.com/download/7.6/Arm/nomachine_7.6.2_3
|
||||
gotty_url="https://github.com/yudai/gotty/releases/download/v1.0.1/gotty_linux_arm.tar.gz"
|
||||
config_file="$(dirname ${my_dir})/birdnet.conf"
|
||||
|
||||
set_hostname() {
|
||||
if [ "$(hostname)" != "birdnetpi" ];then
|
||||
echo "Setting hostname to 'birdnetpi'"
|
||||
hostnamectl set-hostname birdnetpi
|
||||
sed -i 's/raspberrypi/birdnetpi/g' /etc/hosts
|
||||
fi
|
||||
}
|
||||
|
||||
install_scripts() {
|
||||
echo "Installing BirdNET-Pi scripts to /usr/local/bin"
|
||||
ln -sf ${my_dir}/* /usr/local/bin/
|
||||
@@ -24,6 +32,8 @@ install_mariadb() {
|
||||
apt -qqy install mariadb-server
|
||||
echo "MariaDB Installed"
|
||||
fi
|
||||
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
|
||||
}
|
||||
|
||||
install_birdnet_analysis() {
|
||||
@@ -88,7 +98,7 @@ ExecStart=/usr/local/bin/species_notifier.sh
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable --now pushed_notifications
|
||||
systemctl enable pushed_notifications.service
|
||||
}
|
||||
|
||||
create_necessary_dirs() {
|
||||
@@ -98,15 +108,35 @@ create_necessary_dirs() {
|
||||
[ -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 ${PROCESSED} ] || sudo -u ${USER} mkdir -p ${PROCESSED}
|
||||
[ -L ${EXTRACTED}/index.html ] || sudo -u ${USER} ln -s $(dirname ${my_dir})/templates/index.html ${EXTRACTED}
|
||||
[ -L ${EXTRACTED}/scripts ] || sudo -u ${USER} ln -s $(dirname ${my_dir})/scripts ${EXTRACTED}
|
||||
[ -L ${EXTRACTED}/spectrogram.php ] || sudo -u ${USER} ln -s $(dirname ${my_dir})/scripts/spectrogram.* ${EXTRACTED}
|
||||
[ -L ${EXTRACTED}/viewdb.php ] || sudo -u ${USER} ln -s $(dirname ${my_dir})/scripts/viewdb.php ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED}
|
||||
[ -L ${EXTRACTED}/phpsysinfo.ini ] || sudo -u ${USER} cp ${HOME}/phpsysinfo/phpsysinfo.ini.new ${HOME}/phpsysinfo/phpsysinfo.ini
|
||||
|
||||
sudo -u ${USER} ln -fs $(dirname ${my_dir})/homepage/* ${EXTRACTED}
|
||||
set -x
|
||||
if [ ! -z ${BIRDNETLOG_URL} ];then
|
||||
BIRDNETLOG_URL="$(echo ${BIRDNETLOG_URL} | sed 's/\/\//\\\/\\\//g')"
|
||||
sudo -u${USER} sed -i "s/http:\/\/birdnetpi.local:8080/"${BIRDNETLOG_URL}"/g" $(dirname ${my_dir})/homepage/*.html
|
||||
fi
|
||||
set +x
|
||||
if [ ! -z ${EXTRACTIONLOG_URL} ];then
|
||||
EXTRACTIONLOG_URL="$(echo ${EXTRACTIONLOG_URL} | sed 's/\/\//\\\/\\\//g')"
|
||||
sudo -u${USER} sed -i "s/http:\/\/birdnetpi.local:8888/"${EXTRACTIONLOG_URL}"/g" $(dirname ${my_dir})/homepage/*.html
|
||||
fi
|
||||
|
||||
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts ${EXTRACTED}
|
||||
if [ ! -z ${BIRDNETPI_URL} ];then
|
||||
BIRDNETPI_URL="$(echo ${BIRDNETPI_URL} | sed 's/\/\//\\\/\\\//g')"
|
||||
sudo -u${USER} sed -i "s/http:\/\/birdnetpi.local/"${BIRDNETPI_URL}"/g" $(dirname ${my_dir})/homepage/*.html
|
||||
phpfiles="$(grep -l birdnetpi.local ${my_dir}/*.php)"
|
||||
for i in "${phpfiles[@]}";do
|
||||
sudo -u${USER} sed -i "s/http:\/\/birdnetpi.local/"${BIRDNETPI_URL}"/g" ${i}
|
||||
done
|
||||
fi
|
||||
|
||||
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/spectrogram.php ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs $(dirname ${my_dir})/scripts/viewdb.php ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED}
|
||||
[ -L ${EXTRACTED}/phpsysinfo/phpsysinfo.ini ] || sudo -u ${USER} cp ${HOME}/phpsysinfo/phpsysinfo.ini.new ${HOME}/phpsysinfo/phpsysinfo.ini
|
||||
}
|
||||
|
||||
|
||||
install_alsa() {
|
||||
echo "Checking for alsa-utils and pulseaudio"
|
||||
if which arecord &> /dev/null ;then
|
||||
@@ -170,26 +200,7 @@ install_Caddyfile() {
|
||||
fi
|
||||
HASHWORD=$(caddy hash-password -plaintext ${CADDY_PWD})
|
||||
cat << EOF > /etc/caddy/Caddyfile
|
||||
${EXTRACTIONS_URL} {
|
||||
root * ${EXTRACTED}
|
||||
file_server browse
|
||||
basicauth /Processed* {
|
||||
birdnet ${HASHWORD}
|
||||
}
|
||||
basicauth /scripts* {
|
||||
birdnet ${HASHWORD}
|
||||
}
|
||||
basicauth /stream {
|
||||
birdnet ${HASHWORD}
|
||||
}
|
||||
basicauth /phpsysinfo* {
|
||||
birdnet ${HASHWORD}
|
||||
}
|
||||
reverse_proxy /stream localhost:8000
|
||||
php_fastcgi unix//run/php/php7.3-fpm.sock
|
||||
}
|
||||
|
||||
http://birdnetpi.local {
|
||||
http://localhost http://birdnetpi.local ${BIRDNETPI_URL} {
|
||||
root * ${EXTRACTED}
|
||||
file_server browse
|
||||
basicauth /Processed* {
|
||||
@@ -208,6 +219,22 @@ http://birdnetpi.local {
|
||||
php_fastcgi unix//run/php/php7.3-fpm.sock
|
||||
}
|
||||
EOF
|
||||
if [ ! -z ${EXTRACTIONLOG_URL} ];then
|
||||
cat << EOF >> /etc/caddy/Caddyfile
|
||||
|
||||
${EXTRACTIONLOG_URL} {
|
||||
reverse_proxy localhost:8888
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
if [ ! -z ${BIRDNETLOG_URL} ];then
|
||||
cat << EOF >> /etc/caddy/Caddyfile
|
||||
|
||||
${BIRDNETLOG_URL} {
|
||||
reverse_proxy localhost:8080
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
systemctl reload caddy
|
||||
}
|
||||
|
||||
@@ -232,7 +259,7 @@ ExecStart=/bin/bash -c "/usr/bin/avahi-publish -a -R %I $(avahi-resolve -4 -n %H
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable --now avahi-alias@birdnetpi.local.service
|
||||
systemctl enable avahi-alias@birdnetpi.local.service
|
||||
}
|
||||
|
||||
install_spectrogram_service() {
|
||||
@@ -248,7 +275,7 @@ ExecStart=/usr/local/bin/spectrogram.sh
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable --now spectrogram_viewer.service
|
||||
systemctl enable spectrogram_viewer.service
|
||||
}
|
||||
|
||||
install_gotty_logs() {
|
||||
@@ -275,7 +302,7 @@ ExecStart=/usr/local/bin/gotty -p 8080 --title-format "BirdNET-Pi Log" journalct
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable --now birdnet_log.service
|
||||
systemctl enable birdnet_log.service
|
||||
echo "Installing the extraction_log.service"
|
||||
cat << EOF > /etc/systemd/system/extraction_log.service
|
||||
[Unit]
|
||||
@@ -292,7 +319,7 @@ ExecStart=/usr/local/bin/gotty -p 8888 --title-format "Extractions Log" journalc
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable --now extraction_log.service
|
||||
systemctl enable extraction_log.service
|
||||
}
|
||||
|
||||
install_sox() {
|
||||
@@ -354,12 +381,12 @@ install_icecast() {
|
||||
echo "icecast2 icecast2/icecast-setup boolean false" | debconf-set-selections
|
||||
apt install -qqy icecast2
|
||||
config_icecast
|
||||
systemctl enable --now icecast2
|
||||
systemctl enable icecast2.service
|
||||
/etc/init.d/icecast2 start
|
||||
else
|
||||
echo "Icecast2 is installed"
|
||||
config_icecast
|
||||
systemctl enable --now icecast2
|
||||
systemctl enable icecast2.service
|
||||
/etc/init.d/icecast2 start
|
||||
fi
|
||||
}
|
||||
@@ -392,7 +419,7 @@ ExecStart=/usr/local/bin/livestream.sh
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable --now livestream.service
|
||||
systemctl enable livestream.service
|
||||
}
|
||||
|
||||
install_nomachine() {
|
||||
@@ -416,6 +443,7 @@ install_cleanup_cron() {
|
||||
}
|
||||
|
||||
install_selected_services() {
|
||||
set_hostname
|
||||
install_scripts
|
||||
install_birdnet_analysis
|
||||
|
||||
@@ -428,7 +456,6 @@ install_selected_services() {
|
||||
install_recording_service
|
||||
fi
|
||||
|
||||
if [ ! -z "${EXTRACTIONS_URL}" ];then
|
||||
install_caddy
|
||||
install_Caddyfile
|
||||
install_avahi_aliases
|
||||
@@ -439,7 +466,6 @@ install_selected_services() {
|
||||
install_spectrogram_service
|
||||
install_edit_birdnet_conf
|
||||
install_pushed_notifications
|
||||
fi
|
||||
|
||||
if [ ! -z "${ICE_PWD}" ];then
|
||||
install_icecast
|
||||
|
||||
+22
-17
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
header("refresh: 30;");
|
||||
|
||||
$user = 'birder';
|
||||
$password = 'databasepassword';
|
||||
@@ -15,11 +16,16 @@ if ($mysqli->connect_error) {
|
||||
}
|
||||
|
||||
// SQL query to select data from database
|
||||
$sql = "SELECT * FROM detections
|
||||
ORDER BY Date DESC, Time DESC";
|
||||
$sql = "SELECT * FROM detections
|
||||
ORDER BY Date DESC, Time DESC";
|
||||
$fulltable = $mysqli->query($sql);
|
||||
$totalcount=mysqli_num_rows($fulltable);
|
||||
|
||||
$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);
|
||||
@@ -53,7 +59,7 @@ $mysqli->close();
|
||||
|
||||
<head>
|
||||
<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>
|
||||
<!-- CSS FOR STYLING THE PAGE -->
|
||||
<style>
|
||||
@@ -63,13 +69,11 @@ $mysqli->close();
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
margin-left:-5px;
|
||||
margin-right:-5px;
|
||||
}
|
||||
|
||||
.column {
|
||||
flex: 50%;
|
||||
padding: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
table {
|
||||
@@ -108,6 +112,7 @@ $mysqli->close();
|
||||
border: 1px solid black;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
background-color: rgb(219, 296, 235);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
@@ -157,10 +162,13 @@ $mysqli->close();
|
||||
td {
|
||||
font-weight: lighter;
|
||||
}
|
||||
body::-webkit-scrollbar {
|
||||
display:none
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="background-color: rgb(119, 196, 135);background-image: linear-gradient(to top, rgb(119, 196, 135),black;">
|
||||
|
||||
<body>
|
||||
<section>
|
||||
<h2>Number of Detections</h2>
|
||||
<table>
|
||||
@@ -204,11 +212,11 @@ while($rows=$specieslist ->fetch_assoc())
|
||||
</table>
|
||||
</div>
|
||||
<div class="column">
|
||||
<h2>Species stats</h2>
|
||||
<h2>Species Statistics</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Species</th>
|
||||
<th>Number of Detections</th>
|
||||
<th>Detections</th>
|
||||
</tr>
|
||||
<?php // LOOP TILL END OF DATA
|
||||
while($rows=$speciestally ->fetch_assoc())
|
||||
@@ -224,14 +232,13 @@ while($rows=$speciestally ->fetch_assoc())
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<h1>BirdsDB Detections Table</h1>
|
||||
<h2>Today's Detections</h2>
|
||||
<!-- TABLE CONSTRUCTION-->
|
||||
<table>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Time</th>
|
||||
<th>Sci_Name</th>
|
||||
<th>Com_Name</th>
|
||||
<th>Scientific Name</th>
|
||||
<th>Common Name</th>
|
||||
<th>Confidence</th>
|
||||
<th>Lat</th>
|
||||
<th>Lon</th>
|
||||
@@ -242,13 +249,12 @@ while($rows=$speciestally ->fetch_assoc())
|
||||
</tr>
|
||||
<!-- PHP CODE TO FETCH DATA FROM ROWS-->
|
||||
<?php // LOOP TILL END OF DATA
|
||||
while($rows=$fulltable ->fetch_assoc())
|
||||
while($rows=$mosttable ->fetch_assoc())
|
||||
{
|
||||
?>
|
||||
<tr>
|
||||
<!--FETCHING DATA FROM EACH
|
||||
ROW OF EVERY COLUMN-->
|
||||
<td><?php echo $rows['Date'];?></td>
|
||||
<td><?php echo $rows['Time'];?></td>
|
||||
<td><?php echo $rows['Sci_Name'];?></td>
|
||||
<td><?php echo $rows['Com_Name'];?></td>
|
||||
@@ -265,7 +271,6 @@ while($rows=$fulltable ->fetch_assoc())
|
||||
?>
|
||||
</table>
|
||||
</section>
|
||||
</body>
|
||||
|
||||
</div>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -1,15 +1,4 @@
|
||||
${EXTRACTIONS_URL} {
|
||||
root * ${EXTRACTED}
|
||||
file_server browse
|
||||
basicauth ${PROCESSED}* {
|
||||
birdnet ${HASHWORD}
|
||||
}
|
||||
basicauth /stream {
|
||||
birdnet ${HASHWORD}
|
||||
}
|
||||
reverse_proxy /stream localhost:8000
|
||||
}
|
||||
http://birdnetpi.local {
|
||||
http://birdnetpi.local ${BIRDNETPI_URL} {
|
||||
root * ${EXTRACTED}
|
||||
file_server browse
|
||||
basicauth ${PROCESSED}* {
|
||||
@@ -26,6 +15,3 @@ http://birdlog.local {
|
||||
http://extractionlog.local {
|
||||
reverse_proxy localhost:8888
|
||||
}
|
||||
http://birdterminal.local {
|
||||
reverse_proxy localhost:9111
|
||||
}
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
${EXTRACTIONS_URL} {
|
||||
root * ${EXTRACTED}
|
||||
file_server browse
|
||||
basicauth ${PROCESSED}* {
|
||||
birdnet ${HASHWORD}
|
||||
}
|
||||
basicauth /stream {
|
||||
birdnet ${HASHWORD}
|
||||
}
|
||||
}
|
||||
http://birdnetpi.local {
|
||||
http://birdnetpi.local ${BIRDNETPI_URL} {
|
||||
root * ${EXTRACTED}
|
||||
file_server browse
|
||||
basicauth ${PROCESSED}* {
|
||||
@@ -24,6 +14,3 @@ http://birdlog.local {
|
||||
http://extractionlog.local {
|
||||
reverse_proxy localhost:8888
|
||||
}
|
||||
http://birdterminal.local {
|
||||
reverse_proxy localhost:9111
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# testing - 0.4
|
||||
## What's new
|
||||
- New desktop web interface
|
||||
- Better support for public installations
|
||||
- Needs better documentation to explain how to set it up
|
||||
Reference in New Issue
Block a user