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()
Beispiel #2
0
    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()
Beispiel #3
0
    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)
Beispiel #4
0
    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()
Beispiel #5
0
    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()
Beispiel #7
0
    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
Beispiel #8
0
    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()
Beispiel #9
0
    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)
Beispiel #10
0
    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)