예제 #1
0
    def run(self):
        try:
            self.running = True
            self.logger.info("Activated in {:.1f} ms".format(
                (timeit.default_timer() - self.thread_startup_timer) * 1000))
            self.ready.set()

            # Set up edge detection
            if self.device == 'EDGE':
                GPIO.setmode(GPIO.BCM)
                GPIO.setup(int(self.location), GPIO.IN)
                GPIO.add_event_detect(int(self.location),
                                      self.switch_edge_gpio,
                                      callback=self.edge_detected,
                                      bouncetime=self.switch_bouncetime)

            while self.running:
                # Pause loop to modify conditional statements.
                # Prevents execution of conditional while variables are
                # being modified.
                if self.pause_loop:
                    self.verify_pause_loop = True
                    while self.pause_loop:
                        time.sleep(0.1)

                if self.device not in ['EDGE']:
                    now = time.time()
                    # Signal that a measurement needs to be obtained
                    if now > self.next_measurement and not self.get_new_measurement:
                        self.get_new_measurement = True
                        self.trigger_cond = True
                        while self.next_measurement < now:
                            self.next_measurement += self.period

                    # if signaled and a pre output is set up correctly, turn the
                    # output on or on for the set duration
                    if (self.get_new_measurement and
                            self.pre_output_setup and
                            not self.pre_output_activated):

                        # Set up lock
                        self.input_lock = locket.lock_file(self.lock_file, timeout=120)
                        try:
                            self.input_lock.acquire()
                            self.pre_output_locked = True
                        except locket.LockError:
                            self.logger.error("Could not acquire input lock. Breaking for future locking.")
                            try:
                                os.remove(self.lock_file)
                            except OSError:
                                self.logger.error("Can't delete lock file: Lock file doesn't exist.")

                        self.pre_output_timer = time.time() + self.pre_output_duration
                        self.pre_output_activated = True

                        # Only run the pre-output before measurement
                        # Turn on for a duration, measure after it turns off
                        if not self.pre_output_during_measure:
                            output_on = threading.Thread(
                                target=self.control.output_on,
                                args=(self.pre_output_id,
                                      self.pre_output_duration,))
                            output_on.start()

                        # Run the pre-output during the measurement
                        # Just turn on, then off after the measurement
                        else:
                            output_on = threading.Thread(
                                target=self.control.output_on,
                                args=(self.pre_output_id,))
                            output_on.start()

                    # If using a pre output, wait for it to complete before
                    # querying the input for a measurement
                    if self.get_new_measurement:

                        if (self.pre_output_setup and
                                self.pre_output_activated and
                                now > self.pre_output_timer):

                            if self.pre_output_during_measure:
                                # Measure then turn off pre-output
                                self.update_measure()
                                output_off = threading.Thread(
                                    target=self.control.output_off,
                                    args=(self.pre_output_id,))
                                output_off.start()
                            else:
                                # Pre-output has turned off, now measure
                                self.update_measure()

                            self.pre_output_activated = False
                            self.get_new_measurement = False

                            # release pre-output lock
                            try:
                                if self.pre_output_locked:
                                    self.input_lock.release()
                                    self.pre_output_locked = False
                            except AttributeError:
                                self.logger.error("Can't release lock: "
                                                  "Lock file not present.")

                        elif not self.pre_output_setup:
                            # Pre-output not enabled, just measure
                            self.update_measure()
                            self.get_new_measurement = False

                        # Add measurement(s) to influxdb
                        if self.measurement_success:
                            add_measure_influxdb(self.unique_id, self.measurement)
                            self.measurement_success = False

                self.trigger_cond = False

                time.sleep(self.sample_rate)

            self.running = False

            if self.device == 'EDGE':
                GPIO.setmode(GPIO.BCM)
                GPIO.cleanup(int(self.location))

            self.logger.info("Deactivated in {:.1f} ms".format(
                (timeit.default_timer() - self.thread_shutdown_timer) * 1000))
        except requests.ConnectionError:
            self.logger.error("Could not connect to influxdb. Check that it "
                              "is running and accepting connections")
        except Exception as except_msg:
            self.logger.exception("Error: {err}".format(
                err=except_msg))
예제 #2
0
    def run(self):
        try:
            self.running = True
            self.logger.info("Activated in {:.1f} ms".format(
                (timeit.default_timer() - self.thread_startup_timer) * 1000))
            self.ready.set()

            # Set up edge detection
            if self.device == 'EDGE':
                GPIO.setmode(GPIO.BCM)
                GPIO.setup(int(self.location), GPIO.IN)
                GPIO.add_event_detect(int(self.location),
                                      self.switch_edge_gpio,
                                      callback=self.edge_detected,
                                      bouncetime=self.switch_bouncetime)

            while self.running:
                # Pause loop to modify conditional statements.
                # Prevents execution of conditional while variables are
                # being modified.
                if self.pause_loop:
                    self.verify_pause_loop = True
                    while self.pause_loop:
                        time.sleep(0.1)

                if self.device not in ['EDGE']:
                    now = time.time()
                    # Signal that a measurement needs to be obtained
                    if now > self.next_measurement and not self.get_new_measurement:
                        self.get_new_measurement = True
                        self.trigger_cond = True
                        while self.next_measurement < now:
                            self.next_measurement += self.period

                    # if signaled and a pre output is set up correctly, turn the
                    # output on for the set duration
                    if (self.get_new_measurement and self.pre_output_setup
                            and not self.pre_output_activated):
                        self.pre_output_timer = now + self.pre_output_duration
                        self.pre_output_activated = True

                        output_on = threading.Thread(
                            target=self.control.relay_on,
                            args=(
                                self.pre_output_id,
                                self.pre_output_duration,
                            ))
                        output_on.start()

                    # If using a pre output, wait for it to complete before
                    # querying the input for a measurement
                    if self.get_new_measurement:
                        if ((self.pre_output_setup
                             and self.pre_output_activated
                             and now < self.pre_output_timer)
                                or not self.pre_output_setup):
                            # Get measurement(s) from input
                            self.update_measure()
                            # Add measurement(s) to influxdb
                            if self.updateSuccess:
                                add_measure_influxdb(self.unique_id,
                                                     self.measurement)
                            self.pre_output_activated = False
                            self.get_new_measurement = False

                self.trigger_cond = False

                time.sleep(0.1)

            self.running = False

            if self.device == 'EDGE':
                GPIO.setmode(GPIO.BCM)
                GPIO.cleanup(int(self.location))

            self.logger.info("Deactivated in {:.1f} ms".format(
                (timeit.default_timer() - self.thread_shutdown_timer) * 1000))
        except requests.ConnectionError:
            self.logger.error("Could not connect to influxdb. Check that it "
                              "is running and accepting connections")
        except Exception as except_msg:
            self.logger.exception("Error: {err}".format(err=except_msg))
예제 #3
0
    def calculate_math(self):
        if self.math_type == 'average':
            success, measure = self.get_measurements_from_str(self.inputs)
            if success:
                measure_dict = {
                    self.measure:
                    float('{0:.4f}'.format(sum(measure) / float(len(measure))))
                }
                self.measurements = Measurement(measure_dict)
                add_measure_influxdb(self.unique_id, self.measurements)
            elif measure:
                self.logger.error(measure)
            else:
                self.error_not_within_max_age()

        elif self.math_type == 'average_single':
            device_id = self.inputs.split(',')[0]
            measurement = self.inputs.split(',')[1]
            try:
                last_measurements = read_past_influxdb(device_id, measurement,
                                                       self.max_measure_age)

                if last_measurements:
                    measure_list = []
                    for each_set in last_measurements:
                        if len(each_set) == 2:
                            measure_list.append(each_set[1])
                    average = sum(measure_list) / float(len(measure_list))

                    measure_dict = {
                        self.measure: float('{0:.4f}'.format(average))
                    }
                    self.measurements = Measurement(measure_dict)
                    add_measure_influxdb(self.unique_id, self.measurements)
                else:
                    self.error_not_within_max_age()
            except Exception as msg:
                self.logger.error(
                    "average_single Error: {err}".format(err=msg))

        elif self.math_type == 'difference':
            success, measure = self.get_measurements_from_str(self.inputs)
            if success:
                if self.difference_reverse_order:
                    difference = measure[1] - measure[0]
                else:
                    difference = measure[0] - measure[1]
                if self.difference_absolute:
                    difference = abs(difference)
                measure_dict = {
                    self.measure: float('{0:.4f}'.format(difference))
                }
                self.measurements = Measurement(measure_dict)
                add_measure_influxdb(self.unique_id, self.measurements)
            elif measure:
                self.logger.error(measure)
            else:
                self.error_not_within_max_age()

        elif self.math_type == 'equation':
            success, measure = self.get_measurements_from_str(
                self.equation_input)
            if success:
                replaced_str = self.equation.replace('x', str(measure[0]))
                equation_output = eval(replaced_str)
                measure_dict = {
                    self.measure: float('{0:.4f}'.format(equation_output))
                }
                self.measurements = Measurement(measure_dict)
                add_measure_influxdb(self.unique_id, self.measurements)
            elif measure:
                self.logger.error(measure)
            else:
                self.error_not_within_max_age()

        elif self.math_type == 'median':
            success, measure = self.get_measurements_from_str(self.inputs)
            if success:
                measure_dict = {
                    self.measure: float('{0:.4f}'.format(median(measure)))
                }
                self.measurements = Measurement(measure_dict)
                add_measure_influxdb(self.unique_id, self.measurements)
            elif measure:
                self.logger.error(measure)
            else:
                self.error_not_within_max_age()

        elif self.math_type == 'maximum':
            success, measure = self.get_measurements_from_str(self.inputs)
            if success:
                measure_dict = {
                    self.measure: float('{0:.4f}'.format(max(measure)))
                }
                self.measurements = Measurement(measure_dict)
                add_measure_influxdb(self.unique_id, self.measurements)
            elif measure:
                self.logger.error(measure)
            else:
                self.error_not_within_max_age()

        elif self.math_type == 'minimum':
            success, measure = self.get_measurements_from_str(self.inputs)
            if success:
                measure_dict = {
                    self.measure: float('{0:.4f}'.format(min(measure)))
                }
                self.measurements = Measurement(measure_dict)
                add_measure_influxdb(self.unique_id, self.measurements)
            elif measure:
                self.logger.error(measure)
            else:
                self.error_not_within_max_age()

        elif self.math_type == 'verification':
            success, measure = self.get_measurements_from_str(self.inputs)
            if (success and max(measure) - min(measure) < self.max_difference):
                measure_dict = {
                    self.measure:
                    float('{0:.4f}'.format(sum(measure) / float(len(measure))))
                }
                self.measurements = Measurement(measure_dict)
                add_measure_influxdb(self.unique_id, self.measurements)
            elif measure:
                self.logger.error(measure)
            else:
                self.error_not_within_max_age()

        elif self.math_type == 'humidity':
            measure_temps_good = False
            pressure_pa = 101325

            success_dbt, dry_bulb_t = self.get_measurements_from_id(
                self.dry_bulb_t_id, self.dry_bulb_t_measure)
            success_wbt, wet_bulb_t = self.get_measurements_from_id(
                self.wet_bulb_t_id, self.wet_bulb_t_measure)
            if success_dbt and success_wbt:
                measure_temps_good = True

            if self.pressure_pa_id and self.pressure_pa_measure:
                success_pa, pressure = self.get_measurements_from_id(
                    self.pressure_pa_id, self.pressure_pa_measure)
                if success_pa:
                    pressure_pa = int(pressure[1])

            if measure_temps_good:
                dbt_kelvin = celsius_to_kelvin(float(dry_bulb_t[1]))
                wbt_kelvin = celsius_to_kelvin(float(wet_bulb_t[1]))
                psypi = None

                try:
                    psypi = SI.state("DBT", dbt_kelvin, "WBT", wbt_kelvin,
                                     pressure_pa)
                except TypeError as err:
                    self.logger.error("TypeError: {msg}".format(msg=err))

                if psypi:
                    percent_relative_humidity = psypi[2] * 100

                    # Ensure percent humidity stays within 0 - 100 % range
                    if percent_relative_humidity > 100:
                        percent_relative_humidity = 100
                    elif percent_relative_humidity < 0:
                        percent_relative_humidity = 0

                    # Dry bulb temperature: psypi[0])
                    # Wet bulb temperature: psypi[5])

                    measure_dict = dict(
                        specific_enthalpy=float('{0:.5f}'.format(psypi[1])),
                        humidity=float(
                            '{0:.5f}'.format(percent_relative_humidity)),
                        specific_volume=float('{0:.5f}'.format(psypi[3])),
                        humidity_ratio=float('{0:.5f}'.format(psypi[4])))
                    self.measurements = Measurement(measure_dict)
                    add_measure_influxdb(self.unique_id, self.measurements)
            else:
                self.error_not_within_max_age()
예제 #4
0
    def run(self):
        try:
            self.running = True
            self.logger.info("Activated in {:.1f} ms".format(
                (timeit.default_timer() - self.thread_startup_timer) * 1000))
            self.ready.set()

            while self.running:
                # Pause loop to modify conditional statements.
                # Prevents execution of conditional while variables are
                # being modified.
                if self.pause_loop:
                    self.verify_pause_loop = True
                    while self.pause_loop:
                        time.sleep(0.1)

                if self.is_activated and time.time() > self.timer:

                    # If PID is active, retrieve input measurement and update PID output
                    if self.math_type == 'average':
                        success, measure = self.get_measurements_from_str(
                            self.inputs)
                        if success:
                            measure_dict = {
                                self.measure:
                                float('{0:.4f}'.format(
                                    sum(measure) / float(len(measure))))
                            }
                            self.measurements = Measurement(measure_dict)
                            add_measure_influxdb(self.unique_id,
                                                 self.measurements)
                        elif measure:
                            self.logger.error(measure)
                        else:
                            self.error_not_within_max_age()

                    elif self.math_type == 'difference':
                        success, measure = self.get_measurements_from_str(
                            self.inputs)
                        if success:
                            if self.difference_reverse_order:
                                difference = measure[1] - measure[0]
                            else:
                                difference = measure[0] - measure[1]
                            if self.difference_absolute:
                                difference = abs(difference)
                            measure_dict = {
                                self.measure:
                                float('{0:.4f}'.format(difference))
                            }
                            self.measurements = Measurement(measure_dict)
                            add_measure_influxdb(self.unique_id,
                                                 self.measurements)
                        elif measure:
                            self.logger.error(measure)
                        else:
                            self.error_not_within_max_age()

                    elif self.math_type == 'equation':
                        success, measure = self.get_measurements_from_str(
                            self.equation_input)
                        if success:
                            replaced_str = self.equation.replace(
                                'x', str(measure[0]))
                            equation_output = eval(replaced_str)
                            measure_dict = {
                                self.measure:
                                float('{0:.4f}'.format(equation_output))
                            }
                            self.measurements = Measurement(measure_dict)
                            add_measure_influxdb(self.unique_id,
                                                 self.measurements)
                        elif measure:
                            self.logger.error(measure)
                        else:
                            self.error_not_within_max_age()

                    elif self.math_type == 'median':
                        success, measure = self.get_measurements_from_str(
                            self.inputs)
                        if success:
                            measure_dict = {
                                self.measure:
                                float('{0:.4f}'.format(median(measure)))
                            }
                            self.measurements = Measurement(measure_dict)
                            add_measure_influxdb(self.unique_id,
                                                 self.measurements)
                        elif measure:
                            self.logger.error(measure)
                        else:
                            self.error_not_within_max_age()

                    elif self.math_type == 'maximum':
                        success, measure = self.get_measurements_from_str(
                            self.inputs)
                        if success:
                            measure_dict = {
                                self.measure:
                                float('{0:.4f}'.format(max(measure)))
                            }
                            self.measurements = Measurement(measure_dict)
                            add_measure_influxdb(self.unique_id,
                                                 self.measurements)
                        elif measure:
                            self.logger.error(measure)
                        else:
                            self.error_not_within_max_age()

                    elif self.math_type == 'minimum':
                        success, measure = self.get_measurements_from_str(
                            self.inputs)
                        if success:
                            measure_dict = {
                                self.measure:
                                float('{0:.4f}'.format(min(measure)))
                            }
                            self.measurements = Measurement(measure_dict)
                            add_measure_influxdb(self.unique_id,
                                                 self.measurements)
                        elif measure:
                            self.logger.error(measure)
                        else:
                            self.error_not_within_max_age()

                    elif self.math_type == 'verification':
                        success, measure = self.get_measurements_from_str(
                            self.inputs)
                        if (success and max(measure) - min(measure) <
                                self.max_difference):
                            measure_dict = {
                                self.measure:
                                float('{0:.4f}'.format(
                                    sum(measure) / float(len(measure))))
                            }
                            self.measurements = Measurement(measure_dict)
                            add_measure_influxdb(self.unique_id,
                                                 self.measurements)
                        elif measure:
                            self.logger.error(measure)
                        else:
                            self.error_not_within_max_age()

                    elif self.math_type == 'humidity':
                        measure_temps_good = False
                        measure_press_good = False
                        pressure_pa = 101325

                        success_dbt, dry_bulb_t = self.get_measurements_from_id(
                            self.dry_bulb_t_id, self.dry_bulb_t_measure)
                        success_wbt, wet_bulb_t = self.get_measurements_from_id(
                            self.wet_bulb_t_id, self.wet_bulb_t_measure)
                        if success_dbt and success_wbt:
                            measure_temps_good = True

                        if self.pressure_pa_id and self.pressure_pa_measure:
                            success_pa, pressure = self.get_measurements_from_id(
                                self.pressure_pa_id, self.pressure_pa_measure)
                            if success_pa:
                                pressure_pa = int(pressure[1])
                                measure_press_good = True

                        if (measure_temps_good and
                            ((self.pressure_pa_id and self.pressure_pa_measure
                              and measure_press_good) or
                             (not self.pressure_pa_id
                              or not self.pressure_pa_measure))):

                            dbt_kelvin = celsius_to_kelvin(float(
                                dry_bulb_t[1]))
                            wbt_kelvin = celsius_to_kelvin(float(
                                wet_bulb_t[1]))

                            psypi = SI.state("DBT", dbt_kelvin, "WBT",
                                             wbt_kelvin, pressure_pa)

                            percent_relative_humidity = psypi[2] * 100

                            # Ensure percent humidity stays within 0 - 100 % range
                            if percent_relative_humidity > 100:
                                percent_relative_humidity = 100
                            elif percent_relative_humidity < 0:
                                percent_relative_humidity = 0

                            # Dry bulb temperature: psypi[0])
                            # Wet bulb temperature: psypi[5])

                            measure_dict = dict(
                                specific_enthalpy=float('{0:.5f}'.format(
                                    psypi[1])),
                                humidity=float('{0:.5f}'.format(
                                    percent_relative_humidity)),
                                specific_volume=float('{0:.5f}'.format(
                                    psypi[3])),
                                humidity_ratio=float('{0:.5f}'.format(
                                    psypi[4])))
                            self.measurements = Measurement(measure_dict)
                            add_measure_influxdb(self.unique_id,
                                                 self.measurements)
                        else:
                            self.error_not_within_max_age()

                    # Ensure the next timer ends in the future
                    while time.time() > self.timer:
                        self.timer += self.period

                time.sleep(0.1)

            self.running = False
            self.logger.info("Deactivated in {:.1f} ms".format(
                (timeit.default_timer() - self.thread_shutdown_timer) * 1000))
        except Exception as except_msg:
            self.logger.exception("Run Error: {err}".format(err=except_msg))