Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various improvements and bug-fixes #91

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Imrpoved debugging and readability
Changes:
- Created a function to mark printed messages as "debug". These are messaged that are useful for development and understanding what the code is doing, whilst also potentially displaying necessary values. The messages are *not* sent to the log file.
- Added ability to call pipe commands in the process. It beats having mutliple subprocesses running through Python, and just let the terminal/OS handle it.
- Modified the RTL Test method to look for a different string when checking for dongles. This is caused by the new method of calling "subprocesses" and the use of `printf` in the `rtl_test` source code.
- Added descriptive comments.
GlassesToCSharp committed Jan 5, 2020
commit eb88c57a7daeb5fdd671899068d0f839d663805c
6 changes: 3 additions & 3 deletions autowx2.py
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@

def serverLoop():
# Debug print
print("[DEBUG] Server started")
debugPrint("Server started")
time.sleep(2)
app.run(debug=True, port=webInterfacePort)

@@ -28,7 +28,7 @@ def serverLoop():
saveToFile("%s/start.tmp" % (wwwDir), str(time.time()))

# Debug print
print("[DEBUG] Main program started")
debugPrint("Main program started")
# t1 = Thread(target = serverLoop)
# t1.setDaemon(True)
# t1.start
@@ -38,7 +38,7 @@ def serverLoop():

while True:
# Debug print
print("[DEBUG] Main loop started")
debugPrint("Main loop started")
try:
mainLoop()
finally:
148 changes: 75 additions & 73 deletions autowx2_functions.py
Original file line number Diff line number Diff line change
@@ -45,7 +45,33 @@
satellites = list(satellitesData)
qth = (stationLat, stationLon, stationAlt)

process = subprocess.Popen(["sh", "shell_scripts.sh"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True)

# Allow piping when running a shell/bash command.
import signal
def default_sigpipe():
signal.signal(signal.SIGPIPE, signal.SIG_DFL)


# Every time `subprocess.Popen` is called, a new process is created with the
# same memory footprint as the calling script (source:
# https://stackoverflow.com/a/13329386). At some point in the future, while the
# script is running), it will run out of memory. This will throw a "Cannot
# allocate memory" error, which completely crashes the script, causing the
# entire thing to stop running.
#
# `subprocess.Popen` is called here so that a new process is created with the
# tiny initial memory footprint of the script at the beginning. This in theory
# means that memory allocation errors shouldn't happen (or at least
# significantly reduced).
#
# A separate shell script is written to listen for inputs to call. This simply
# is a way of just adding executables to a pre-existing process. More
# information here: https://stackoverflow.com/a/9674162
process = subprocess.Popen(["sh", "shell_scripts.sh"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True, preexec_fn=default_sigpipe)


def debugPrint(message):
print("[DEBUG] %s" % message)


def mkdir_p(outdir):
@@ -232,25 +258,6 @@ def listNextPases(passTable, howmany):
i += 1


# def runForDuration(cmdline, duration, loggingDir):
# justRun(cmdline, loggingDir, duration)

# outLogFile = logFile(loggingDir)
# teeCommand = ['tee', '-a', outLogFile ] # quick and dirty hack to get log to file

# cmdline = [str(x) for x in cmdline]
# print cmdline

# try:
# p1 = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# _ = subprocess.Popen(teeCommand, stdin=p1.stdout)
# time.sleep(duration)
# p1.terminate()
# except OSError as e:
# log("✖ OS Error during command: " + " ".join(cmdline), style=bc.FAIL)
# log("✖ OS Error: " + e.strerror, style=bc.FAIL)


def justRun(cmdline, loggingDir, duration=-1):
'''Just run the command as long as necesary and return the output'''
outLogFile = logFile(loggingDir)
@@ -260,22 +267,27 @@ def justRun(cmdline, loggingDir, duration=-1):
try:
if (duration != -1):
cmdline = "timeout %d %s" % (duration, cmdline)
print("Running command: %s" % cmdline)
debugPrint("Running command: %s" % cmdline)
process.stdin.write(cmdline + "\n")

lineText = ""
lines = ""
for line in process.stdout.readline():
lineText += line

# Check for unique string that signifies the task has completed
if lineText == "SQsw48V8JZLwGOscVeuO":
# We don't neet to print this
break

if line == "\n":
lines += lineText
lineText = ""
# Keep reading the output until the output gives out a unique string
# that signifies the task has completed.
while lineText != "SQsw48V8JZLwGOscVeuO":
for line in process.stdout.readline():
lineText += line

if lineText == "SQsw48V8JZLwGOscVeuO":
# No need to check the remaining output. The task has
# completed.
break

if line == "\n":
lines += lineText
lineText = ""

debugPrint("Process completed")
return lines
except OSError as e:
log("✖ OS Error during command: " + " ".join(cmdline), style=bc.FAIL)
@@ -284,43 +296,37 @@ def justRun(cmdline, loggingDir, duration=-1):

def runTest(duration=3):
'''Check, if RTL_SDR dongle is connected'''
# TODO: Create a way of just adding executables to a pre-existing process, a process created at the beginning of the program.
# More information here: https://stackoverflow.com/a/9674162
# Error occurring: Cannot allocate memory
# 'subprocess.Popen' creates new process witht the same memory footprint as the calling script - https://stackoverflow.com/a/13329386
# SQsw48V8JZLwGOscVeuO - Unique characters

# child = subprocess.Popen('rtl_test', stdout=subprocess.PIPE,
# stderr=subprocess.PIPE)
# time.sleep(duration)
# child.terminate()
# _, err = child.communicate()

print('Check, if RTL_SDR dongle is connected')
time.sleep(5)
output = justRun(["timeout %d rtl_test" % duration], loggingDir, duration)
# if no device: ['No', 'supported', 'devices', 'found.']
# if OK: ['Found', '1', 'device(s):', '0:', 'Realtek,',
# 'RTL2838UHIDIR,',...
print("Output received")
time.sleep(5)
split = output.split()
print("Split:")
print(split)
info = split[0]
if info == "No":
log("✖ No SDR device found!", style=bc.FAIL)
log(output)

# `rtl_test` uses "fprintf" to print out most of its output, EXCEPT for the
# last line "lost at least XX bytes", which uses "printf". While all the
# output is displayed on the console, only this last line is picked up by
# the new shell script. It seems this is what denotes whether a dongle is
# present AND AVAILABLE. Source code at:
# https://github.com/osmocom/rtl-sdr/blob/b5af355b1d833b3c898a61cf1e072b59b0ea3440/src/rtl_test.c#L147
#
# NOTE: The output from `rtl_test` won't get saved to the log. This is due
# to the "fprintf" output mentioned above. It will however, be printed on
# the console. This may clutter the console, but the logs will stay "clean".
#
# `output` should appear as (or similar): lost at least 12 bytes
# `outputSplit` should appear as (or similar): ['lost', 'at, 'least', '12, 'bytes']
outputSplit = output.split()
if len(outputSplit) <= 0:
log("✖ Failed to find SDR device!", style=bc.FAIL)
return False
elif info == "Found":

info = outputSplit[0]
if info == "lost":
log("SDR device found!")
return True
else:
log("Not sure, if SDR device is there...")
return True
log("Not sure, if SDR device is there. Preventing access to potentially harmful devices.")
return False

def killRtl():
log("Killing all remaining rtl_* processes...")
time.sleep(5)
justRun(["sh bin/kill_rtl.sh"], loggingDir)


@@ -715,8 +721,7 @@ def passTable():
# --------------------------------------------------------------------------- #

def mainLoop():
#Debug print
print("[DEBUG] Main loop started")
debugPrint("Main loop started.")
dongleShift = getDefaultDongleShift()

while True:
@@ -766,10 +771,8 @@ def mainLoop():

# It's a high time to record!
if towait <= 1 and duration > 0:
# Debug print
print("[DEBUG] Recording duration: " + str(duration))
# Debug print
print("[DEBUG] To wait: " + str(towait))
debugPrint("Recording duration: %d seconds" % duration)
debugPrint("Time to wait: %d seconds" % towait)
# here the recording happens
log("!! Recording " + printPass(satellite, start, duration,
peak, azimuth, freq, processWith), style=bc.WARNING)
@@ -783,13 +786,12 @@ def mainLoop():
peak,
azimuth,
freq]
# Debug print
print("[DEBUG] Process command line: ")
print(processCmdline)
debugPrint("Process command line: ")
debugPrint(processCmdline)
cmdline_result = justRun(processCmdline, loggingDir)
# Debug print
print("[DEBUG] Command line result: ")
print(cmdline_result)

debugPrint("Command line result: ")
debugPrint(cmdline_result)
time.sleep(10.0)

# still some time before recording
2 changes: 1 addition & 1 deletion shell_scripts.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash

# Need an input parameter, which should come in the form of a shell
input=""