Change to python3, moved to argparse, adding a config file for defaults, adding logging

This commit is contained in:
nzkarit 2017-09-10 20:29:20 +12:00
parent dd857bcadc
commit c8e625f608
5 changed files with 87 additions and 21 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
*.iq8s *.iq8s
*.pyc *.pyc
*.log

View File

@ -1,11 +1,14 @@
#!/usr/bin/env python #!/usr/bin/env python3
# #
from HackRF import HackRF from HackRF import HackRF
from PPM import PPM from PPM import PPM
from ModeS import ModeS from ModeS import ModeS
from sys import argv, exit from sys import argv, exit
from optparse import OptionParser import argparse
import configparser
import logging
import logging.config
import os import os
############################################################### ###############################################################
@ -28,29 +31,45 @@ import os
############################################################### ###############################################################
# Further work on fork # Further work on fork
# Copyright (C) 2017 David Robinson # Copyright (C) 2017 David Robinson
def optionParser():
usage = 'usage: %prog [options]' def auto_int(x):
parser = OptionParser(usage=usage) """Parses HEX into for argParser"""
parser.add_option('-i', '--icao', action='store', type='int', dest='icao', default='0xABCDEF', help='The ICAO number for the plane in hex. Ensure the ICAO is prefixed with \'0x\' to ensure this is parsed as a hex number. Default: %default') return int(x, 0)
parser.add_option('--lat', '--latitude', action='store', type='float', dest='latitude', default='12.34', help='Latitude for the plane in decminal degrees. Default: %default')
parser.add_option('--lon', '--long', '--longitude', action='store', type='float', dest='longitude', default='56.78', help='Longitude for the place in decminal degrees. Default: %default') def argParser():
parser.add_option('-a', '--alt', '--altitude', action='store', type='float', dest='altitude', default='9876.5', help='Altitude in decminal feet. Default: %default') #TODO add some contraint checking
parser.add_option('--ca', '--capability', action='store', type='int', dest='capability', default=5, help='The capability. (Think this is always 5 from ADSB messages. More info would be appreciate). Default: %default') description = 'This tool will generate ADS-B data in a form that a hackRF can broadcast. In addition to providing the information at the command the defaults can be changed in the config.cfg file and the the loggin config changed in logging.cfg.'
parser.add_option('--tc', '--typecode', action='store', type='int', dest='typecode', default=11, help='The type for the ADSB messsage. See https://adsb-decode-guide.readthedocs.io/en/latest/content/introduction.html#ads-b-message-types for more information. Default: %default') parser = argparse.ArgumentParser(description=description)
parser.add_option('--ss', '--surveillancestatus', action='store', type='int', dest='surveillancestatus', default=0, help='The surveillance status. (Think this is always 0 from ADSB messages. More info would be appreciate). Default: %default') parser.add_argument('-i', '--icao', action='store', type=auto_int, dest='icao', default=cfg.get('plane', 'icao'), help='The ICAO number for the plane in hex. Ensure the ICAO is prefixed with \'0x\' to ensure this is parsed as a hex number. Default: %(default)s')
parser.add_option('--nicsb', '--nicsupplementb', action='store', type='int', dest='nicsupplementb', default=0, help='The NIC supplement-B.(Think this is always 0 from ADSB messages. More info would be appreciate). Default: %default') parser.add_argument('--lat', '--latitude', action='store', type=float, dest='latitude', default=cfg.getfloat('plane', 'latitude'), help='Latitude for the plane in decminal degrees. Default: %(default)s')
parser.add_option('--time', action='store', type='int', dest='time', default=0, help='The time. (Think this is always 0 from ADSB messages. More info would be appreciate). Default: %default') parser.add_argument('--lon', '--long', '--longitude', action='store', type=float, dest='longitude', default=cfg.getfloat('plane', 'longitude'), help='Longitude for the place in decminal degrees. Default: %(default)s')
parser.add_option('-s', '--surface', action='store', default=False, dest='surface', help='If the plane is on the ground or not. Default: %default') parser.add_argument('-a', '--alt', '--altitude', action='store', type=float, dest='altitude', default=cfg.getfloat('plane', 'altitude'), help='Altitude in decminal feet. Default: %(default)s')
parser.add_option('-o', '--out', '--output', action='store', type='string', default='Samples_256K.iq8s', dest='outputfilename', help='The iq8s output filename. This is the file which you will feed into the hackRF. Default: %default') parser.add_argument('--ca', '--capability', action='store', type=int, dest='capability', default=cfg.getint('plane', 'capability'), help='The capability. (Think this is always 5 from ADSB messages. More info would be appreciate). Default: %(default)s')
parser.add_argument('--tc', '--typecode', action='store', type=int, dest='typecode', default=cfg.getint('plane', 'typecode'), help='The type for the ADSB messsage. See https://adsb-decode-guide.readthedocs.io/en/latest/content/introduction.html#ads-b-message-types for more information. Default: %(default)s')
parser.add_argument('--ss', '--surveillancestatus', action='store', type=int, dest='surveillancestatus', default=cfg.getint('plane', 'surveillancestatus'), help='The surveillance status. (Think this is always 0 from ADSB messages. More info would be appreciate). Default: %(default)s')
parser.add_argument('--nicsb', '--nicsupplementb', action='store', type=int, dest='nicsupplementb', default=cfg.getint('plane', 'nicsupplementb'), help='The NIC supplement-B.(Think this is always 0 from ADSB messages. More info would be appreciate). Default: %(default)s')
parser.add_argument('--time', action='store', type=int, dest='time', default=cfg.getint('plane', 'time'), help='The time. (Think this is always 0 from ADSB messages. More info would be appreciate). Default: %(default)s')
parser.add_argument('-s', '--surface', action='store', default=cfg.getboolean('plane', 'surface'), type=bool, dest='surface', help='If the plane is on the ground or not. Default: %(default)s')
parser.add_argument('-o', '--out', '--output', action='store', type=str, default=cfg.get('general', 'outputfilename'), dest='outputfilename', help='The iq8s output filename. This is the file which you will feed into the hackRF. Default: %(default)s')
parser.add_argument('-r', '--repeats', action='store', dest='repeats', type=int, default=cfg.getint('general', 'repeats'), help='How many repeats of the data to perform. Default: %(default)s')
return parser.parse_args() return parser.parse_args()
if __name__ == "__main__": if __name__ == "__main__":
global cfg
cfg = configparser.ConfigParser()
cfg.read('config.cfg')
options, arguments = optionParser() arguments = argParser()
print options
global logger
logging.config.fileConfig('logging.cfg')
logger = logging.getLogger(__name__)
logger.info('Starting ADSB Encoder')
logger.debug('The arguments: %s' % (arguments))
modes = ModeS() modes = ModeS()
(df17_even, df17_odd) = modes.df17_pos_rep_encode(options.capability, options.icao, options.typecode, options.surveillancestatus, options.nicsupplementb, options.altitude, options.time, options.latitude, options.longitude, options.surface) (df17_even, df17_odd) = modes.df17_pos_rep_encode(arguments.capability, arguments.icao, arguments.typecode, arguments.surveillancestatus, arguments.nicsupplementb, arguments.altitude, arguments.time, arguments.latitude, arguments.longitude, arguments.surface)
ppm = PPM() ppm = PPM()
df17_array = ppm.frame_1090es_ppm_modulate(df17_even, df17_odd) df17_array = ppm.frame_1090es_ppm_modulate(df17_even, df17_odd)
@ -60,5 +79,8 @@ if __name__ == "__main__":
SamplesFile = open('tmp.iq8s', 'wb') SamplesFile = open('tmp.iq8s', 'wb')
SamplesFile.write(samples_array) SamplesFile.write(samples_array)
os.system("dd if=tmp.iq8s of=%s bs=4k seek=63" % (options.outputfilename)) SamplesFile.close()
os.system("dd if=tmp.iq8s of=%s bs=4k seek=63" % (arguments.outputfilename)) # TODO redirect output to /dev/null
os.system('sync')
os.system('rm tmp.iq8s') os.system('rm tmp.iq8s')

View File

@ -32,7 +32,7 @@ class ModeSLocation:
def encode_alt_modes(self, alt, bit13): def encode_alt_modes(self, alt, bit13):
mbit = False mbit = False
qbit = True qbit = True
encalt = (int(alt) + 1000) / 25 encalt = int((int(alt) + 1000) / 25)
if bit13 is True: if bit13 is True:
tmp1 = (encalt & 0xfe0) << 2 tmp1 = (encalt & 0xfe0) << 2

15
config.cfg Normal file
View File

@ -0,0 +1,15 @@
[general]
outputfilename = Samples_256K.iq8s
repeats = 1
[plane]
icao = 0xABCDEF
latitude = 12.34
longitude = 56.78
altitude = 9876.5
capability = 5
typecode = 11
surveillancestatus = 0
nicsupplementb = 0
time = 0
surface = false

28
logging.cfg Normal file
View File

@ -0,0 +1,28 @@
[loggers]
keys=root
[handlers]
keys=consoleHandler, timedRotatingFileHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler, timedRotatingFileHandler
[handler_timedRotatingFileHandler]
class=handlers.TimedRotatingFileHandler
level=DEBUG
formatter=simpleFormatter
args=('ADSB_Encoder.log', 'H', 1, 72)
[handler_consoleHandler]
class=StreamHandler
level=WARNING
formatter=simpleFormatter
args=(sys.stdout,)
[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=