def run(self): """ Start counting time. This method does NOT return, so run in a subprocess if you want to keep control. However, setting self.running = False will stop, as will a KeyboardInterrupt. """ this_start, this_end = self.get_interval(time.time()) self.vprint( 1, ('Manager is starting to run at {}' + ' with intervals of {}s').format( datetime_from_epoch(this_start), self.interval)) self.running = True try: while self.running: self.vprint(3, 'Sleeping at {} until {}'.format( datetime_from_epoch(time.time()), datetime_from_epoch(this_end))) try: self.sleep_until(this_end) except SleepError: self.vprint(1, 'SleepError: system clock skipped ahead!') # the previous start/end times are meaningless. # There are a couple ways this could be handled. # 1. keep the same start time, but go until time.time() # - but if there was actually an execution delay, # the CPM will be too high. # 2. set start time to be time.time() - interval, # and end time is time.time(). # - but if the system clock was adjusted halfway through # the interval, the CPM will be too low. # The second one is more acceptable. self.vprint( 3, 'former this_start = {}, this_end = {}'.format( datetime_from_epoch(this_start), datetime_from_epoch(this_end))) this_start, this_end = self.get_interval( time.time() - self.interval) self.handle_cpm(this_start, this_end) if self.quit_after_interval: self.vprint(1, 'Reboot: taking down Manager') self.stop() self.takedown() os.system('sudo {0} {1}'.format( REBOOT_SCRIPT, self.branch)) this_start, this_end = self.get_interval(this_end) except KeyboardInterrupt: self.vprint(1, '\nKeyboardInterrupt: stopping Manager run') self.stop() self.takedown() except SystemExit: self.vprint(1, '\nSystemExit: taking down Manager') self.stop() self.takedown()
def main(self, datalog, calibrationlog, spectra, this_start, this_end): """ Determines how to handle the spectra data. """ start_text = datetime_from_epoch(this_start).strftime(strf) end_text = datetime_from_epoch(this_end).strftime(strf) self.vprint( 1, SPECTRA_DISPLAY_TEXT.format( time=datetime_from_epoch(time.time()), total_counts=sum(spectra), start_time=start_text, end_time=end_text)) self.manager.data_log(datalog, spectra=spectra) self.manager.calibration_log(calibrationlog, spectra) if self.manager.test: # for testing the memory queue self.send_to_memory(spectra) elif not self.manager.config: self.no_config_send(spectra) elif not self.manager.publickey: self.no_publickey_send(spectra) else: try: self.regular_send(this_end, spectra) except (socket.gaierror, socket.error, socket.timeout) as e: if e == socket.gaierror: if e[0] == socket.EAI_AGAIN: # TCP and UDP # network is down, but NetworkStatus didn't notice yet # (resolving DNS like dosenet.dhcp.lbl.gov) self.vprint( 1, 'Failed to send packet! Address resolution error') else: self.vprint( 1, 'Failed to send packet! Address error: ' + '{}: {}'.format(*e)) elif e == socket.error: if e[0] == errno.ECONNREFUSED: # TCP # server is not accepting connections self.vprint( 1, 'Failed to send packet! Connection refused') elif e[0] == errno.ENETUNREACH: # TCP and UDP # network is down, but NetworkStatus didn't notice yet # (IP like 131.243.51.241) self.vprint( 1, 'Failed to send packet! Network is unreachable') else: # consider handling errno.ECONNABORTED errno.ECONNRESET self.vprint( 1, 'Failed to send packet! Socket error: ' + '{}: {}'.format(*e)) elif e == socket.timeout: # TCP self.vprint(1, 'Failed to send packet! Socket timeout') self.send_to_memory(spectra)
def add_data(self, queue, spectra, maxspectra): """ Takes data from datalog and places it in a queue. Rebin data here. Applies to waterfall plot. """ ''' Create a new spectrum by binning the old spectrum. ''' new_spectra = self.rebin(spectra) ''' Add the new spectrum to queue. ''' queue.append(new_spectra) self.time_stamp.append(datetime_from_epoch(time.time())) self.disp_count.append(sum(spectra)) ''' Save the original size of the data queue. ''' data_length = len(queue) ''' Pop off the first data point if the total number of counts in the spectrum is more than the count window defined by the sum interval to create a running average. ''' if data_length > maxspectra: queue.popleft() if len(self.time_stamp) > maxspectra: self.time_stamp = self.time_stamp[1:] self.disp_count = self.disp_count[1:] self.run_avg, self.sum_data = self.run_avg_data(self.queue) self.make_image()
def count(self, pin=SIGNAL_PIN): """ Add one count to queue. (Callback for GPIO pin) pin argument is supplied by GPIO.add_event_detect, do not remove """ # watching for stray errors... (temp?) try: # add to queue. (usually takes ~10 us) now = time.time() self.counts.append(now) # display(s) self.vprint(1, '\tCount at {}'.format(datetime_from_epoch(now))) if self.LED: self.LED.flash() except: if self.logfile: with open(self.logfile, 'a') as f: traceback.print_exc(15, f) raise
def run(self): this_start, this_end = self.get_interval(time.time()) self.vprint(1, ('Manager is starting to run at {}' + ' with intervals of {}s').format( datetime_from_epoch(this_start), self.interval)) self.running = True try: while self.running: self.handle_air_counts(this_start, this_end) this_start, this_end = self.get_interval(this_end) except KeyboardInterrupt: self.vprint(1, '\nKeyboardInterrupt: stopping Manager run') self.stop() self.takedown() except SystemExit: self.vprint(1, '\nSystemExit: taking down Manager') self.stop() self.takedown()
def run(self): """ Main method to run the sensors continuously, the run procedure is determined by the sensor_type of the instance. """ if self.new_setup: self.vprint( 1, NEW_SENSOR_DISPLAY_TEXT.format(sensor_name=self.sensor_names[self.sensor_type-1])) else: self.vprint( 1, OLD_SENSOR_DISPLAY_TEXT.format(sensor_name=self.sensor_names[self.sensor_type-1])) this_start, this_end = self.get_interval(time.time()) if self.sensor_type != 2: self.vprint( 1, RUNNING_DISPLAY_TEXT.format( start_time=datetime_from_epoch(this_start).strftime(strf), date=str(datetime.date.today()), interval=self.interval)) self.running = True if self.sensor_type == 1: try: while self.running: self.vprint(3, 'Sleeping at {} until {}'.format( datetime_from_epoch(time.time()), datetime_from_epoch(this_end))) try: self.sleep_until(this_end) except SleepError: self.vprint(1, 'SleepError: system clock skipped ahead!') self.vprint( 3, 'former this_start = {}, this_end = {}'.format( datetime_from_epoch(this_start), datetime_from_epoch(this_end))) this_start, this_end = self.get_interval( time.time() - self.interval) self.handle_data(this_start, this_end, None) if self.quit_after_interval: self.vprint(1, 'Reboot: taking down Manager') self.stop() self.takedown() os.system('sudo {0} {1}'.format( REBOOT_SCRIPT, self.branch)) this_start, this_end = self.get_interval(this_end) except KeyboardInterrupt: self.vprint(1, '\nKeyboardInterrupt: stopping Manager run') self.stop() self.takedown() except SystemExit: self.vprint(1, '\nSystemExit: taking down Manager') self.stop() self.takedown() if self.sensor_type == 2: print("Attempting to connect to D3S now") if self.transport == 'any': devs = kromek.discover() else: devs = kromek.discover(self.transport) if len(devs) <= 0: print("No D3S connected, exiting manager now") self.d3s_LED.stop_blink() self.d3s_presence = False GPIO.cleanup() return else: print ('Discovered %s' % devs) print("D3S device found, checking for data now") self.d3s_LED.start_blink(interval=self.d3s_LED_blink_period_2) self.d3s_presence = True filtered = [] for dev in devs: if self.device == 'all' or dev[0] in self.device: filtered.append(dev) devs = filtered if len(devs) <= 0: print("No D3S connected, exiting manager now") self.d3s_LED.stop_blink() self.d3s_presence = False GPIO.cleanup() return signal.alarm(10) # Checks if the RaspberryPi is getting data from the D3S and turns on # the red LED if it is. If a D3S is connected but no data is being recieved, # it tries a couple times then reboots the RaspberryPi. if self.d3s_presence: try: test_time_outer = time.time() + self.signal_test_time + 25 while time.time() < test_time_outer: test_time_inner = time.time() + self.signal_test_time + 5 while time.time() < test_time_inner: try: with kromek.Controller(devs, self.signal_test_time) as controller: for reading in controller.read(): if sum(reading[4]) != 0: self.d3s_light_switch = True signal.alarm(0) break else: break except Exception as e: print(e) print("Data acquisition attempt {} failed".format(self.d3s_data_attempts)) if self.d3s_data_attempts != self.d3s_data_lim: signal.alarm(10) self.d3s_data_attempts += 1 if self.d3s_light_switch: print("Data from D3S found on attempt {}".format(self.d3s_data_attempts)) break if self.d3s_data_attempts > self.d3s_data_lim: print("Failed to find data from D3S {} times".format(self.d3s_data_attempts-1)) print("The D3S is either having data collection issues or is currently off") self.d3s_presence = False break except KeyboardInterrupt: self.vprint(1, '\nKeyboardInterrupt: stopping Manager run') self.takedown() except SystemExit: self.vprint(1, '\nSystemExit: taking down Manager') self.takedown() if self.d3s_light_switch: self.d3s_LED.stop_blink() print("D3S data connection found, continuing with normal data collection") self.d3s_LED.on() else: self.d3s_LED.stop_blink() print("Turning off light and will try to gather data again at reboot") self.d3s_LED.off() GPIO.cleanup() return if self.d3s_presence: self.vprint( 1, RUNNING_DISPLAY_TEXT.format( start_time=datetime_from_epoch(this_start).strftime(strf), date=str(datetime.date.today()), interval=self.interval)) done_devices = set() try: while self.running: with kromek.Controller(devs, self.interval) as controller: for reading in controller.read(): if self.create_structures: self.total = np.array(reading[4]) self.lst = np.array([reading[4]]) self.create_structures = False else: self.total += np.array(reading[4]) self.lst = np.concatenate( (self.lst, [np.array(reading[4])])) serial = reading[0] dev_count = reading[1] if serial not in done_devices: this_start, this_end = self.get_interval( time.time() - self.interval) self.handle_data( this_start, this_end, reading[4]) if dev_count >= self.count > 0: done_devices.add(serial) controller.stop_collector(serial) if len(done_devices) >= len(devs): break except KeyboardInterrupt: self.vprint(1, '\nKeyboardInterrupt: stopping Manager run') self.takedown() except SystemExit: self.vprint(1, '\nSystemExit: taking down Manager') self.takedown() if self.sensor_type == 3 or self.sensor_type == 4 or self.sensor_type == 5: try: while self.running: self.handle_data(this_start, this_end, None) this_start, this_end = self.get_interval(this_end) except KeyboardInterrupt: self.vprint(1, '\nKeyboardInterrupt: stopping Manager run') self.stop() self.takedown() except SystemExit: self.vprint(1, '\nSystemExit: taking down Manager') self.stop() self.takedown()
def main(self, datalog, this_start, this_end, **kwargs): """ Determines how to handle the sensor data. """ start_text = datetime_from_epoch(this_start).strftime(strf) end_text = datetime_from_epoch(this_end).strftime(strf) date = str(datetime.date.today()) if self.manager.sensor_type == 1: cpm, cpm_err = kwargs.get('cpm'), kwargs.get('cpm_err') counts = kwargs.get('counts') self.vprint(1, SINGLE_BREAK_LINE) self.vprint( 1, TIME_DISPLAY_TEXT.format(start_time=start_text, end_time=end_text, date=date)) self.vprint( 1, CPM_DISPLAY_TEXT.format(counts=counts, cpm=cpm, cpm_err=cpm_err)) self.vprint(1, SINGLE_BREAK_LINE) self.manager.data_log(datalog, cpm=cpm, cpm_err=cpm_err) if self.manager.test: self.send_to_memory(cpm=cpm, cpm_err=cpm_err) elif not self.manager.config: self.no_config_send(cpm=cpm, cpm_err=cpm_err) elif not self.manager.publickey: self.no_publickey_send(cpm=cpm, cpm_err=cpm_err) if self.manager.sensor_type == 2: spectra = kwargs.get('spectra') calibrationlog = kwargs.get('calibrationlog') self.vprint(1, SINGLE_BREAK_LINE) self.vprint( 1, TIME_DISPLAY_TEXT.format(start_time=start_text, end_time=end_text, date=date)) self.vprint(1, SPECTRA_DISPLAY_TEXT.format(total_counts=sum(spectra))) self.vprint(1, SINGLE_BREAK_LINE) self.manager.data_log(datalog, spectra=spectra) self.manager.calibration_log(calibrationlog, spectra) if self.manager.test: self.send_to_memory(spectra=spectra) elif not self.manager.config: self.no_config_send(spectra=spectra) elif not self.manager.publickey: self.no_publickey_send(spectra=spectra) if self.manager.sensor_type == 3: average_data = kwargs.get('average_data') self.vprint(1, SINGLE_BREAK_LINE) self.vprint( 1, TIME_DISPLAY_TEXT.format(start_time=start_text, end_time=end_text, date=date)) for i in range(3): self.vprint( 1, AQ_PM_DISPLAY_TEXT.format(variable=self.variables[i], avg_data=average_data[i])) for i in range(3, 9): self.vprint( 1, AQ_P_DISPLAY_TEXT.format(variable=self.variables[i], avg_data=average_data[i])) self.vprint(1, SINGLE_BREAK_LINE) self.manager.data_log(datalog, average_data=average_data) if self.manager.test: self.send_to_memory(average_data=average_data) elif not self.manager.config: self.no_config_send(average_data=average_data) elif not self.manager.publickey: self.no_publickey_send(average_data=average_data) if self.manager.sensor_type == 4: average_data = kwargs.get('average_data') self.vprint(1, SINGLE_BREAK_LINE) self.vprint( 1, TIME_DISPLAY_TEXT.format(start_time=start_text, end_time=end_text, date=date)) for i in range(len(self.variables)): self.vprint( 1, CO2_DISPLAY_TEXT.format(variable=self.variables[i], data=average_data[i])) self.vprint(1, SINGLE_BREAK_LINE) self.manager.data_log(datalog, average_data=average_data) if self.manager.test: self.send_to_memory(average_data=average_data) elif not self.manager.config: self.no_config_send(average_data=average_data) elif not self.manager.publickey: self.no_publickey_send(average_data=average_data) if self.manager.sensor_type == 5: average_data = kwargs.get('average_data') self.vprint(1, SINGLE_BREAK_LINE) self.vprint( 1, TIME_DISPLAY_TEXT.format(start_time=start_text, end_time=end_text, date=date)) for i in range(len(self.variables)): self.vprint( 1, WEATHER_DISPLAY_TEXT.format(variable=self.variables[i], unit=self.variables_units[i], data=average_data[i])) self.vprint(1, SINGLE_BREAK_LINE) self.manager.data_log(datalog, average_data=average_data) if self.manager.test: self.send_to_memory(average_data=average_data) elif not self.manager.config: self.no_config_send(average_data=average_data) elif not self.manager.publickey: self.no_publickey_send(average_data=average_data) if not self.manager.test: try: if self.manager.sensor_type == 1: self.regular_send(this_end, cpm=cpm, cpm_err=cpm_err) if self.manager.sensor_type == 2: self.regular_send(this_end, spectra=spectra) if self.manager.sensor_type == 3 or \ self.manager.sensor_type == 4 or self.manager.sensor_type == 5: self.regular_send(this_end, average_data=average_data) except (socket.gaierror, socket.error, socket.timeout) as e: if e == socket.gaierror: if e[0] == socket.EAI_AGAIN: # TCP and UDP # network is down, but NetworkStatus didn't notice yet # (resolving DNS like dosenet.dhcp.lbl.gov) self.vprint( 1, 'Failed to send packet! Address resolution error') else: self.vprint( 1, 'Failed to send packet! Address error: ' + '{}: {}'.format(*e)) elif e == socket.error: if e[0] == errno.ECONNREFUSED: # TCP # server is not accepting connections self.vprint( 1, 'Failed to send packet! Connection refused') elif e[0] == errno.ENETUNREACH: # TCP and UDP # network is down, but NetworkStatus didn't notice yet # (IP like 131.243.51.241) self.vprint( 1, 'Failed to send packet! Network is unreachable') else: # consider handling errno.ECONNABORTED errno.ECONNRESET self.vprint( 1, 'Failed to send packet! Socket error: ' + '{}: {}'.format(*e)) elif e == socket.timeout: # TCP self.vprint(1, 'Failed to send packet! Socket timeout') if self.manager.sensor_type == 1: if self.send_fail: self.led.stop_blink() self.led.off() if not self.send_fail: self.send_fail = True self.led.start_blink( interval=self.blink_period_lost_connection) self.send_to_memory(cpm=cpm, cpm_err=cpm_err) if self.manager.sensor_type == 2: self.send_to_memory(spectra=spectra) if self.manager.sensor_type == 3 or \ self.manager.sensor_type == 4 or self.manager.sensor_type == 5: self.send_to_memory(average_data=average_data)
def main(self, datalog, average_data, this_start, this_end): """ Determines how to handle the average air quality data """ start_text = datetime_from_epoch(this_start).strftime(strf) end_text = datetime_from_epoch(this_end).strftime(strf) self.vprint( 1, TIME_DISPLAY_TEXT.format( start_time=start_text, end_time=end_text)) for i in range(3): self.vprint( 1, AQ_PM_DISPLAY_TEXT.format( variable=self.variables[i], avg_data=average_data[i])) for i in range(3, 9): self.vprint( 1, AQ_P_DISPLAY_TEXT.format( variable=self.variables[i], avg_data=average_data[i])) self.vprint( 1, BREAK_LINE) self.manager.data_log(datalog, average_data=average_data) if self.manager.test: self.send_to_memory(average_data) elif not self.manager.config: self.no_config_send(average_data) elif not self.manager.publickey: self.no_publickey_send(average_data) else: try: self.regular_send(this_end, average_data) except (socket.gaierror, socket.error, socket.timeout) as e: if e == socket.gaierror: if e[0] == socket.EAI_AGAIN: # TCP and UDP # network is down, but NetworkStatus didn't notice yet # (resolving DNS like dosenet.dhcp.lbl.gov) self.vprint( 1, 'Failed to send packet! Address resolution error') else: self.vprint( 1, 'Failed to send packet! Address error: ' + '{}: {}'.format(*e)) elif e == socket.error: if e[0] == errno.ECONNREFUSED: # TCP # server is not accepting connections self.vprint( 1, 'Failed to send packet! Connection refused') elif e[0] == errno.ENETUNREACH: # TCP and UDP # network is down, but NetworkStatus didn't notice yet # (IP like 131.243.51.241) self.vprint( 1, 'Failed to send packet! Network is unreachable') else: # consider handling errno.ECONNABORTED errno.ECONNRESET self.vprint( 1, 'Failed to send packet! Socket error: ' + '{}: {}'.format(*e)) elif e == socket.timeout: # TCP self.vprint(1, 'Failed to send packet! Socket timeout') self.send_to_memory(average_data)
def main(self, datalog, cpm, cpm_err, this_start, this_end, counts): """ Determines how to handle the cpm data. """ start_text = datetime_from_epoch(this_start).strftime(strf) end_text = datetime_from_epoch(this_end).strftime(strf) self.vprint( 1, CPM_DISPLAY_TEXT.format( time=datetime_from_epoch(time.time()), counts=counts, cpm=cpm, cpm_err=cpm_err, start_time=start_text, end_time=end_text)) self.manager.data_log(datalog, cpm, cpm_err) if self.manager.test: # for testing the memory queue self.send_to_memory(None, cpm, cpm_err) elif not self.manager.config: self.no_config_send(cpm, cpm_err) elif not self.manager.publickey: self.no_publickey_send(cpm, cpm_err) else: try: self.regular_send(this_end, cpm, cpm_err) except (socket.gaierror, socket.error, socket.timeout) as e: if e == socket.gaierror: if e[0] == socket.EAI_AGAIN: # TCP and UDP # network is down, but NetworkStatus didn't notice yet # (resolving DNS like dosenet.dhcp.lbl.gov) self.vprint( 1, 'Failed to send packet! Address resolution error') else: self.vprint( 1, 'Failed to send packet! Address error: ' + '{}: {}'.format(*e)) elif e == socket.error: if e[0] == errno.ECONNREFUSED: # TCP # server is not accepting connections self.vprint( 1, 'Failed to send packet! Connection refused') elif e[0] == errno.ENETUNREACH: # TCP and UDP # network is down, but NetworkStatus didn't notice yet # (IP like 131.243.51.241) self.vprint( 1, 'Failed to send packet! Network is unreachable') else: # consider handling errno.ECONNABORTED errno.ECONNRESET self.vprint( 1, 'Failed to send packet! Socket error: ' + '{}: {}'.format(*e)) elif e == socket.timeout: # TCP self.vprint(1, 'Failed to send packet! Socket timeout') self.send_to_memory(this_end, cpm, cpm_err)