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))
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))
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()
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))