def run(self): try: self.__open() self.__read() except SerialException as error: events.Post(self._queue).gps_error(error.message) except OSError as error: events.Post(self._queue).gps_error(error) except ValueError as error: events.Post(self._queue).gps_error(error) self.__close()
def __connect(self): self._conn = sqlite3.connect(self._path) self._conn.row_factory = name_factory error = create_database(self._conn) if error is not None: events.Post(self._notify).error(error)
def run(self): while not self._cancel: if self._client is None: endpoints = [self._server] else: endpoints = [self._server, self._client] read, _write, error = select.select(endpoints, [], [], 0.5) for sock in read: if sock is self._server: try: client, _addr = self._server.accept() if self._client is not None: self._client.close() self._client = client result = self._parse.result_connect(VERSION) self.send(result) host = self.__get_client_name(client) info = 'Connection from \'{}\''.format(host) events.Post(self._queue).info(info) except socket.error: self._client = None elif sock is self._client: for line in self.__read(): if line: result = self._parse.parse(line) self.send(result) for sock in error: if sock is self._client: self._client = None sock.close()
def __close_client(self): host = self.__get_client_name(self._client) info = '\'{}\' disconnected'.format(host) events.Post(self._queue).info(info) self._client.close() self._client = None
def __receive(self): self._receive = False events.Post(self._queue).status(events.STATUS_CAPTURE) try: if self._sdr is None: self._sdr = rtlsdr.RtlSdr( device_index=self._settings.recvIndex) self._sdr.set_sample_rate(SAMPLE_RATE) self._sdr.set_center_freq(self._settings.freq * 1e6) time.sleep(1) self._sdr.set_gain(self._settings.recvGain) cal = int(self._settings.recvCal) if cal != 0: self._sdr.set_freq_correction(cal) self._timeStamp = time.time() self._sdr.read_bytes_async(self.__capture, 2 * SAMPLE_RATE * SAMPLE_TIME / BLOCKS) if self._cancel: return events.Post(self._queue).status(events.STATUS_PROCESS) iq = stream_to_complex(self._capture) if self._cancel: return scan = Scan(SAMPLE_RATE, iq) frequencies = scan.search() if self._cancel: return detect = Detect(SAMPLE_RATE, iq, frequencies) collars = detect.search(self._settings.freq * 1e6) events.Post(self._queue).status(events.STATUS_IDLE) events.Post(self._queue).scan_done(collars=collars, timeStamp=self._timeStamp) except IOError as e: error = 'Capture failed: {}'.format(e.message) events.Post(self._queue).error(error)
def __execute(self, command, method, value): if method == Parse.SCAN: if command == Parse.RUN: events.Post(self._queue).scan_start() elif method == Parse.SCANS: self._database.get_scans(self.result_scans) elif method == Parse.SIGNALS: self._database.get_signals(self.result_signals) elif method == Parse.LOG: return self.result(method, self._database.get_log(self.result_log)) elif method == Parse.PORTS: if command == Parse.GET: ports = [ port.device for port in self._settings.gps.get_ports() ] return self.result(method, ports) elif method == Parse.SETTINGS: if command == Parse.GET: return self.result(method, self._settings.get()) elif method == Parse.PORT: if command == Parse.SET: self._settings.gps.port = value events.Post(self._queue).gps_open(0) return self.result(method) elif method == Parse.DELAY: if command == Parse.SET: if value < 0: value = None self._settings.delay = value return self.result(method) elif method == Parse.FREQUENCY: if command == Parse.SET: self._settings.freq = value return self.result(method)
def __read(self): for resp in self.__serial_read(): nmea = resp.split('*') if len(nmea) == 2: data = nmea[0].split(',') if data[0] in ['GPGGA', 'GPGSV']: checksum = self.__checksum(nmea[0]) if checksum == nmea[1]: if data[0] == 'GPGGA': self.__global_fix(data) elif data[0] == 'GPGSV': self.__sats(data) else: warn = 'Invalid checksum for {} sentence'.format(data[0]) events.Post(self._queue).warning(warn)
def __init__(self, settings): print 'Test mode' queue = Queue.Queue() self._receive = Receive(settings, queue) self._signal = signal.signal(signal.SIGINT, self.__close) events.Post(queue).scan_start() while self._receive.isAlive(): if not queue.empty(): self.__process_queue(settings, queue) self.__close()
def __process_queue(self, settings, queue): event = queue.get() eventType = event.get_type() if eventType == events.SCAN_START: print 'Scanning...' self._receive.receive() if eventType == events.STATUS_PROCESS: print 'Processing...' elif eventType == events.SCAN_DONE: collars = event.get_arg('collars') if collars is not None: print 'Signals:' if len(collars): for collar in collars: summary = '\t{:8.4f}MHz {:2} {:4.1f}PPM, {:.4f}dB' level = 10 * log10(collar.level) print summary.format(collar.freq / 1e6, MOD_DESC[collar.mod], collar.rate, level) else: print '\tNo signals found' events.Post(queue).scan_start() elif eventType == events.WARN: warning = 'Warning: {}'.format(event.get_arg('warning')) print warning elif eventType == events.ERR: error = event.get_arg('error') sys.stderr.write(error) self.__close() exit(3) try: time.sleep(0.1) except IOError: pass
def __sats(self, data): message = int(data[1]) messages = int(data[1]) viewed = int(data[3]) if message == 1: self._sats.clear() blocks = (len(data) - 4) / 4 for i in range(0, blocks): sat = int(data[4 + i * 4]) level = data[7 + i * 4] used = True if level == '': level = None used = False else: level = int(level) self._sats[sat] = {'Level': level, 'Used': used} if message == messages and len(self._sats) == viewed: events.Post(self._queue).gps_satellites(self._sats)
def __init__(self, queue, status, database, settings): threading.Thread.__init__(self) self.name = 'Server' self._queue = queue self._status = status self._database = database self._parse = Parse(queue, status, database, settings, self) self._client = None self._server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: self._server.bind(('', HARRIER_PORT)) self._server.listen(5) except socket.error: events.Post(self._queue).error('Could not start server') return self._cancel = False self.start()
def __init__(self, settings, queue): threading.Thread.__init__(self) self.name = 'Receive' self.daemon = True self._settings = settings self._queue = queue self._cancel = False self._receive = False self._sdr = None self._capture = (ctypes.c_ubyte * int(2 * SAMPLE_RATE * SAMPLE_TIME))() self._captureBlock = 0 self._timeStamp = None devices = rtlsdr.librtlsdr.rtlsdr_get_device_count() if self._settings.recvIndex >= devices: error = 'Cannot find device at index {}' error = error.format(self._settings.recvIndex) events.Post(self._queue).error(error) else: self.start()
def __global_fix(self, data): if data[6] in ['1', '2']: lat = self.__coord(data[2], data[3]) lon = self.__coord(data[4], data[5]) events.Post(self._queue).gps_location((lon, lat))
def __timeout(self): self.stop() events.Post(self._queue).gps_error('GPS timed out')
def __init__(self): settings = Settings(self.__arguments()) self._settings = settings print 'Harrier\n' try: print 'Host :\t\t{} ({})'.format( socket.gethostname(), socket.gethostbyname(socket.getfqdn())) except socket.gaierror: pass queue = Queue.Queue() if settings.test: TestMode(settings) return print 'Survey:\t\t{}'.format(settings.survey) self._gps = None self._database = Database(settings.db, queue) self._receive = Receive(settings, queue) self._status = Status(self._database) self._server = Server(queue, self._status, self._database, settings) self._isScanning = False self._cancel = False self._signal = signal.signal(signal.SIGINT, self.__close) halfBand = SAMPLE_RATE / 2e6 print 'Scan range:\t{:.2f}-{:.2f}MHz'.format(settings.freq - halfBand, settings.freq + halfBand) if settings.delay is None: mode = 'Remote' else: mode = 'Automatic, after {}s'.format(settings.delay) print 'Scan mode:\t{}'.format(mode) events.Post(queue).gps_open(0) if settings.delay is not None: events.Post(queue).scan_start() while not self._cancel: if not queue.empty(): self.__process_queue(settings, queue) else: try: time.sleep(0.1) except IOError: pass print '\nExiting...' waiting = self._status.get_wait() if waiting is not None: print '(Waiting for {} to finish)'.format(self._status.get_wait()) self._cancel = True if self._server is not None: self._server.stop() if self._gps is not None: self._gps.stop() if self._receive is not None: self._receive.stop() if self._database is not None: self._database.stop()
def __process_queue(self, settings, queue): if self._cancel: return event = queue.get() eventType = event.get_type() # Start scan if eventType == events.SCAN_START: location = self._status.get_location() if location is None or time.time() - location[1] > GPS_AGE: self._status.set_status(events.STATUS_WAIT) events.Post(queue).scan_start(1) elif not self._isScanning: self._receive.receive() self._server.send_status() # Scan finished elif eventType == events.SCAN_DONE: self._isScanning = False timeStamp = event.get_arg('time') collars = event.get_arg('collars') if collars is not None: self._status.set_signals(len(collars)) for collar in collars: location = self._status.get_location()[0] collar.lon = location[0] collar.lat = location[1] self._database.append_signal(timeStamp, collar, settings.freq, self._settings.survey) else: self._status.set_signals(0) self._server.send_signals(timeStamp, collars) log = 'Found {} signals'.format(len(collars)) logTime = self._database.append_log(log) self._server.send_log(logTime, log) if settings.delay is not None: events.Post(queue).scan_start(settings.delay) self._server.send_status() # Open GPS elif eventType == events.GPS_OPEN: if self._gps is not None: self._gps.stop() self._gps.join() if self._gps is None: print '\nStarting GPS' self._gps = Gps(settings.gps, queue) # GPS location elif eventType == events.GPS_LOC: self._status.set_location(event.get_arg('location')) self._server.send_status() # GPS satellites elif eventType == events.GPS_SATS: self._status.set_sats(event.get_arg('satellites')) self._server.send_sats() # GPS error elif eventType == events.GPS_ERR: self._gps = None error = 'GPS error: {}'.format(event.get_arg('error')) print '\n' + error print 'Retry in {}s'.format(GPS_RETRY) logTime = self._database.append_log(error) self._server.send_log(logTime, error) self._status.clear_gps() self._server.send_status() events.Post(queue).gps_open(GPS_RETRY) # Info elif eventType == events.INFO: self._status.clear_gps() info = 'Info: {}'.format(event.get_arg('info')) print '\n' + info logTime = self._database.append_log(info) self._server.send_log(logTime, info) # Warning elif eventType == events.WARN: self._status.clear_gps() warning = 'Warning: {}'.format(event.get_arg('warning')) print '\n' + warning logTime = self._database.append_log(warning) self._server.send_log(logTime, warning) # Error elif eventType == events.ERR: error = event.get_arg('error') sys.stderr.write(error) logTime = self._database.append_log(error) self._server.send_log(logTime, error) self.__close() else: self._status.set_status(eventType) self._server.send_status()