@@ -4,6 +4,7 @@ | |||
# set -x | |||
. "$HOME/.noaa.conf" | |||
export PATH=$PATH:/usr/local/bin/ | |||
declare -A levels=([DEBUG]=0 [INFO]=1 [WARN]=2 [ERROR]=3) | |||
log_level=${LOG_LEVEL} | |||
@@ -21,6 +22,7 @@ log() { | |||
#log here | |||
echo "${log_priority} : ${log_message}" | |||
echo $(date '+%d-%m-%Y %H:%M') $0 "${log_priority} : ${log_message}" >> "$NOAA_LOG" | |||
} | |||
## current date and folder structure | |||
@@ -53,12 +53,11 @@ if [ "$raspbian_version" == "stretch" ]; then | |||
fi | |||
sudo apt update -yq | |||
sudo apt install -yq predict \ | |||
python-setuptools \ | |||
ntp \ | |||
sudo apt install -yq python-setuptools \ | |||
unzip zip \ | |||
cmake \ | |||
libusb-1.0 \ | |||
sox \ | |||
libusb-1.0-0-dev \ | |||
sox libsox-fmt-mp3 \ | |||
at \ | |||
bc \ | |||
nginx \ | |||
@@ -72,8 +71,8 @@ sudo apt install -yq predict \ | |||
libjpeg9 \ | |||
libjpeg9-dev \ | |||
socat \ | |||
php7.2-fpm \ | |||
php7.2-sqlite \ | |||
php7.3-fpm \ | |||
php7.3-sqlite3 \ | |||
sqlite3 | |||
if [ "$raspbian_version" == "stretch" ]; then | |||
@@ -105,11 +104,11 @@ fi | |||
if [ -e /usr/local/bin/rtl_fm ]; then | |||
log_done "rtl-sdr was already installed" | |||
else | |||
log_running "Installing rtl-sdr from osmocom..." | |||
log_running "Installing rtl-sdr from librtlsdr..." | |||
( | |||
cd /tmp/ | |||
git clone https://github.com/osmocom/rtl-sdr.git | |||
cd rtl-sdr/ | |||
git clone https://github.com/librtlsdr/librtlsdr.git | |||
cd librtlsdr/ | |||
mkdir build | |||
cd build | |||
cmake ../ -DINSTALL_UDEV_RULES=ON -DDETACH_KERNEL_DRIVER=ON | |||
@@ -131,6 +130,19 @@ else | |||
log_done "WxToIMG installed" | |||
fi | |||
### install predict | |||
if command -v predict &> /dev/null; then | |||
log_done "predict was already installed" | |||
else | |||
$orig_dir=$(pwd) | |||
cd software | |||
tar -xzf predict-2.2.7.tar.gz | |||
cd predict-2.2.7 | |||
sudo ./configure #this also installs :X | |||
cd $orig_dir | |||
log_done "predict installed" | |||
fi | |||
### Install default config file | |||
if [ -e "$HOME/.noaa.conf" ]; then | |||
log_done "$HOME/.noaa.conf already exists" | |||
@@ -177,38 +189,69 @@ else | |||
fi | |||
### Install medet_arm | |||
if [ -e /usr/bin/medet_arm ]; then | |||
log_done "medet_arm was already installed" | |||
if [ -e /usr/bin/medet ]; then | |||
log_done "medet was already installed" | |||
else | |||
log_running "Installing medet_arm..." | |||
sudo cp software/medet_arm /usr/bin/medet_arm | |||
sudo chmod +x /usr/bin/medet_arm | |||
log_done "medet_arm installed" | |||
if [[ $(uname -m) == *"arm"* ]]; then | |||
log_running "Installing medet_arm..." | |||
sudo cp software/medet_arm /usr/bin/medet | |||
elif [[ $(uname -m) == *"x86_64"* ]]; then | |||
log_running "Installing medet_x86_64..." | |||
sudo cp software/medet_x86_64 /usr/bin/medet | |||
else | |||
log_error "Unknown archictecture $(uname -m)!" | |||
exit -1 | |||
fi | |||
sudo chmod +x /usr/bin/medet | |||
log_done "medet installed" | |||
fi | |||
### Install noaa-apt | |||
if command -v noaa-apt &> /dev/null; then | |||
log_done "noaa-apt was already installed" | |||
else | |||
if [[ $(uname -m) == *"arm"* ]]; then | |||
log_running "Installing noaa-apt arm..." | |||
unzip software/noaa-apt-1.3.0-armv7-linux-gnueabihf-nogui.zip | |||
sudo mv noaa-apt /usr/bin | |||
sudo mv res /usr/bin #ok, this is not so nice, but it works | |||
elif [[ $(uname -m) == *"x86_64"* ]]; then | |||
log_running "Installing noaa-apt x86..." | |||
sudo dpkg -i software/noaa-apt_1.3.0-1_amd64.deb | |||
else | |||
log_error "Unknown archictecture $(uname -m)!" | |||
exit -1 | |||
fi | |||
mkdir -p "$HOME/.config/noaa-apt" | |||
cp templates/settings.toml "$HOME/.config/noaa-apt" | |||
log_done "noaa-apt installed" | |||
fi | |||
### Cron the scheduler | |||
set +e | |||
crontab -l | grep -q "raspberry-noaa" | |||
if [ $? -eq 0 ]; then | |||
log_done "Crontab for schedule.sh already exists" | |||
else | |||
cat <(crontab -l) <(echo "1 0 * * * /home/pi/raspberry-noaa/schedule.sh") | crontab - | |||
cat <(crontab -l) <(echo "1 0 * * * $HOME/raspberry-noaa/schedule.sh") | crontab - | |||
log_done "Crontab installed" | |||
fi | |||
set -e | |||
### Setup Nginx | |||
log_running "Setting up Nginx..." | |||
usr=$(whoami) | |||
sudo cp templates/nginx.cfg /etc/nginx/sites-enabled/default | |||
( | |||
sudo mkdir -p /var/www/wx/images | |||
sudo chown -R pi:pi /var/www/wx | |||
sudo usermod -a -G www-data pi | |||
sudo chown -R $usr:$usr /var/www/wx | |||
sudo usermod -a -G www-data $usr | |||
sudo chmod 775 /var/www/wx | |||
) | |||
sudo systemctl restart nginx | |||
sudo cp -rp templates/webpanel/* /var/www/wx/ | |||
sed -i -e "s/pi/${usr}/g" "/var/www/wx/Model/Conn.php" | |||
log_done "Nginx configured" | |||
### Setup ramFS | |||
@@ -243,6 +286,7 @@ else | |||
log_done "pd120_decoder installed" | |||
fi | |||
cp templates/sun.py . | |||
success "Install (almost) done!" | |||
@@ -298,10 +342,12 @@ read -rp "Enter your longitude (West values are negative): " | |||
read -rp "Enter your timezone offset (ex: -3 for Argentina time): " | |||
tzoffset=$REPLY | |||
sed -i -e "s/change_latitude/${lat}/g;s/change_longitude/${lon}/g" "$HOME/.noaa.conf" | |||
sed -i -e "s/change_latitude/${lat}/g;s/change_longitude/${lon}/g;s/pi/${usr}/g" "$HOME/.noaa.conf" | |||
sed -i -e "s/change_latitude/${lat}/g;s/change_longitude/${lon}/g" "$HOME/.wxtoimgrc" | |||
sed -i -e "s/change_latitude/${lat}/g;s/change_longitude/$(echo "$lon * -1" | bc)/g" "$HOME/.predict/predict.qth" | |||
sed -i -e "s/change_latitude/${lat}/g;s/change_longitude/${lon}/g" "$HOME/.predict/predict.qth" | |||
sed -i -e "s/change_latitude/${lat}/g;s/change_longitude/${lon}/g;s/change_tz/$(echo "$tzoffset * -1" | bc)/g" "sun.py" | |||
sed -i -e "s/change_tz/$tzoffset/g" "$HOME/.config/noaa-apt/settings.toml" | |||
sed -i -e "s/change_tz/$tzoffset/g" "sun.py" | |||
success "Install done! Double check your $HOME/.noaa.conf settings" | |||
@@ -315,4 +361,8 @@ set +e | |||
### Running WXTOIMG to have the user accept the licensing agreement | |||
wxtoimg | |||
sudo reboot | |||
read -rp "reboot now? (Y/n)" | |||
doreboot=$REPLY | |||
[ ! -z "$doreboot" ] || sudo reboot | |||
[ "$doreboot" == "y" ] && sudo reboot |
@@ -26,7 +26,7 @@ fi | |||
# $7 = Satellite max elevation | |||
log "Starting rtl_fm record" "INFO" | |||
timeout "${6}" /usr/local/bin/rtl_fm ${BIAS_TEE} -M fm -f 145.8M -s 48k -g $GAIN -E dc -E wav -E deemp -F 9 - | sox -t raw -r 48k -c 1 -b 16 -e s - -t wav "${NOAA_OUTPUT}/audio/${3}.wav" rate 11025 | |||
timeout "${6}" /usr/local/bin/rtl_fm ${BIAS_TEE} -M fm -f ${2}M -s 48k $GAIN -E dc -E wav -E deemp -F 9 - | sox -t raw -r 48k -c 1 -b 16 -e s - -t wav "${NOAA_OUTPUT}/audio/${3}.wav" rate 11025 | |||
if [ -f "$NOAA_HOME/demod.py" ]; then | |||
log "Decoding ISS pass" "INFO" | |||
@@ -52,5 +52,8 @@ if [ -f "$NOAA_HOME/demod.py" ]; then | |||
fi | |||
fi | |||
sqlite3 "$NOAA_HOME/panel.db" "update predict_passes set is_active = 0 where (predict_passes.pass_start) in (select predict_passes.pass_start from predict_passes inner join decoded_passes on predict_passes.pass_start = decoded_passes.pass_start where decoded_passes.id = $pass_id);" | |||
else | |||
log "Did not receive any images from ISS" ERROR | |||
sqlite3 "$NOAA_HOME/panel.db" "update predict_passes set is_active = 0 where predict_passes.pass_start = $5;" | |||
fi | |||
fi |
@@ -11,6 +11,8 @@ fi | |||
. "$HOME/.tweepy.conf" | |||
. "$NOAA_HOME/common.sh" | |||
log "starting $0" DEBUG | |||
SYSTEM_MEMORY=$(free -m | awk '/^Mem:/{print $2}') | |||
if [ "$SYSTEM_MEMORY" -lt 2000 ]; then | |||
log "The system doesn't have enough space to store a Meteor pass on RAM" "INFO" | |||
@@ -42,11 +44,15 @@ fi | |||
# $6 = Time to capture | |||
# $7 = Satellite max elevation | |||
log "Starting rtl_fm record" "INFO" | |||
timeout "${6}" /usr/local/bin/rtl_fm ${BIAS_TEE} -M raw -f "${2}"M -s 288k -g $GAIN | sox -t raw -r 288k -c 2 -b 16 -e s - -t wav "${RAMFS_AUDIO}/audio/${3}.wav" rate 96k | |||
pre_rate=288k | |||
log "Starting rtl_fm record for $1 at $2 to $3 at epoch $5" "INFO" | |||
log "timeout \"${6}\" /usr/local/bin/rtl_fm ${BIAS_TEE} -p $PPM_ERROR -M raw -f ${2}M -F0 -s $pre_rate $GAIN | sox -t raw -r $pre_rate -c 2 -b 16 -e s - -t wav \"${RAMFS_AUDIO}/audio/${3}.wav\"" DEBUG | |||
timeout "${6}" /usr/local/bin/rtl_fm ${BIAS_TEE} -p $PPM_ERROR -M raw -f ${2}M -F0 -s $pre_rate $GAIN | sox -t raw -r $pre_rate -c 2 -b 16 -e s - -t wav "${RAMFS_AUDIO}/audio/${3}.wav" #rate 96k | |||
log "Demodulation in progress (QPSK)" "INFO" | |||
meteor_demod -B -o "${METEOR_OUTPUT}/${3}.qpsk" "${RAMFS_AUDIO}/audio/${3}.wav" | |||
[[ $1 == "METEOR-M22" ]] && demod_extra="-m opsk" | |||
log "Demodulation in progress (QPSK) $demod_extra" "INFO" | |||
meteor_demod $demod_extra -B -o "${METEOR_OUTPUT}/${3}.qpsk" "${RAMFS_AUDIO}/audio/${3}.wav" 2>> $NOAA_LOG | |||
if [ "$DELETE_AUDIO" = true ]; then | |||
log "Deleting audio files" "INFO" | |||
@@ -58,20 +64,21 @@ else | |||
rm "${RAMFS_AUDIO}/audio/${3}.wav" | |||
fi | |||
log "Decoding in progress (QPSK to BMP)" "INFO" | |||
medet_arm "${METEOR_OUTPUT}/${3}.qpsk" "${METEOR_OUTPUT}/${3}" -cd | |||
log "Decoding in progress (QPSK to BMP)" INFO | |||
[[ $1 == "METEOR-M22" ]] && medet_extra="-diff" | |||
medet $medet_extra "${METEOR_OUTPUT}/${3}.qpsk" "${METEOR_OUTPUT}/${3}" -cd | |||
rm "${METEOR_OUTPUT}/${3}.qpsk" | |||
if [ -f "${METEOR_OUTPUT}/${3}.dec" ]; then | |||
log "Sun elevation: ${SUN_ELEV}" DEBUG | |||
if [ "${SUN_ELEV}" -lt "${SUN_MIN_ELEV}" ]; then | |||
log "I got a successful ${3}.dec file. Decoding APID 68" "INFO" | |||
medet_arm "${METEOR_OUTPUT}/${3}.dec" "${NOAA_OUTPUT}/images/${3}-122" -r 68 -g 68 -b 68 -d | |||
medet "${METEOR_OUTPUT}/${3}.dec" "${NOAA_OUTPUT}/images/${3}-122" -r 68 -g 68 -b 68 -d | |||
/usr/bin/convert $FLIP -negate "${NOAA_OUTPUT}/images/${3}-122.bmp" "${NOAA_OUTPUT}/images/${3}-122.bmp" | |||
else | |||
log "I got a successful ${3}.dec file. Creating false color image" "INFO" | |||
medet_arm "${METEOR_OUTPUT}/${3}.dec" "${NOAA_OUTPUT}/images/${3}-122" -r 65 -g 65 -b 64 -d | |||
medet "${METEOR_OUTPUT}/${3}.dec" "${NOAA_OUTPUT}/images/${3}-122" -r 65 -g 65 -b 64 -d | |||
fi | |||
log "Rectifying image to adjust aspect ratio" "INFO" | |||
@@ -82,13 +89,15 @@ if [ -f "${METEOR_OUTPUT}/${3}.dec" ]; then | |||
rm "${METEOR_OUTPUT}/${3}.bmp" | |||
rm "${METEOR_OUTPUT}/${3}.dec" | |||
sqlite3 /home/pi/raspberry-noaa/panel.db "insert into decoded_passes (pass_start, file_path, daylight_pass, sat_type) values ($5,\"$3\", 1,0);" | |||
pass_id=$(sqlite3 /home/pi/raspberry-noaa/panel.db "select id from decoded_passes order by id desc limit 1;") | |||
sqlite3 $HOME/raspberry-noaa/panel.db "insert into decoded_passes (pass_start, file_path, daylight_pass, sat_type) values ($5,\"$3\", 1,0);" | |||
pass_id=$(sqlite3 $HOME/raspberry-noaa/panel.db "select id from decoded_passes order by id desc limit 1;") | |||
sqlite3 $HOME/raspberry-noaa/panel.db "update predict_passes set is_active = 0 where (predict_passes.pass_start) in (select predict_passes.pass_start from predict_passes inner join decoded_passes on predict_passes.pass_start = decoded_passes.pass_start where decoded_passes.id = $pass_id);" | |||
if [ -n "$CONSUMER_KEY" ]; then | |||
log "Posting to Twitter" "INFO" | |||
python3 "${NOAA_HOME}/post.py" "$1 ${START_DATE} Resolución completa: https://weather.reyni.co/detail.php?id=$pass_id" "$7" "${NOAA_OUTPUT}/images/${3}-122-rectified.jpg" | |||
fi | |||
sqlite3 /home/pi/raspberry-noaa/panel.db "update predict_passes set is_active = 0 where (predict_passes.pass_start) in (select predict_passes.pass_start from predict_passes inner join decoded_passes on predict_passes.pass_start = decoded_passes.pass_start where decoded_passes.id = $pass_id);" | |||
else | |||
log "Decoding failed, either a bad pass/low SNR or a software problem" "ERROR" | |||
sqlite3 $HOME/raspberry-noaa/panel.db "update predict_passes set is_active = 0 where predict_passes.pass_start = $5;" | |||
fi |
@@ -30,8 +30,11 @@ fi | |||
# $6 = Time to capture | |||
# $7 = Satellite max elevation | |||
log "Starting rtl_fm record" "INFO" | |||
timeout "${6}" /usr/local/bin/rtl_fm ${BIAS_TEE} -f "${2}"M -s 60k -g $GAIN -E wav -E deemp -F 9 - | /usr/bin/sox -t raw -e signed -c 1 -b 16 -r 60000 - "${RAMFS_AUDIO}/audio/${3}.wav" rate 11025 | |||
pre_samplerate=60k | |||
log "Starting rtl_fm record for $1 at $2 to $3 at epoch $5" "INFO" | |||
log "timeout ${6} /usr/local/bin/rtl_fm ${BIAS_TEE} -f ${2}M -s$pre_samplerate $GAIN -p $PPM_ERROR -E wav -E deemp -F 0 - | /usr/bin/sox -t raw -e signed -c 1 -b 16 -r $pre_samplerate - ${RAMFS_AUDIO}/audio/${3}.wav rate 11025" DEBUG | |||
timeout "${6}" /usr/local/bin/rtl_fm ${BIAS_TEE} -f "${2}"M -s$pre_samplerate $GAIN -p $PPM_ERROR -E wav -E deemp -F 0 - | /usr/bin/sox -t raw -e signed -c 1 -b 16 -r $pre_samplerate - "${RAMFS_AUDIO}/audio/${3}.wav" rate 11025 | |||
if [ "${SUN_ELEV}" -gt "${SUN_MIN_ELEV}" ]; then | |||
ENHANCEMENTS="ZA MCIR MCIR-precip MSA MSA-precip HVC-precip HVCT-precip HVC HVCT" | |||
@@ -41,24 +44,33 @@ else | |||
daylight="false" | |||
fi | |||
log "Bulding pass map" "INFO" | |||
log "Bulding pass map wxtoimg" "INFO" | |||
/usr/local/bin/wxmap -T "${1}" -H "${4}" -p 0 -l 0 -o "${PASS_START}" "${NOAA_HOME}/map/${3}-map.png" | |||
for i in $ENHANCEMENTS; do | |||
log "Decoding image" "INFO" | |||
/usr/local/bin/wxtoimg -o -m "${NOAA_HOME}/map/${3}-map.png" -e "$i" "${RAMFS_AUDIO}/audio/${3}.wav" "${NOAA_OUTPUT}/images/${3}-$i.jpg" | |||
/usr/bin/convert -quality 90 -format jpg "${NOAA_OUTPUT}/images/${3}-$i.jpg" -undercolor black -fill yellow -pointsize 18 -annotate +20+20 "${1} $i ${START_DATE} Elev: $7°" "${NOAA_OUTPUT}/images/${3}-$i.jpg" | |||
/usr/bin/convert -quality 98 -format jpg "${NOAA_OUTPUT}/images/${3}-$i.jpg" -undercolor black -fill yellow -pointsize 18 -annotate +20+20 "${1} $i ${START_DATE} Elev: $7°" "${NOAA_OUTPUT}/images/${3}-$i.jpg" | |||
/usr/bin/convert -thumbnail 300 "${NOAA_OUTPUT}/images/${3}-$i.jpg" "${NOAA_OUTPUT}/images/thumb/${3}-$i.jpg" | |||
done | |||
log "Building noaa-apt maps" DEBUG | |||
curpath=$(pwd) # needed for faulty noaa-apt arm version | |||
cd /usr/bin | |||
noaa-apt "${RAMFS_AUDIO}/audio/${3}.wav" -R auto -m yes -o "${NOAA_OUTPUT}/images/${3}-noaa-apt.png" | |||
cd $curpath | |||
/usr/bin/convert -quality 98 -format jpg "${NOAA_OUTPUT}/images/${3}-noaa-apt.png" -undercolor black -fill yellow -pointsize 18 -annotate +20+20 "${1} $i ${START_DATE} Elev: $7°" "${NOAA_OUTPUT}/images/${3}-noaa-apt.jpg" | |||
/usr/bin/convert -thumbnail 300 "${NOAA_OUTPUT}/images/${3}-noaa-apt.jpg" "${NOAA_OUTPUT}/images/thumb/${3}-noaa-apt.jpg" | |||
rm "${NOAA_OUTPUT}/images/${3}-noaa-apt.png" | |||
rm "${NOAA_HOME}/map/${3}-map.png" | |||
if [ "${SUN_ELEV}" -gt "${SUN_MIN_ELEV}" ]; then | |||
sqlite3 /home/pi/raspberry-noaa/panel.db "insert into decoded_passes (pass_start, file_path, daylight_pass, sat_type) values ($5,\"$3\", 1,1);" | |||
sqlite3 $HOME/raspberry-noaa/panel.db "insert into decoded_passes (pass_start, file_path, daylight_pass, sat_type) values ($5,\"$3\", 1,1);" | |||
else | |||
sqlite3 /home/pi/raspberry-noaa/panel.db "insert into decoded_passes (pass_start, file_path, daylight_pass, sat_type) values ($5,\"$3\", 0,1);" | |||
sqlite3 $HOME/raspberry-noaa/panel.db "insert into decoded_passes (pass_start, file_path, daylight_pass, sat_type) values ($5,\"$3\", 0,1);" | |||
fi | |||
pass_id=$(sqlite3 /home/pi/raspberry-noaa/panel.db "select id from decoded_passes order by id desc limit 1;") | |||
pass_id=$(sqlite3 $HOME/raspberry-noaa/panel.db "select id from decoded_passes order by id desc limit 1;") | |||
if [ -n "$CONSUMER_KEY" ]; then | |||
log "Posting to Twitter" "INFO" | |||
@@ -69,12 +81,12 @@ if [ -n "$CONSUMER_KEY" ]; then | |||
fi | |||
fi | |||
sqlite3 /home/pi/raspberry-noaa/panel.db "update predict_passes set is_active = 0 where (predict_passes.pass_start) in (select predict_passes.pass_start from predict_passes inner join decoded_passes on predict_passes.pass_start = decoded_passes.pass_start where decoded_passes.id = $pass_id);" | |||
sqlite3 $HOME/raspberry-noaa/panel.db "update predict_passes set is_active = 0 where (predict_passes.pass_start) in (select predict_passes.pass_start from predict_passes inner join decoded_passes on predict_passes.pass_start = decoded_passes.pass_start where decoded_passes.id = $pass_id);" | |||
if [ "$DELETE_AUDIO" = true ]; then | |||
log "Deleting audio files" "INFO" | |||
rm "${RAMFS_AUDIO}/audio/${3}.wav" | |||
else | |||
log "Moving audio files out to the SD card" "INFO" | |||
mv "${RAMFS_AUDIO}/audio/${3}.wav" "${NOAA_OUTPUT}/audio/${3}.wav" | |||
mv "${RAMFS_AUDIO}/audio/${3}.wav" "${NOAA_OUTPUT}/audio/${3}_${pre_samplerate}_${7}.wav" | |||
fi |
@@ -10,12 +10,15 @@ fi | |||
. "$HOME/.noaa.conf" | |||
. "$NOAA_HOME/common.sh" | |||
log "Scheduling new passes" INFO | |||
wget -qr http://www.celestrak.com/NORAD/elements/weather.txt -O "${NOAA_HOME}"/predict/weather.txt | |||
wget -qr http://www.celestrak.com/NORAD/elements/amateur.txt -O "${NOAA_HOME}"/predict/amateur.txt | |||
grep "NOAA 15" "${NOAA_HOME}"/predict/weather.txt -A 2 > "${NOAA_HOME}"/predict/weather.tle | |||
grep "NOAA 18" "${NOAA_HOME}"/predict/weather.txt -A 2 >> "${NOAA_HOME}"/predict/weather.tle | |||
grep "NOAA 19" "${NOAA_HOME}"/predict/weather.txt -A 2 >> "${NOAA_HOME}"/predict/weather.tle | |||
grep "METEOR-M 2" "${NOAA_HOME}"/predict/weather.txt -A 2 >> "${NOAA_HOME}"/predict/weather.tle | |||
grep "METEOR-M2 2" "${NOAA_HOME}"/predict/weather.txt -A 2 >> "${NOAA_HOME}"/predict/weather.tle | |||
if [ "$SCHEDULE_ISS" == "true" ]; then | |||
grep "ZARYA" "${NOAA_HOME}"/predict/amateur.txt -A 2 > "${NOAA_HOME}"/predict/amateur.tle | |||
fi | |||
@@ -27,7 +30,8 @@ for i in $(atq | awk '{print $1}');do atrm "$i";done | |||
if [ "$SCHEDULE_ISS" == "true" ]; then | |||
"${NOAA_HOME}"/schedule_iss.sh "ISS (ZARYA)" 145.8000 | |||
fi | |||
"${NOAA_HOME}"/schedule_meteor.sh "METEOR-M 2" 137.1000 | |||
"${NOAA_HOME}"/schedule_sat.sh "METEOR-M 2" 137.1000 | |||
#"${NOAA_HOME}"/schedule_sat.sh "METEOR-M2 2" 137.9000 #Meteor M2-2 will never send LRPT again :( | |||
"${NOAA_HOME}"/schedule_sat.sh "NOAA 19" 137.1000 | |||
"${NOAA_HOME}"/schedule_sat.sh "NOAA 18" 137.9125 | |||
"${NOAA_HOME}"/schedule_sat.sh "NOAA 15" 137.6200 |
@@ -10,13 +10,13 @@ fi | |||
. "$HOME/.noaa.conf" | |||
. "$NOAA_HOME/common.sh" | |||
PREDICTION_START=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/amateur.tle -p "${1}" | head -1) | |||
PREDICTION_END=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/amateur.tle -p "${1}" | tail -1) | |||
PREDICTION_START=$(predict -t "${NOAA_HOME}"/predict/amateur.tle -p "${1}" | head -1) | |||
PREDICTION_END=$(predict -t "${NOAA_HOME}"/predict/amateur.tle -p "${1}" | tail -1) | |||
var2=$(echo "${PREDICTION_END}" | cut -d " " -f 1) | |||
MAXELEV=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/amateur.tle -p "${1}" | awk -v max=0 '{if($5>max){max=$5}}END{print max}') | |||
MAXELEV=$(predict -t "${NOAA_HOME}"/predict/amateur.tle -p "${1}" | awk -v max=0 '{if($5>max){max=$5}}END{print max}') | |||
while [ "$(date --date="@${var2}" +%D)" = "$(date +%D)" ]; do | |||
START_TIME=$(echo "$PREDICTION_START" | cut -d " " -f 3-4) | |||
@@ -31,12 +31,12 @@ while [ "$(date --date="@${var2}" +%D)" = "$(date +%D)" ]; do | |||
echo ${SATNAME} "${OUTDATE}" "$MAXELEV" | |||
echo "${NOAA_HOME}/receive_iss.sh \"${1}\" $2 ISS${OUTDATE} "${NOAA_HOME}"/predict/amateur.tle \ | |||
${var1} ${TIMER} ${MAXELEV}" | at "$(date --date="TZ=\"UTC\" ${START_TIME}" +"%H:%M %D")" | |||
sqlite3 /home/pi/raspberry-noaa/panel.db "insert or replace into predict_passes (sat_name,pass_start,pass_end,max_elev,is_active) values (\"$SATNAME\",$var1,$var2,$MAXELEV,1);" | |||
sqlite3 $HOME/raspberry-noaa/panel.db "insert or replace into predict_passes (sat_name,pass_start,pass_end,max_elev,is_active) values (\"$SATNAME\",$var1,$var2,$MAXELEV,1);" | |||
fi | |||
NEXTPREDICT=$(expr "${var2}" + 60) | |||
PREDICTION_START=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/amateur.tle -p "${1}" "${NEXTPREDICT}" | head -1) | |||
PREDICTION_END=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/amateur.tle -p "${1}" "${NEXTPREDICT}" | tail -1) | |||
MAXELEV=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/amateur.tle -p "${1}" "${NEXTPREDICT}" | awk -v max=0 '{if($5>max){max=$5}}END{print max}') | |||
PREDICTION_START=$(predict -t "${NOAA_HOME}"/predict/amateur.tle -p "${1}" "${NEXTPREDICT}" | head -1) | |||
PREDICTION_END=$(predict -t "${NOAA_HOME}"/predict/amateur.tle -p "${1}" "${NEXTPREDICT}" | tail -1) | |||
MAXELEV=$(predict -t "${NOAA_HOME}"/predict/amateur.tle -p "${1}" "${NEXTPREDICT}" | awk -v max=0 '{if($5>max){max=$5}}END{print max}') | |||
var2=$(echo "${PREDICTION_END}" | cut -d " " -f 1) | |||
done | |||
@@ -1,42 +0,0 @@ | |||
#!/bin/bash | |||
### Run as a normal user | |||
if [ $EUID -eq 0 ]; then | |||
echo "This script shouldn't be run as root." | |||
exit 1 | |||
fi | |||
## import common lib | |||
. "$HOME/.noaa.conf" | |||
. "$NOAA_HOME/common.sh" | |||
PREDICTION_START=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" | head -1) | |||
PREDICTION_END=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" | tail -1) | |||
var2=$(echo "${PREDICTION_END}" | cut -d " " -f 1) | |||
MAXELEV=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" | awk -v max=0 '{if($5>max){max=$5}}END{print max}') | |||
while [ "$(date --date="@${var2}" +%D)" = "$(date +%D)" ]; do | |||
log "Pass prediction in progress" "INFO" | |||
START_TIME=$(echo "$PREDICTION_START" | cut -d " " -f 3-4) | |||
var1=$(echo "$PREDICTION_START" | cut -d " " -f 1) | |||
var3=$(echo "$START_TIME" | cut -d " " -f 2 | cut -d ":" -f 3) | |||
TIMER=$(expr "${var2}" - "${var1}" + "${var3}") | |||
OUTDATE=$(date --date="TZ=\"UTC\" ${START_TIME}" +%Y%m%d-%H%M%S) | |||
if [ "${MAXELEV}" -gt "${METEOR_MIN_ELEV}" ]; then | |||
log "Pass is above ${METEOR_MIN_ELEV}, that is OK for me" "INFO" | |||
SATNAME=$(echo "$1" | sed "s/ //g") | |||
echo "${SATNAME}" "${OUTDATE}" "$MAXELEV" | |||
echo "${NOAA_HOME}/receive_meteor.sh \"${1}\" $2 ${SATNAME}${OUTDATE} "${NOAA_HOME}"/predict/weather.tle \ | |||
${var1} ${TIMER} ${MAXELEV}" | at "$(date --date="TZ=\"UTC\" ${START_TIME}" +"%H:%M %D")" | |||
sqlite3 /home/pi/raspberry-noaa/panel.db "insert or replace into predict_passes (sat_name,pass_start,pass_end,max_elev,is_active) values (\"$SATNAME\",$var1,$var2,$MAXELEV,1);" | |||
fi | |||
NEXTPREDICT=$(expr "${var2}" + 60) | |||
PREDICTION_START=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" "${NEXTPREDICT}" | head -1) | |||
PREDICTION_END=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" "${NEXTPREDICT}" | tail -1) | |||
MAXELEV=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" "${NEXTPREDICT}" | awk -v max=0 '{if($5>max){max=$5}}END{print max}') | |||
var2=$(echo "${PREDICTION_END}" | cut -d " " -f 1) | |||
done | |||
@@ -18,12 +18,29 @@ fi | |||
# $6 = Time to capture | |||
# $7 = Satellite max elevation | |||
PREDICTION_START=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" | head -1) | |||
PREDICTION_END=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" | tail -1) | |||
if [[ "$1" == *"NOAA"* ]]; then | |||
receive_script="receive_noaa" | |||
elif [[ "$1" == *"METEOR"* ]]; then | |||
receive_script="receive_meteor" | |||
else | |||
log "No recognized receive skript for satellite $1!" ERROR | |||
return -1 | |||
fi | |||
log "Looking for passes of $1" INFO | |||
PREDICTION_START=$(predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" | head -1) | |||
PREDICTION_END=$(predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" | tail -1) | |||
if [ -z "$PREDICTION_START" ]; then | |||
log "predict did not return any values for $1!" ERROR | |||
log "predict -t \"${NOAA_HOME}\"/predict/weather.tle -p \"${1}\"" ERROR | |||
predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" >> /var/log/noaa.log 2>&1 | |||
fi | |||
var2=$(echo "${PREDICTION_END}" | cut -d " " -f 1) | |||
MAXELEV=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" | awk -v max=0 '{if($5>max){max=$5}}END{print max}') | |||
MAXELEV=$(predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" | awk -v max=0 '{if($5>max){max=$5}}END{print max}') | |||
while [ "$(date --date="@${var2}" +%D)" = "$(date +%D)" ]; do | |||
START_TIME=$(echo "$PREDICTION_START" | cut -d " " -f 3-4) | |||
@@ -34,15 +51,17 @@ while [ "$(date --date="@${var2}" +%D)" = "$(date +%D)" ]; do | |||
if [ "${MAXELEV}" -gt "${SAT_MIN_ELEV}" ]; then | |||
SATNAME=$(echo "$1" | sed "s/ //g") | |||
echo "${SATNAME}" "${OUTDATE}" "$MAXELEV" | |||
echo "${NOAA_HOME}/receive.sh \"${1}\" $2 ${SATNAME}${OUTDATE} "${NOAA_HOME}"/predict/weather.tle \ | |||
log "Scheduling ${SATNAME} at ${OUTDATE} $MAXELEV" INFO | |||
echo "${NOAA_HOME}/${receive_script}.sh \"${1}\" $2 ${SATNAME}-${OUTDATE} "${NOAA_HOME}"/predict/weather.tle \ | |||
${var1} ${TIMER} ${MAXELEV}" | at "$(date --date="TZ=\"UTC\" ${START_TIME}" +"%H:%M %D")" | |||
sqlite3 /home/pi/raspberry-noaa/panel.db "insert or replace into predict_passes (sat_name,pass_start,pass_end,max_elev,is_active) values (\"$SATNAME\",$var1,$var2,$MAXELEV, 1);" | |||
sqlite3 $HOME/raspberry-noaa/panel.db "insert or replace into predict_passes (sat_name,pass_start,pass_end,max_elev,is_active) values (\"$SATNAME\",$var1,$var2,$MAXELEV, 1);" | |||
else | |||
log "Max. elevation ${MAXELEV} too small for configured ${SAT_MIN_ELEV}" DEBUG | |||
fi | |||
NEXTPREDICT=$(expr "${var2}" + 60) | |||
PREDICTION_START=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" "${NEXTPREDICT}" | head -1) | |||
PREDICTION_END=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" "${NEXTPREDICT}" | tail -1) | |||
MAXELEV=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" "${NEXTPREDICT}" | awk -v max=0 '{if($5>max){max=$5}}END{print max}') | |||
PREDICTION_START=$(predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" "${NEXTPREDICT}" | head -1) | |||
PREDICTION_END=$(predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" "${NEXTPREDICT}" | tail -1) | |||
MAXELEV=$(predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1}" "${NEXTPREDICT}" | awk -v max=0 '{if($5>max){max=$5}}END{print max}') | |||
var2=$(echo "${PREDICTION_END}" | cut -d " " -f 1) | |||
done | |||
@@ -2,12 +2,12 @@ | |||
import ephem | |||
import time | |||
import sys | |||
timezone = change_tz + time.localtime().tm_isdst | |||
timezone = 1 + time.localtime().tm_isdst | |||
date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(sys.argv[1])-(timezone*60*60))) | |||
obs=ephem.Observer() | |||
obs.lat='change_latitude' | |||
obs.long='change_longitude' | |||
obs.lat='53.06272' | |||
obs.long='8.86' | |||
obs.date = date | |||
sun = ephem.Sun(obs) | |||
@@ -12,7 +12,7 @@ server { | |||
location ~ \.php$ { | |||
include snippets/fastcgi-php.conf; | |||
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; | |||
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock; | |||
} | |||
# Rewrite the old path yyyy/mm/dd/ to /images/ | |||
@@ -1,5 +1,6 @@ | |||
NOAA_HOME=/home/pi/raspberry-noaa | |||
NOAA_OUTPUT=/var/www/wx | |||
NOAA_LOG=/var/log/noaa.log | |||
METEOR_OUTPUT=/var/www/wx/meteor | |||
RAMFS_AUDIO=/var/ramfs | |||
SAT_MIN_ELEV=30 | |||
@@ -11,5 +12,6 @@ LON=change_longitude | |||
BIAS_TEE="enable_bias_tee" | |||
DELETE_AUDIO="true" | |||
FLIP_METEOR_IMG="true" | |||
GAIN=50 | |||
GAIN="-g 50" #leave out for auto-gain | |||
PPM_ERROR=0 | |||
SCHEDULE_ISS="false" |
@@ -0,0 +1,139 @@ | |||
# noaa-apt settings | |||
# Settings file version, newer noaa-apt releases will require more fields and | |||
# variables | |||
version = 3 | |||
check_updates = true | |||
[timestamps] | |||
# Prefer reading recording times from file modification timestamps instead of | |||
# looking at the date and time on the filename. If the filename format is not | |||
# recognised, timestamps are going to be used anyways. In this case the inferred | |||
# satellite will be always NOAA 19 and you will have to indicate it otherwise. | |||
prefer_timestamps = false | |||
# Supported filenames. Indicate where years, hours, etc. are located on the | |||
# filename, used to detemine recording time and satellite received from | |||
# filename. The program will compare the loaded WAV filename against each one of | |||
# these formats until it finds a match, if no match is found, the time will be | |||
# loaded from the file modification timestamp and the sat will be NOAA 19. If | |||
# some date/time value is missing, the current will be used. E.g. if there is no | |||
# month, the current month will be used. | |||
# | |||
# Supported variables: | |||
# - %Y: Year as a 4 digit number. | |||
# - %m: Month as a 2 digit number. | |||
# - %d: Day as a 2 digit number. | |||
# - %H: Hour as a 2 digit number. | |||
# - %M: Minute as a 2 digit number. | |||
# - %S: Second as a 2 digit number. | |||
# - %N: Satellite number, should be 15, 18 or 19. | |||
# - %!: Recording frequency in Hz, also used to determine satellite number | |||
# (noaa-apt knows that e.g. NOAA 19 uses 137.1MHz or close). Should have 9 | |||
# consecutive digits, e.g: 137100000. | |||
# - %1, %2, %3, ..., %9: Ignore 1, 2, 3, ... 9 characters. Useful if the | |||
# filename has something not useful that can change, for example pass elevation. | |||
filenames = [ | |||
# gqrx_20181222_203941_137100000.wav | |||
"gqrx_%Y%m%d_%H%M%S_%!.wav", | |||
# SDRSharp_20200325_204556Z_137102578Hz_AF.wav | |||
"SDRSharp_%Y%m%d_%H%M%SZ_%!Hz_AF.wav", | |||
# On WXtoIMG go to Option > File Names and Locations... | |||
# Set this template: %Y%m%d-%H%M-%e-%s | |||
"%Y%m%d-%H%M-noaa-%N.wav", | |||
# NOAA15-20200325-060601.wav | |||
"NOAA%N-%Y%m%d-%H%M%S.wav", | |||
# N1520200327073417.wav | |||
"N%N%Y%m%d%H%M%S.wav", | |||
# 2020-02-09-05-24-16-NOAA_19.wav | |||
"%Y-%m-%d-%H-%M-%S-NOAA_%N.wav", | |||
# 20200320-213957NOAA19El64.wav | |||
"%Y%m%d-%H%M%SNOAA%NEl%2.wav", | |||
] | |||
# Timezone offset in hours to assume when reading filenames. | |||
timezone = change_tz # UTC+1 | |||
[map_overlay] | |||
# Default colors as RGBA. Set alpha to 0 to disable | |||
default_countries_color = [255, 255, 0, 255] | |||
default_states_color = [255, 255, 0, 150] | |||
default_lakes_color = [50, 200, 200, 255] | |||
[false_color] | |||
# Values used as thresholds for false color algorithm: | |||
# [water, vegetation, clouds] | |||
# Valid values: 0..255 with water < vegetation < clouds | |||
default_false_color_values = [50, 105, 137] | |||
[profiles] | |||
default_profile = "standard" | |||
# Allowed profiles are "standard", "fast", and "slow". Each one has: | |||
# - work_rate: Sample rate to use when processing in Hz. Choose a multiple of | |||
# 4160 equal or bigger than 12480 | |||
# - resample_atten: Attenuation in dB for the resampling filter. | |||
# - resample_delta_freq: Transition band width in Hz for the resampling filter. | |||
# - resample_cutout: Cutout frequency in Hz of the resampling filter. The | |||
# transition band goes from `cutout - delta_freq / 2` to | |||
# `cutout + delta_freq / 2`. | |||
# - demodulation_atten: Attenuation in dB for the demodulation filter. | |||
# - wav_resample_atten: Attenuation in dB, used when resampling a WAV into | |||
# another WAV. Not used when decoding images | |||
# - wav_resample_delta_freq: Transition band width in pi radians per second, | |||
# used when resampling a WAV into another WAV. Not used when decoding images | |||
# Should work perfectly on every image | |||
[profiles.standard] | |||
work_rate = 12480 | |||
resample_atten = 30 | |||
resample_delta_freq = 1000 | |||
resample_cutout = 4800 | |||
demodulation_atten = 25 | |||
wav_resample_atten = 40 | |||
wav_resample_delta_freq = 0.1 | |||
# Fast profile, the filters are less strict and noise can be a problem, but | |||
# it should be barely visible | |||
[profiles.fast] | |||
work_rate = 16640 | |||
resample_atten = 30 | |||
resample_delta_freq = 3000 | |||
resample_cutout = 4800 | |||
demodulation_atten = 23 | |||
wav_resample_atten = 30 | |||
wav_resample_delta_freq = 0.2 | |||
# Should be used temporarily if there is a problem with the "standard" | |||
# profile in some images. But leave a bug report in that case. | |||
[profiles.slow] | |||
work_rate = 20800 | |||
resample_atten = 40 | |||
resample_delta_freq = 500 | |||
resample_cutout = 4800 | |||
demodulation_atten = 25 | |||
wav_resample_atten = 50 | |||
wav_resample_delta_freq = 0.05 |
@@ -0,0 +1,16 @@ | |||
#!/usr/bin/env python3 | |||
import ephem | |||
import time | |||
import sys | |||
timezone = change_tz + time.localtime().tm_isdst | |||
date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(sys.argv[1])-(timezone*60*60))) | |||
obs=ephem.Observer() | |||
obs.lat='change_latitude' | |||
obs.long='change_longitude' | |||
obs.date = date | |||
sun = ephem.Sun(obs) | |||
sun.compute(obs) | |||
sun_angle = float(sun.alt) * 57.2957795 # Rad to deg | |||
print(int(sun_angle)) |
@@ -40,6 +40,7 @@ echo "$(tput setaf 2) | |||
$(tput sgr0) | |||
" | |||
rtl_fm ${BIAS_TEE} -f "$1M" -s 256k -g 48 -p 55 -E deemp -F 9 - \ | |||
echo "rtl_fm ${BIAS_TEE} -f "$1M" -s 256k $GAIN -p $PPM_ERROR -E deemp -F 9 -" | |||
rtl_fm ${BIAS_TEE} -f "$1M" -s 256k $GAIN -p $PPM_ERROR -E deemp -F 9 - \ | |||
| sox -traw -r256k -es -b16 -c1 -V1 - -tmp3 - \ | |||
| socat -u - TCP-LISTEN:8073 1>/dev/null |