@@ -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/) | Most of the code and setup stolen from: [Instructables](https://www.instructables.com/id/Raspberry-Pi-NOAA-Weather-Satellite-Receiver/) | ||||
### New Features! | ### New Features! | ||||
- [Meteor M2 full decoding!](METEOR.md) | |||||
- Nginx webserver to show images. | - Nginx webserver to show images. | ||||
- Timestamp and satellite name over every image. | - Timestamp and satellite name over every image. | ||||
- WXToIMG configured to create several images (HVC,HVCT,MCIR, etc). | - 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 -*- | # -*- coding: utf-8 -*- | ||||
import sys | import sys | ||||
import tweepy | import tweepy | ||||
@@ -6,30 +6,37 @@ | |||||
. ~/.noaa.conf | . ~/.noaa.conf | ||||
## sane checks | ## sane checks | ||||
if [ ! -d ${NOAA_HOME} ]; then | |||||
mkdir -p ${NOAA_HOME} | |||||
if [ ! -d "${NOAA_HOME}" ]; then | |||||
mkdir -p "${NOAA_HOME}" | |||||
fi | fi | ||||
if [ ! -d ${NOAA_OUTPUT} ]; then | |||||
mkdir -p ${NOAA_OUTPUT} | |||||
if [ ! -d "${NOAA_OUTPUT}" ]; then | |||||
mkdir -p "${NOAA_OUTPUT}" | |||||
fi | fi | ||||
if [ ! -d ${NOAA_AUDIO}/audio/ ]; then | |||||
mkdir -p ${NOAA_AUDIO}/audio/ | |||||
if [ ! -d "${NOAA_AUDIO}/audio/" ]; then | |||||
mkdir -p "${NOAA_AUDIO}/audio/" | |||||
fi | fi | ||||
if [ ! -d ${NOAA_OUTPUT}/image/ ]; then | |||||
mkdir -p ${NOAA_OUTPUT}/image/ | |||||
if [ ! -d "${NOAA_OUTPUT}/image/" ]; then | |||||
mkdir -p "${NOAA_OUTPUT}/image/" | |||||
fi | fi | ||||
if [ ! -d ${NOAA_HOME}/map/ ]; then | |||||
mkdir -p ${NOAA_HOME}/map/ | |||||
if [ ! -d "${NOAA_HOME}/map/" ]; then | |||||
mkdir -p "${NOAA_HOME}/map/" | |||||
fi | fi | ||||
if [ ! -d ${NOAA_HOME}/predict/ ]; then | |||||
mkdir -p ${NOAA_HOME}/predict/ | |||||
if [ ! -d "${NOAA_HOME}/predict/" ]; then | |||||
mkdir -p "${NOAA_HOME}/predict/" | |||||
fi | 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 | if pgrep "rtl_fm" > /dev/null | ||||
then | then | ||||
exit 1 | exit 1 | ||||
@@ -45,13 +52,14 @@ fi | |||||
START_DATE=$(date '+%d-%m-%Y %H:%M') | START_DATE=$(date '+%d-%m-%Y %H:%M') | ||||
FOLDER_DATE="$(date +%Y)/$(date +%m)/$(date +%d)" | 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) | 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 | fi | ||||
if [ "${SUN_ELEV}" -gt "${SUN_MIN_ELEV}" ]; then | if [ "${SUN_ELEV}" -gt "${SUN_MIN_ELEV}" ]; then | ||||
@@ -60,17 +68,16 @@ else | |||||
ENHANCEMENTS="ZA MCIR MCIR-precip" | ENHANCEMENTS="ZA MCIR MCIR-precip" | ||||
fi | 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 | 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 | done | ||||
if [ "${SUN_ELEV}" -gt "${SUN_MIN_ELEV}" ]; then | 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 | 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 | fi | ||||
rm ${NOAA_AUDIO}/audio/* | |||||
rm "${NOAA_AUDIO}/audio/${3}.wav" |
@@ -1,3 +1,3 @@ | |||||
#!/bin/sh | #!/bin/sh | ||||
datetime=$(date +"%Y%m%d-%H%M%S") | 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 | . ~/.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 | 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 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 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 "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 | #Remove all AT jobs | ||||
for i in $(atq | awk '{print $1}');do atrm "$i";done | for i in $(atq | awk '{print $1}');do atrm "$i";done | ||||
#Schedule Satellite Passes: | #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 19" 137.1000 | ||||
"${NOAA_HOME}"/schedule_sat.sh "NOAA 18" 137.9125 | "${NOAA_HOME}"/schedule_sat.sh "NOAA 18" 137.9125 | ||||
"${NOAA_HOME}"/schedule_sat.sh "NOAA 15" 137.6200 | "${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) | 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}') | 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 | 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")" | ${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 | 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) | 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}') | 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) | OUTDATE=$(date --date="TZ=\"UTC\" ${START_TIME}" +%Y%m%d-%H%M%S) | ||||
if [ "${MAXELEV}" -gt "${SAT_MIN_ELEV}" ] | if [ "${MAXELEV}" -gt "${SAT_MIN_ELEV}" ] | ||||
#if [ "${MAXELEV}" -gt 19 ] | |||||
then | then | ||||
SATNAME=$(echo "$1" | sed "s/ //g") | 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 \ | 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")" | ${var1} ${TIMER} ${MAXELEV}" | at "$(date --date="TZ=\"UTC\" ${START_TIME}" +"%H:%M %D")" | ||||
fi | fi | ||||
@@ -1,4 +1,4 @@ | |||||
#!/usr/bin/env python2 | |||||
#!/usr/bin/env python3 | |||||
import ephem | import ephem | ||||
import time | import time | ||||
import sys | import sys | ||||
@@ -13,4 +13,4 @@ obs.date = date | |||||
sun = ephem.Sun(obs) | sun = ephem.Sun(obs) | ||||
sun.compute(obs) | sun.compute(obs) | ||||
sun_angle = float(sun.alt) * 57.2957795 # Rad to deg | sun_angle = float(sun.alt) * 57.2957795 # Rad to deg | ||||
print int(sun_angle) | |||||
print(int(sun_angle)) |