@@ -0,0 +1,13 @@ | |||
### Meteor M2 decoding | |||
The satellite uses a 72k QPSK 120hz carrier to send very high quality images | |||
## Receiving | |||
Currently, the satellite is using 137.1Mhz as the center frequency, Wide-FM @ 120Khz. I'm using `rtl_fm` @ 288k and `sox` to capture the raw stream. Most likely, the 288k bandwidth may be lower | |||
## Decoding steps | |||
1. Normalize audio stream with `sox gain -n` | |||
2. Use dbdexter's [meteor_demod](https://github.com/dbdexter-dev/meteor_demod) to convert the audio stream to QPSK symbols at a 72k rate | |||
3. Use artlav's [medet_arm](https://github.com/artlav/meteor_decoder) to generate a decoded dump and then a false color image | |||
4. Use dbdexter's [meteor_rectify](https://github.com/dbdexter-dev/meteor_rectify) to correct the visible deformation on Meteor images (wrong aspect ratio) | |||
1. [I made](rectify.py) some changes on the script such as running it as a single process, export to compressed JPG and so on | |||
@@ -2,6 +2,7 @@ | |||
Most of the code and setup stolen from: [Instructables](https://www.instructables.com/id/Raspberry-Pi-NOAA-Weather-Satellite-Receiver/) | |||
### New Features! | |||
- [Meteor M2 full decoding!](METEOR.md) | |||
- Nginx webserver to show images. | |||
- Timestamp and satellite name over every image. | |||
- WXToIMG configured to create several images (HVC,HVCT,MCIR, etc). | |||
@@ -1,4 +1,4 @@ | |||
#!/usr/bin/env python2 | |||
#!/usr/bin/env python3 | |||
# -*- coding: utf-8 -*- | |||
import sys | |||
import tweepy | |||
@@ -6,30 +6,37 @@ | |||
. ~/.noaa.conf | |||
## sane checks | |||
if [ ! -d ${NOAA_HOME} ]; then | |||
mkdir -p ${NOAA_HOME} | |||
if [ ! -d "${NOAA_HOME}" ]; then | |||
mkdir -p "${NOAA_HOME}" | |||
fi | |||
if [ ! -d ${NOAA_OUTPUT} ]; then | |||
mkdir -p ${NOAA_OUTPUT} | |||
if [ ! -d "${NOAA_OUTPUT}" ]; then | |||
mkdir -p "${NOAA_OUTPUT}" | |||
fi | |||
if [ ! -d ${NOAA_AUDIO}/audio/ ]; then | |||
mkdir -p ${NOAA_AUDIO}/audio/ | |||
if [ ! -d "${NOAA_AUDIO}/audio/" ]; then | |||
mkdir -p "${NOAA_AUDIO}/audio/" | |||
fi | |||
if [ ! -d ${NOAA_OUTPUT}/image/ ]; then | |||
mkdir -p ${NOAA_OUTPUT}/image/ | |||
if [ ! -d "${NOAA_OUTPUT}/image/" ]; then | |||
mkdir -p "${NOAA_OUTPUT}/image/" | |||
fi | |||
if [ ! -d ${NOAA_HOME}/map/ ]; then | |||
mkdir -p ${NOAA_HOME}/map/ | |||
if [ ! -d "${NOAA_HOME}/map/" ]; then | |||
mkdir -p "${NOAA_HOME}/map/" | |||
fi | |||
if [ ! -d ${NOAA_HOME}/predict/ ]; then | |||
mkdir -p ${NOAA_HOME}/predict/ | |||
if [ ! -d "${NOAA_HOME}/predict/" ]; then | |||
mkdir -p "${NOAA_HOME}/predict/" | |||
fi | |||
#if pgrep "stream_fm" > /dev/null | |||
#then | |||
# pkill -9 -f stream_fm | |||
# pkill -9 -f rtl_fm | |||
# pkill -9 -f socat | |||
#fi | |||
if pgrep "rtl_fm" > /dev/null | |||
then | |||
exit 1 | |||
@@ -45,13 +52,14 @@ fi | |||
START_DATE=$(date '+%d-%m-%Y %H:%M') | |||
FOLDER_DATE="$(date +%Y)/$(date +%m)/$(date +%d)" | |||
timeout "${6}" /usr/local/bin/rtl_fm -f "${2}"M -s 60k -g 50 -p 55 -E wav -E deemp -F 9 - | /usr/bin/sox -t raw -e signed -c 1 -b 16 -r 60000 - ${NOAA_AUDIO}/audio/"${3}".wav rate 11025 | |||
timeout "${6}" /usr/local/bin/rtl_fm -f "${2}"M -s 60k -g 50 -p 55 -E wav -E deemp -F 9 - | /usr/bin/sox -t raw -e signed -c 1 -b 16 -r 60000 - "${NOAA_AUDIO}/audio/${3}.wav" rate 11025 | |||
sudo renice -19 -p "$(pidof rtl_fm)" | |||
PASS_START=$(expr "$5" + 90) | |||
SUN_ELEV=$(python2 sun.py $PASS_START) | |||
SUN_ELEV=$(python3 sun.py "$PASS_START") | |||
if [ ! -d ${NOAA_OUTPUT}/image/${FOLDER_DATE} ]; then | |||
mkdir -p ${NOAA_OUTPUT}/image/${FOLDER_DATE} | |||
if [ ! -d "{NOAA_OUTPUT}/image/${FOLDER_DATE}" ]; then | |||
mkdir -p "${NOAA_OUTPUT}/image/${FOLDER_DATE}" | |||
fi | |||
if [ "${SUN_ELEV}" -gt "${SUN_MIN_ELEV}" ]; then | |||
@@ -60,17 +68,16 @@ else | |||
ENHANCEMENTS="ZA MCIR MCIR-precip" | |||
fi | |||
/usr/local/bin/wxmap -T "${1}" -H "${4}" -p 0 -l 0 -o "${PASS_START}" ${NOAA_HOME}/map/"${3}"-map.png | |||
/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 | |||
/usr/local/bin/wxtoimg -o -m ${NOAA_HOME}/map/"${3}"-map.png -e $i ${NOAA_AUDIO}/audio/"${3}".wav ${NOAA_OUTPUT}/image/${FOLDER_DATE}/"${3}"-$i.jpg | |||
/usr/bin/convert -quality 90 -format jpg ${NOAA_OUTPUT}/image/${FOLDER_DATE}/"${3}"-$i.jpg -undercolor black -fill yellow -pointsize 18 -annotate +20+20 "${1} $i ${START_DATE}" ${NOAA_OUTPUT}/image/${FOLDER_DATE}/"${3}"-$i.jpg | |||
/usr/bin/gdrive upload --parent 1gehY-0iYkNSkBU9RCDsSTexRaQ_ukN0A ${NOAA_OUTPUT}/image/${FOLDER_DATE}/"${3}"-$i.jpg | |||
/usr/local/bin/wxtoimg -o -m "${NOAA_HOME}/map/${3}-map.png" -e "$i" "${NOAA_AUDIO}/audio/${3}.wav" "${NOAA_OUTPUT}/image/${FOLDER_DATE}/${3}-$i.jpg" | |||
/usr/bin/convert -quality 90 -format jpg "${NOAA_OUTPUT}/image/${FOLDER_DATE}/${3}-$i.jpg" -undercolor black -fill yellow -pointsize 18 -annotate +20+20 "${1} $i ${START_DATE}" "${NOAA_OUTPUT}/image/${FOLDER_DATE}/${3}-$i.jpg" | |||
done | |||
if [ "${SUN_ELEV}" -gt "${SUN_MIN_ELEV}" ]; then | |||
python2 ${NOAA_HOME}/post.py "$1 ${START_DATE}" "$7" ${NOAA_OUTPUT}/image/${FOLDER_DATE}/$3-MCIR-precip.jpg ${NOAA_OUTPUT}/image/${FOLDER_DATE}/$3-MSA-precip.jpg ${NOAA_OUTPUT}/image/${FOLDER_DATE}/$3-HVC-precip.jpg ${NOAA_OUTPUT}/image/${FOLDER_DATE}/$3-HVCT-precip.jpg | |||
python3 "${NOAA_HOME}/post.py" "$1 ${START_DATE}" "$7" "${NOAA_OUTPUT}/image/${FOLDER_DATE}/$3-MCIR-precip.jpg" "${NOAA_OUTPUT}/image/${FOLDER_DATE}/$3-MSA-precip.jpg" "${NOAA_OUTPUT}/image/${FOLDER_DATE}/$3-HVC-precip.jpg" "${NOAA_OUTPUT}/image/${FOLDER_DATE}/$3-HVCT-precip.jpg" | |||
else | |||
python2 ${NOAA_HOME}/post.py "$1 ${START_DATE}" "$7" ${NOAA_OUTPUT}/image/${FOLDER_DATE}/$3-MCIR-precip.jpg ${NOAA_OUTPUT}/image/${FOLDER_DATE}/$3-MCIR.jpg | |||
python3 "${NOAA_HOME}/post.py" "$1 ${START_DATE}" "$7" "${NOAA_OUTPUT}/image/${FOLDER_DATE}/$3-MCIR-precip.jpg" "${NOAA_OUTPUT}/image/${FOLDER_DATE}/$3-MCIR.jpg" | |||
fi | |||
rm ${NOAA_AUDIO}/audio/* | |||
rm "${NOAA_AUDIO}/audio/${3}.wav" |
@@ -1,3 +1,3 @@ | |||
#!/bin/sh | |||
datetime=$(date +"%Y%m%d-%H%M%S") | |||
timeout 660 /usr/local/bin/rtl_fm -M fm -f 145.8M -s 48k -g 50 -p 55 -E wav -E deemp -F 9 - | /usr/bin/sox -t raw -e signed -c 1 -b 16 -r 48000 - /usr/share/html/audio/iss-$datetime.wav rate 11025 | |||
timeout 660 /usr/local/bin/rtl_fm -M fm -f 145.8M -s 48k -g 50 -p 55 -E wav -E deemp -F 9 - | /usr/bin/sox -t raw -e signed -c 1 -b 16 -r 48000 - /usr/share/html/iss/iss-$datetime.wav rate 11025 |
@@ -0,0 +1,74 @@ | |||
#!/bin/sh | |||
## debug | |||
# set -x | |||
. ~/.noaa.conf | |||
## sane checks | |||
if [ ! -d "${NOAA_HOME}" ]; then | |||
mkdir -p "${NOAA_HOME}" | |||
fi | |||
if [ ! -d "${NOAA_OUTPUT}" ]; then | |||
mkdir -p "${NOAA_OUTPUT}" | |||
fi | |||
if [ ! -d "${METEOR_OUTPUT}" ]; then | |||
mkdir -p "${METEOR_OUTPUT}" | |||
fi | |||
if [ ! -d "${NOAA_AUDIO}/audio/" ]; then | |||
mkdir -p "${NOAA_AUDIO}/audio/" | |||
fi | |||
if [ ! -d "${NOAA_OUTPUT}/image/" ]; then | |||
mkdir -p "${NOAA_OUTPUT}/image/" | |||
fi | |||
if [ ! -d "${NOAA_HOME}/map/" ]; then | |||
mkdir -p "${NOAA_HOME}/map/" | |||
fi | |||
if [ ! -d "${NOAA_HOME}/predict/" ]; then | |||
mkdir -p "${NOAA_HOME}/predict/" | |||
fi | |||
if pgrep "rtl_fm" > /dev/null | |||
then | |||
exit 1 | |||
fi | |||
# $1 = Satellite Name | |||
# $2 = Frequency | |||
# $3 = FileName base | |||
# $4 = TLE File | |||
# $5 = EPOC start time | |||
# $6 = Time to capture | |||
# $7 = Satellite max elevation | |||
START_DATE=$(date '+%d-%m-%Y %H:%M') | |||
FOLDER_DATE="$(date +%Y)/$(date +%m)/$(date +%d)" | |||
if [ ! -d "${NOAA_OUTPUT}/image/${FOLDER_DATE}" ]; then | |||
mkdir -p "${NOAA_OUTPUT}/image/${FOLDER_DATE}" | |||
fi | |||
timeout 660 /usr/local/bin/rtl_fm -M raw -f 137.1M -s 288k -g 48 -p 1 | sox -t raw -r 288k -c 2 -b 16 -e s - -t wav "${NOAA_AUDIO}/audio/${3}.wav" rate 96k | |||
sox "${NOAA_AUDIO}/audio/${3}.wav" "${METEOR_OUTPUT}/${3}.wav" gain -n | |||
rm "${NOAA_AUDIO}/audio/${3}.wav" | |||
meteor_demod -B -o "${METEOR_OUTPUT}/${3}.qpsk" "${METEOR_OUTPUT}/${3}.wav" | |||
medet_arm "${METEOR_OUTPUT}/${3}.qpsk" "${METEOR_OUTPUT}/${3}" -cd | |||
if [ -f "${METEOR_OUTPUT}/${3}.dec" ]; then | |||
medet_arm "${METEOR_OUTPUT}/${3}.dec" "${METEOR_OUTPUT}/${3}-122" -r 65 -g 65 -b 64 -d | |||
convert "${METEOR_OUTPUT}/${3}-122.bmp" "${NOAA_OUTPUT}/image/${FOLDER_DATE}/${3}-122.jpg" | |||
python3 "${NOAA_HOME}/rectify.py" "${NOAA_OUTPUT}/image/${FOLDER_DATE}/${3}-122.jpg" | |||
rm "${METEOR_OUTPUT}/${3}-122.bmp" | |||
python3 "${NOAA_HOME}/post.py" "$1 EXPERIMENTAL ${START_DATE}" "$7" "${NOAA_OUTPUT}/image/${FOLDER_DATE}/${3}-122-rectified.jpg" | |||
fi | |||
@@ -0,0 +1,124 @@ | |||
#!/usr/bin/python3 | |||
import sys | |||
import re | |||
from math import atan,sin,cos,sqrt,tan,acos,ceil | |||
from PIL import Image | |||
EARTH_RADIUS = 6371.0 | |||
SAT_HEIGHT = 822.5 | |||
SAT_ORBIT_RADIUS = EARTH_RADIUS + SAT_HEIGHT | |||
SWATH_KM = 2800.0 | |||
THETA_C = SWATH_KM / EARTH_RADIUS | |||
# Note: theta_s is the satellite viewing angle, theta_c is the angle between the projection of the satellite on the | |||
# Earth's surface and the point the satellite is looking at, measured at the center of the Earth | |||
# Compute the satellite angle of view given the center angle | |||
def theta_s(theta_c): | |||
return atan(EARTH_RADIUS * sin(theta_c)/(SAT_HEIGHT+EARTH_RADIUS*(1-cos(theta_c)))) | |||
# Compute the inverse of the function above | |||
def theta_c(theta_s): | |||
delta_sqrt = sqrt(EARTH_RADIUS**2 + tan(theta_s)**2 * | |||
(EARTH_RADIUS**2-SAT_ORBIT_RADIUS**2)) | |||
return acos((tan(theta_s)**2*SAT_ORBIT_RADIUS+delta_sqrt)/(EARTH_RADIUS*(tan(theta_s)**2+1))) | |||
# The nightmare fuel that is the correction factor function. | |||
# It is the reciprocal of d/d(theta_c) of theta_s(theta_c) a.k.a. | |||
# the derivative of the inverse of theta_s(theta_c) | |||
def correction_factor(theta_c): | |||
norm_factor = EARTH_RADIUS/SAT_HEIGHT | |||
tan_derivative_recip = ( | |||
1+(EARTH_RADIUS*sin(theta_c)/(SAT_HEIGHT+EARTH_RADIUS*(1-cos(theta_c))))**2) | |||
arg_derivative_recip = (SAT_HEIGHT+EARTH_RADIUS*(1-cos(theta_c)))**2/(EARTH_RADIUS*cos( | |||
theta_c)*(SAT_HEIGHT+EARTH_RADIUS*(1-cos(theta_c)))-EARTH_RADIUS**2*sin(theta_c)**2) | |||
return norm_factor * tan_derivative_recip * arg_derivative_recip | |||
# Radians position given the absolute x pixel position, assuming that the sensor samples the Earth | |||
# surface with a constant angular step | |||
def theta_center(img_size, x): | |||
ts = theta_s(THETA_C/2.0) * (abs(x-img_size/2.0) / (img_size/2.0)) | |||
return theta_c(ts) | |||
if __name__ == "__main__": | |||
if len(sys.argv) < 2: | |||
print("Usage: {} <input file>".format(sys.argv[0])) | |||
sys.exit(1) | |||
out_fname = re.sub("\..*$", "-rectified", sys.argv[1]) | |||
img = Image.open(sys.argv[1]) | |||
print("Opened {}x{} image".format(img.size[0], img.size[1])) | |||
# Precompute the correction factors | |||
corr = [] | |||
for i in range(img.size[0]): | |||
corr.append(correction_factor(theta_center(img.size[0], i))) | |||
# Estimate the width of the rectified image | |||
rectified_width = ceil(sum(corr)) | |||
rectified_img = Image.new(img.mode, (rectified_width, img.size[1])) | |||
# Get the pixel 2d arrays from both the source image and the target image | |||
orig_pixels = img.load() | |||
rectified_pixels = rectified_img.load() | |||
for row in range(img.size[1]): | |||
if row % 20 == 0: | |||
print("Row {}".format(row)) | |||
# First pass: stretch from the center towards the right side of the image | |||
start_px = orig_pixels[img.size[0]/2, row] | |||
cur_col = int(rectified_width/2) | |||
target_col = cur_col | |||
for col in range(int(img.size[0]/2), img.size[0]): | |||
target_col += corr[col] | |||
end_px = orig_pixels[col, row] | |||
delta = int(target_col) - cur_col | |||
# Linearly interpolate | |||
for i in range(delta): | |||
interp_r = int((start_px[0]*(delta-i) + end_px[0]*i) / delta) | |||
interp_g = int((start_px[1]*(delta-i) + end_px[1]*i) / delta) | |||
interp_b = int((start_px[2]*(delta-i) + end_px[2]*i) / delta) | |||
rectified_pixels[cur_col, row] = (interp_r, interp_g, interp_b) | |||
cur_col += 1 | |||
start_px = end_px | |||
# First pass: stretch from the center towards the left side of the image | |||
start_px = orig_pixels[img.size[0]/2, row] | |||
cur_col = int(rectified_width/2) | |||
target_col = cur_col | |||
for col in range(int(img.size[0]/2)-1, -1, -1): | |||
target_col -= corr[col] | |||
end_px = orig_pixels[col, row] | |||
delta = cur_col - int(target_col) | |||
# Linearly interpolate | |||
for i in range(delta): | |||
interp_r = int((start_px[0]*(delta-i) + end_px[0]*i) / delta) | |||
interp_g = int((start_px[1]*(delta-i) + end_px[1]*i) / delta) | |||
interp_b = int((start_px[2]*(delta-i) + end_px[2]*i) / delta) | |||
rectified_pixels[cur_col, row] = (interp_r, interp_g, interp_b) | |||
cur_col -= 1 | |||
start_px = end_px | |||
print("Writing rectified image to {}".format(out_fname + ".jpg")) | |||
rectified_img.save(out_fname + ".jpg", "JPEG", quality=90) |
@@ -0,0 +1,5 @@ | |||
idna==2.8 | |||
numpy==1.18.1 | |||
Pillow==7.0.0 | |||
tweepy==3.8.0 | |||
urllib3==1.25.8 |
@@ -5,18 +5,20 @@ | |||
. ~/.noaa.conf | |||
wget -qr https://www.celestrak.com/NORAD/elements/weather.txt -O "${NOAA_HOME}"/predict/weather.txt | |||
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 "ZARYA" "${NOAA_HOME}"/predict/amateur.txt -A 2 > "${NOAA_HOME}"/predict/amateur.tle | |||
grep "METEOR-M 2" "${NOAA_HOME}"/predict/weather.txt -A 2 >> "${NOAA_HOME}"/predict/weather.tle | |||
# grep "ZARYA" "${NOAA_HOME}"/predict/amateur.txt -A 2 > "${NOAA_HOME}"/predict/amateur.tle | |||
#Remove all AT jobs | |||
for i in $(atq | awk '{print $1}');do atrm "$i";done | |||
#Schedule Satellite Passes: | |||
#"${NOAA_HOME}"/schedule_iss.sh "ISS (ZARYA)" 145.8000 | |||
"${NOAA_HOME}"/schedule_meteor.sh "METEOR-M 2" 137.1000 | |||
"${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 | |||
"${NOAA_HOME}"/schedule_iss.sh "ISS (ZARYA)" 145.8000 |
@@ -11,27 +11,27 @@ PREDICTION_END=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/amateur.tle -p "${1} | |||
var2=$(echo "${PREDICTION_END}" | cut -d " " -f 1) | |||
var21=`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}') | |||
while [ "$(date --date="@${var2}" +%D)" = "$(date +%D)" ]; do | |||
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 "${SAT_MIN_ELEV}" ] | |||
then | |||
SATNAME=$(echo "$1" | sed "s/ //g") | |||
echo ${SATNAME} "${OUTDATE}" "$MAXELEV" | |||
echo "${NOAA_HOME}/receive_iss.sh \"${1}\" $2 ISS-${OUTDATE} "${NOAA_HOME}"/predict/amateur.tle \ | |||
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 "${SAT_MIN_ELEV}" ] | |||
then | |||
SATNAME=$(echo "$1" | sed "s/ //g") | |||
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")" | |||
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}') | |||
var2=$(echo "${PREDICTION_END}" | cut -d " " -f 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}') | |||
var2=$(echo "${PREDICTION_END}" | cut -d " " -f 1) | |||
done | |||
@@ -0,0 +1,36 @@ | |||
#!/bin/sh | |||
## debug | |||
# set -x | |||
. ~/.noaa.conf | |||
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 | |||
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 | |||
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")" | |||
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 | |||
@@ -10,7 +10,6 @@ PREDICTION_END=$(/usr/bin/predict -t "${NOAA_HOME}"/predict/weather.tle -p "${1} | |||
var2=$(echo "${PREDICTION_END}" | cut -d " " -f 1) | |||
var21=`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}') | |||
@@ -22,10 +21,9 @@ while [ "$(date --date="@${var2}" +%D)" = "$(date +%D)" ]; do | |||
OUTDATE=$(date --date="TZ=\"UTC\" ${START_TIME}" +%Y%m%d-%H%M%S) | |||
if [ "${MAXELEV}" -gt "${SAT_MIN_ELEV}" ] | |||
#if [ "${MAXELEV}" -gt 19 ] | |||
then | |||
SATNAME=$(echo "$1" | sed "s/ //g") | |||
echo ${SATNAME} "${OUTDATE}" "$MAXELEV" | |||
echo "${SATNAME}" "${OUTDATE}" "$MAXELEV" | |||
echo "${NOAA_HOME}/receive.sh \"${1}\" $2 ${SATNAME}${OUTDATE} "${NOAA_HOME}"/predict/weather.tle \ | |||
${var1} ${TIMER} ${MAXELEV}" | at "$(date --date="TZ=\"UTC\" ${START_TIME}" +"%H:%M %D")" | |||
fi | |||
@@ -1,4 +1,4 @@ | |||
#!/usr/bin/env python2 | |||
#!/usr/bin/env python3 | |||
import ephem | |||
import time | |||
import sys | |||
@@ -13,4 +13,4 @@ obs.date = date | |||
sun = ephem.Sun(obs) | |||
sun.compute(obs) | |||
sun_angle = float(sun.alt) * 57.2957795 # Rad to deg | |||
print int(sun_angle) | |||
print(int(sun_angle)) |