def initialize_input(self): self.interface = self.input_dev.interface try: self.atlas_device = setup_atlas_device(self.input_dev) if self.temperature_comp_meas_measurement_id: self.atlas_command = AtlasScientificCommand(self.input_dev, sensor=self.atlas_device) except Exception: self.logger.exception("Exception while initializing sensor") # Throw out first measurement of Atlas Scientific sensor, as it may be prone to error self.get_measurement()
def setup_atlas_rgb(): """ Step-by-step tool for calibrating the Atlas Scientific RGB sensor """ if not utils_general.user_has_permission('edit_controllers'): return redirect(url_for('routes_general.home')) form_rgb_calibrate = forms_calibration.CalibrationAtlasRGB() input_dev = Input.query.filter(Input.device == 'ATLAS_RGB').all() ui_stage = 'start' selected_input = None input_device_name = None complete_with_error = None # Begin calibration from Selected input if form_rgb_calibrate.start_calibration.data: selected_input = Input.query.filter_by( unique_id=form_rgb_calibrate.selected_input_id.data).first() dict_inputs = parse_input_information() list_inputs_sorted = generate_form_input_list(dict_inputs) if not selected_input: flash( 'Input not found: {}'.format( form_rgb_calibrate.selected_input_id.data), 'error') else: for each_input in list_inputs_sorted: if selected_input.device == each_input[0]: input_device_name = each_input[1] atlas_command = AtlasScientificCommand(selected_input) return_status, return_string = atlas_command.send_command('Cal') if return_status: complete_with_error = return_string ui_stage = 'complete' return render_template('tools/calibration_options/atlas_rgb.html', complete_with_error=complete_with_error, form_rgb_calibrate=form_rgb_calibrate, input=input_dev, input_device_name=input_device_name, selected_input=selected_input, ui_stage=ui_stage)
def initialize(self): self.interface = self.input_dev.interface try: self.atlas_device = setup_atlas_device(self.input_dev) # Enabling DO, disabling % saturation self.atlas_device.query("O,mg,1") self.atlas_device.query("O,%,0") ret_status, ret_val = self.atlas_device.query("O,?") self.logger.info("Parameters enabled: {}".format(ret_val)) if self.temperature_comp_meas_measurement_id: self.atlas_command = AtlasScientificCommand( self.input_dev, sensor=self.atlas_device) except Exception: self.logger.exception("Exception while initializing sensor") # Throw out first measurement of Atlas Scientific sensor, as it may be prone to error self.get_measurement()
def dual_commands_to_sensor(input_sel, first_cmd, amount, second_cmd, current_stage, next_stage=None): """ Handles the Atlas Scientific sensor calibration. Sends two consecutive commands to the sensor board. Denies advancement to the next stage if any commands fail. Permits advancement to the next stage if all commands succeed. """ if not utils_general.user_has_permission('edit_settings'): return redirect(url_for('routes_general.home')) return_error = None set_amount = None if first_cmd == 'temperature': unit = '°C' set_amount = amount elif first_cmd in ['ec_dry', 'ec_low', 'ec_high']: unit = 'μS' set_amount = amount else: unit = 'pH' atlas_command = AtlasScientificCommand(input_sel) sensor_measurement = atlas_command.get_sensor_measurement() first_status, first_return_str = atlas_command.calibrate( first_cmd, set_amount=set_amount) if isinstance(first_return_str, tuple): message_status = first_return_str[0] message_info = first_return_str[1] first_return_message = "{}".format(message_status) if message_info: first_return_message += ": {}".format(message_info) else: first_return_message = first_return_str first_info_str = "{act}: {lvl} ({amt} {unit}): {resp}".format( act=TRANSLATIONS['calibration']['title'], lvl=first_cmd, amt=amount, unit=unit, resp=first_return_message) if sensor_measurement != 'NA': first_info_str = "{} {}".format(sensor_measurement, first_info_str) if first_status: flash(first_info_str, "error") return_error = first_return_str return_stage = current_stage else: flash(first_info_str, "success") time.sleep(0.1) # Add space between commands second_status, second_return_str = atlas_command.calibrate(second_cmd) if isinstance(second_return_str, tuple): message_status = second_return_str[0] message_info = second_return_str[1] second_return_message = "{}".format(message_status) if message_info: second_return_message += ": {}".format(message_info) else: second_return_message = second_return_str second_info_str = "{act}: {cmd}: {resp}".format( act=gettext('Command'), cmd=second_cmd, resp=second_return_message) if sensor_measurement != 'NA': second_info_str = "{} {}".format(sensor_measurement, second_info_str) if second_status: flash(second_info_str, "error") return_error = second_return_str return_stage = current_stage else: flash(second_info_str, "success") # Advance to the next stage return_stage = next_stage return return_stage, return_error
def setup_atlas_ph(): """ Step-by-step tool for calibrating the Atlas Scientific pH sensor """ if not utils_general.user_has_permission('edit_controllers'): return redirect(url_for('routes_general.home')) form_ph_calibrate = forms_calibration.CalibrationAtlasph() input_dev = Input.query.filter(Input.device == 'ATLAS_PH').all() ui_stage = 'start' backend_stage = None next_stage = None selected_input = None selected_point_calibration = None input_device_name = None complete_with_error = None if form_ph_calibrate.hidden_current_stage.data: backend_stage = form_ph_calibrate.hidden_current_stage.data if form_ph_calibrate.hidden_selected_point_calibration.data: selected_point_calibration = form_ph_calibrate.hidden_selected_point_calibration.data elif form_ph_calibrate.point_calibration.data: selected_point_calibration = form_ph_calibrate.point_calibration.data if selected_point_calibration: list_point_calibrations = selected_point_calibration.split(',') else: list_point_calibrations = [] # Clear Calibration memory if form_ph_calibrate.clear_calibration.data: selected_input = Input.query.filter_by( unique_id=form_ph_calibrate.selected_input_id.data).first() atlas_command = AtlasScientificCommand(selected_input) status, message = atlas_command.calibrate('clear_calibration') sensor_measurement = atlas_command.get_sensor_measurement() if isinstance(message, tuple): message_status = message[0] message_info = message[1] message = "Calibration command returned from sensor: {}".format( message_status) if message_info: message += ": {}".format(message_info) else: message = "Calibration command returned from sensor: {}".format( message) if sensor_measurement != 'NA': message = "{} {}".format(sensor_measurement, message) if status: flash(message, "error") else: flash(message, "success") # Begin calibration from Selected input elif form_ph_calibrate.start_calibration.data: ui_stage = 'temperature' selected_input = Input.query.filter_by( unique_id=form_ph_calibrate.selected_input_id.data).first() dict_inputs = parse_input_information() list_inputs_sorted = generate_form_input_list(dict_inputs) if not selected_input: flash( 'Input not found: {}'.format( form_ph_calibrate.selected_input_id.data), 'error') else: for each_input in list_inputs_sorted: if selected_input.device == each_input[0]: input_device_name = each_input[1] # Continue calibration from selected input elif (form_ph_calibrate.go_to_next_stage.data or form_ph_calibrate.go_to_last_stage.data or (backend_stage is not None and backend_stage not in ['start', 'temperature'])): selected_input = Input.query.filter_by( unique_id=form_ph_calibrate.hidden_input_id.data).first() dict_inputs = parse_input_information() list_inputs_sorted = generate_form_input_list(dict_inputs) for each_input in list_inputs_sorted: if selected_input.device == each_input[0]: input_device_name = each_input[1] if backend_stage in ['temperature', 'low', 'mid', 'high']: time.sleep(2) # Sleep makes querying sensor more stable # Determine next ui_stage if backend_stage == 'temperature': next_stage = list_point_calibrations[0] logger.error("next_stage: {}".format(next_stage)) else: current_stage_index = list_point_calibrations.index(backend_stage) if current_stage_index == len(list_point_calibrations) - 1: next_stage = 'complete' else: next_stage = list_point_calibrations[current_stage_index + 1] if form_ph_calibrate.clear_calibration.data: pass elif backend_stage == 'temperature': if form_ph_calibrate.temperature.data is None: flash( gettext( "A valid temperature is required: %(temp)s is invalid.", temp=form_ph_calibrate.temperature.data), "error") ui_stage = 'start' else: temp = '{temp:.2f}'.format( temp=float(form_ph_calibrate.temperature.data)) ui_stage, complete_with_error = dual_commands_to_sensor( selected_input, 'temperature', temp, 'continuous', current_stage='temperature', next_stage=next_stage) elif backend_stage == 'low': ui_stage, complete_with_error = dual_commands_to_sensor( selected_input, 'low', '4.0', 'continuous', current_stage='low', next_stage=next_stage) elif backend_stage == 'mid': ui_stage, complete_with_error = dual_commands_to_sensor( selected_input, 'mid', '7.0', 'continuous', current_stage='mid', next_stage=next_stage) elif backend_stage == 'high': ui_stage, complete_with_error = dual_commands_to_sensor( selected_input, 'high', '10.0', 'end', current_stage='high', next_stage=next_stage) return render_template( 'tools/calibration_options/atlas_ph.html', complete_with_error=complete_with_error, form_ph_calibrate=form_ph_calibrate, input=input_dev, input_device_name=input_device_name, selected_input=selected_input, selected_point_calibration=selected_point_calibration, ui_stage=ui_stage)
class InputModule(AbstractInput): """A sensor support class that monitors the Atlas Scientific sensor ORP""" def __init__(self, input_dev, testing=False): super(InputModule, self).__init__(input_dev, testing=testing, name=__name__) self.atlas_device = None self.interface = None self.atlas_command = None self.temperature_comp_meas_device_id = None self.temperature_comp_meas_measurement_id = None self.max_age = None if not testing: self.setup_custom_options( INPUT_INFORMATION['custom_options'], input_dev) self.initialize_input() def initialize_input(self): self.interface = self.input_dev.interface try: self.atlas_device = setup_atlas_device(self.input_dev) if self.temperature_comp_meas_measurement_id: self.atlas_command = AtlasScientificCommand( self.input_dev, sensor=self.atlas_device) except Exception: self.logger.exception("Exception while initializing sensor") # Throw out first measurement of Atlas Scientific sensor, as it may be prone to error self.get_measurement() def get_measurement(self): """ Gets the sensor's ORP measurement """ if not self.atlas_device.setup: self.logger.error("Input not set up") return orp = None self.return_dict = copy.deepcopy(measurements_dict) # Compensate measurement based on a temperature measurement if self.temperature_comp_meas_measurement_id and self.atlas_command: self.logger.debug("pH sensor set to calibrate temperature") last_measurement = self.get_last_measurement( self.temperature_comp_meas_device_id, self.temperature_comp_meas_measurement_id, max_age=self.max_age) if last_measurement: self.logger.debug("Latest temperature used to calibrate: {temp}".format(temp=last_measurement[1])) ret_value, ret_msg = self.atlas_command.calibrate('temperature', set_amount=last_measurement[1]) time.sleep(0.5) self.logger.debug("Calibration returned: {val}, {msg}".format(val=ret_value, msg=ret_msg)) else: self.logger.error("Calibration measurement not found within the past {} seconds".format(self.max_age)) # Read sensor via FTDI or UART if self.interface in ['FTDI', 'UART']: orp_status, orp_list = self.atlas_device.query('R') if orp_list: self.logger.debug("Returned list: {lines}".format(lines=orp_list)) # Find float value in list float_value = None for each_split in orp_list: if str_is_float(each_split): float_value = each_split break if 'check probe' in orp_list: self.logger.error('"check probe" returned from sensor') elif str_is_float(float_value): orp = float(float_value) self.logger.debug('Found float value: {val}'.format(val=orp)) else: self.logger.error('Value or "check probe" not found in list: {val}'.format(val=orp_list)) # Read sensor via I2C elif self.interface == 'I2C': ec_status, ec_str = self.atlas_device.query('R') if ec_status == 'error': self.logger.error("Sensor read unsuccessful: {err}".format(err=ec_str)) elif ec_status == 'success': orp = float(ec_str) self.value_set(0, orp) return self.return_dict
class InputModule(AbstractInput): """A sensor support class that monitors the Atlas Scientific sensor pH""" def __init__(self, input_dev, testing=False): super(InputModule, self).__init__(input_dev, testing=testing, name=__name__) self.atlas_device = None self.interface = None self.atlas_command = None self.temperature_comp_meas_device_id = None self.temperature_comp_meas_measurement_id = None self.max_age = None if not testing: self.setup_custom_options(INPUT_INFORMATION['custom_options'], input_dev) self.initialize_input() def initialize_input(self): self.interface = self.input_dev.interface try: self.atlas_device = setup_atlas_device(self.input_dev) if self.temperature_comp_meas_measurement_id: self.atlas_command = AtlasScientificCommand( self.input_dev, sensor=self.atlas_device) except Exception: self.logger.exception("Exception while initializing sensor") # Throw out first measurement of Atlas Scientific sensor, as it may be prone to error self.get_measurement() def get_measurement(self): """ Gets the sensor's pH measurement """ if not self.atlas_device.setup: self.logger.error("Input not set up") return ph = None self.return_dict = copy.deepcopy(measurements_dict) # Compensate measurement based on a temperature measurement if self.temperature_comp_meas_measurement_id and self.atlas_command: self.logger.debug("pH sensor set to calibrate temperature") last_measurement = self.get_last_measurement( self.temperature_comp_meas_device_id, self.temperature_comp_meas_measurement_id, max_age=self.max_age) if last_measurement: self.logger.debug( "Latest temperature used to calibrate: {temp}".format( temp=last_measurement[1])) ret_value, ret_msg = self.atlas_command.calibrate( 'temperature', set_amount=last_measurement[1]) time.sleep(0.5) self.logger.debug("Calibration returned: {val}, {msg}".format( val=ret_value, msg=ret_msg)) else: self.logger.error( "Calibration measurement not found within the past {} seconds" .format(self.max_age)) # Read sensor via FTDI or UART if self.interface in ['FTDI', 'UART']: ph_status, ph_list = self.atlas_device.query('R') if ph_list: self.logger.debug( "Returned list: {lines}".format(lines=ph_list)) # Find float value in list float_value = None for each_split in ph_list: if str_is_float(each_split): float_value = each_split break if 'check probe' in ph_list: self.logger.error('"check probe" returned from sensor') elif str_is_float(float_value): ph = float(float_value) self.logger.debug('Found float value: {val}'.format(val=ph)) else: self.logger.error( 'Value or "check probe" not found in list: {val}'.format( val=ph_list)) # Read sensor via I2C elif self.interface == 'I2C': ph_status, ph_str = self.atlas_device.query('R') if ph_status == 'error': self.logger.error( "Sensor read unsuccessful: {err}".format(err=ph_str)) elif ph_status == 'success': if ',' in ph_str and str_is_float(ph_str.split(',')[2]): ph = float(ph_str.split(',')[2]) elif str_is_float(ph_str): ph = float(ph_str) else: self.logger.error( "Could not determine pH from returned string: '{}'". format(ph_str)) self.value_set(0, ph) return self.return_dict def compensation_temp_set(self, args_dict): if 'compensation_temp_c' not in args_dict: self.logger.error( "Cannot set temperature compensation without temperature") return try: write_cmd = "T,{:.2f}".format(args_dict['compensation_temp_c']) self.logger.debug("Compensation command: {}".format(write_cmd)) ret_val = self.atlas_device.write(write_cmd) self.logger.info("Command returned: {}".format(ret_val)) except: self.logger.exception("Exception compensating temperature") def calibrate(self, level, ph): try: if level == "clear": write_cmd = "Cal,clear" else: write_cmd = "Cal,{},{:.2f}".format(level, ph) self.logger.debug("Calibration command: {}".format(write_cmd)) ret_val = self.atlas_device.write(write_cmd) self.logger.info("Command returned: {}".format(ret_val)) # Verify calibration saved write_cmd = "Cal,?" self.logger.info("Device Calibrated?: {}".format( self.atlas_device.write(write_cmd))) except: self.logger.exception("Exception calibrating") def clear_calibrate(self, args_dict): self.calibrate('clear', None) def mid_calibrate(self, args_dict): if 'mid_point_ph' not in args_dict: self.logger.error( "Cannot calibrate without calibration solution pH") return self.calibrate('mid', args_dict['mid_point_ph']) def low_calibrate(self, args_dict): if 'low_point_ph' not in args_dict: self.logger.error( "Cannot calibrate without calibration solution pH") return self.calibrate('low', args_dict['low_point_ph']) def high_calibrate(self, args_dict): if 'high_point_ph' not in args_dict: self.logger.error( "Cannot calibrate without calibration solution pH") return self.calibrate('high', args_dict['high_point_ph']) def set_i2c_address(self, args_dict): if 'new_i2c_address' not in args_dict: self.logger.error( "Cannot set new I2C address without an I2C address") return try: i2c_address = int(str(args_dict['new_i2c_address']), 16) write_cmd = "I2C,{}".format(i2c_address) self.logger.debug("I2C Change command: {}".format(write_cmd)) ret_val = self.atlas_device.write(write_cmd) self.logger.info("Command returned: {}".format(ret_val)) self.atlas_device = None except: self.logger.exception("Exception changing I2C address")
class InputModule(AbstractInput): """A sensor support class that monitors the Atlas Scientific sensor ElectricalConductivity""" def __init__(self, input_dev, testing=False): super(InputModule, self).__init__(input_dev, testing=testing, name=__name__) self.atlas_device = None self.interface = None self.temperature_comp_meas_device_id = None self.temperature_comp_meas_measurement_id = None self.max_age = None if not testing: self.setup_custom_options(INPUT_INFORMATION['custom_options'], input_dev) self.initialize_input() def initialize_input(self): self.interface = self.input_dev.interface try: self.atlas_device = setup_atlas_device(self.input_dev) if self.temperature_comp_meas_measurement_id: self.atlas_command = AtlasScientificCommand( self.input_dev, sensor=self.atlas_device) self.set_sensor_settings() except Exception: self.logger.exception("Exception while initializing sensor") # Throw out first measurement of Atlas Scientific sensor, as it may be prone to error self.get_measurement() def set_sensor_settings(self): if self.is_enabled(0): self.atlas_device.query('O,EC,1') else: self.atlas_device.query('O,EC,0') if self.is_enabled(1): self.atlas_device.query('O,TDS,1') else: self.atlas_device.query('O,TDS,0') if self.is_enabled(2): self.atlas_device.query('O,S,1') else: self.atlas_device.query('O,S,0') if self.is_enabled(3): self.atlas_device.query('O,SG,1') else: self.atlas_device.query('O,SG,0') self.logger.debug("Measurements enabled: {}".format( self.atlas_device.query('O?'))) def get_measurement(self): """ Gets the sensor's Electrical Conductivity measurement """ if not self.atlas_device.setup: self.logger.error("Input not set up") return return_string = None self.return_dict = copy.deepcopy(measurements_dict) # Compensate measurement based on a temperature measurement if self.temperature_comp_meas_measurement_id and self.atlas_command: self.logger.debug("pH sensor set to calibrate temperature") device_measurement = get_measurement( self.temperature_comp_meas_measurement_id) conversion = db_retrieve_table_daemon( Conversion, unique_id=device_measurement.conversion_id) channel, unit, measurement = return_measurement_info( device_measurement, conversion) last_measurement = self.get_last_measurement( self.temperature_comp_meas_device_id, self.temperature_comp_meas_measurement_id, max_age=self.max_age) out_value = convert_from_x_to_y_unit(unit, "C", last_measurement[1]) if last_measurement: self.logger.debug( "Latest temperature used to calibrate: {temp}".format( temp=out_value)) ret_value, ret_msg = self.atlas_command.calibrate( 'temperature', set_amount=out_value) time.sleep(0.5) self.logger.debug("Calibration returned: {val}, {msg}".format( val=ret_value, msg=ret_msg)) else: self.logger.error( "Calibration measurement not found within the past " "{} seconds".format(self.max_age)) # Read sensor via FTDI or UART if self.interface in ['FTDI', 'UART']: ec_status, ec_list = self.atlas_device.query('R') if ec_list: self.logger.debug("Return list: '{}'".format(ec_list)) # Check for "check probe" for each_split in ec_list: if 'check probe' in each_split: self.logger.error('"check probe" returned from sensor') return # Find float value in list for each_split in ec_list: if "," in each_split or str_is_float(each_split): return_string = each_split break # Read sensor via I2C elif self.interface == 'I2C': ec_status, return_string = self.atlas_device.query('R') if ec_status == 'error': self.logger.error("Sensor read unsuccessful: {err}".format( err=return_string)) self.logger.debug("Return string: '{}'".format(return_string)) if ',' in return_string: # Multiple values returned index_place = 0 return_list = return_string.split(',') if (self.is_enabled(0) and len(return_list) > index_place and str_is_float(return_list[index_place])): self.value_set(0, float(return_list[index_place])) index_place += 1 if (self.is_enabled(1) and len(return_list) > index_place and str_is_float(return_list[index_place])): self.value_set(1, float(return_list[index_place])) index_place += 1 if (self.is_enabled(2) and len(return_list) > index_place and str_is_float(return_list[index_place])): self.value_set(2, float(return_list[index_place])) index_place += 1 if (self.is_enabled(3) and len(return_list) > index_place and str_is_float(return_list[index_place])): self.value_set(3, float(return_list[index_place])) elif str_is_float(return_string): # Single value returned if self.is_enabled(0): self.value_set(0, float(return_string)) elif self.is_enabled(1): self.value_set(1, float(return_string)) elif self.is_enabled(2): self.value_set(2, float(return_string)) elif self.is_enabled(3): self.value_set(3, float(return_string)) return self.return_dict def calibrate(self, level, ec): try: if level == "clear": write_cmd = "Cal,clear" elif level == "dry": write_cmd = "Cal,dry" elif level == "single": write_cmd = "Cal,{}".format(level, ec) else: write_cmd = "Cal,{},{}".format(level, ec) self.logger.debug("Calibration command: {}".format(write_cmd)) ret_val = self.atlas_device.atlas_write(write_cmd) self.logger.info("Command returned: {}".format(ret_val)) # Verify calibration saved write_cmd = "Cal,?" self.logger.info("Device Calibrated?: {}".format( self.atlas_device.atlas_write(write_cmd))) except: self.logger.exception("Exception calibrating") def clear_calibrate(self, args_dict): self.calibrate('clear', None) def dry_calibrate(self, args_dict): self.calibrate('dry', None) def single_calibrate(self, args_dict): if 'single_point_ec' not in args_dict: self.logger.error( "Cannot calibrate without calibration solution EC") return self.calibrate('single', args_dict['single_point_ec']) def low_calibrate(self, args_dict): if 'low_point_ec' not in args_dict: self.logger.error( "Cannot calibrate without calibration solution EC") return self.calibrate('low', args_dict['low_point_ec']) def high_calibrate(self, args_dict): if 'high_point_ec' not in args_dict: self.logger.error( "Cannot calibrate without calibration solution EC") return self.calibrate('high', args_dict['high_point_ec']) def set_i2c_address(self, args_dict): if 'new_i2c_address' not in args_dict: self.logger.error( "Cannot set new I2C address without an I2C address") return try: i2c_address = int(str(args_dict['new_i2c_address']), 16) write_cmd = "I2C,{}".format(i2c_address) self.logger.debug("I2C Change command: {}".format(write_cmd)) ret_val = self.atlas_device.atlas_write(write_cmd) self.logger.info("Command returned: {}".format(ret_val)) self.atlas_device = None except: self.logger.exception("Exception changing I2C address")
class InputModule(AbstractInput): """A sensor support class that monitors the Atlas Scientific sensor ElectricalConductivity""" def __init__(self, input_dev, testing=False): super(InputModule, self).__init__(input_dev, testing=testing, name=__name__) self.atlas_device = None self.interface = None self.temperature_comp_meas_device_id = None self.temperature_comp_meas_measurement_id = None self.max_age = None if not testing: self.setup_custom_options(INPUT_INFORMATION['custom_options'], input_dev) self.initialize_input() def initialize_input(self): self.interface = self.input_dev.interface try: self.atlas_device = setup_atlas_device(self.input_dev) if self.temperature_comp_meas_measurement_id: self.atlas_command = AtlasScientificCommand( self.input_dev, sensor=self.atlas_device) except Exception: self.logger.exception("Exception while initializing sensor") # Throw out first measurement of Atlas Scientific sensor, as it may be prone to error self.get_measurement() def get_measurement(self): """ Gets the sensor's Electrical Conductivity measurement """ if not self.atlas_device.setup: self.logger.error("Input not set up") return electrical_conductivity = None self.return_dict = copy.deepcopy(measurements_dict) # Compensate measurement based on a temperature measurement if self.temperature_comp_meas_measurement_id and self.atlas_command: self.logger.debug("pH sensor set to calibrate temperature") last_measurement = self.get_last_measurement( self.temperature_comp_meas_device_id, self.temperature_comp_meas_measurement_id, max_age=self.max_age) if last_measurement: self.logger.debug( "Latest temperature used to calibrate: {temp}".format( temp=last_measurement[1])) ret_value, ret_msg = self.atlas_command.calibrate( 'temperature', set_amount=last_measurement[1]) time.sleep(0.5) self.logger.debug("Calibration returned: {val}, {msg}".format( val=ret_value, msg=ret_msg)) else: self.logger.error( "Calibration measurement not found within the past " "{} seconds".format(self.max_age)) # Read sensor via FTDI or UART if self.interface in ['FTDI', 'UART']: ec_status, ec_list = self.atlas_device.query('R') if ec_list: self.logger.debug( "Returned list: {lines}".format(lines=ec_list)) # Find float value in list float_value = None for each_split in ec_list: if str_is_float(each_split): float_value = each_split break # 'check probe' indicates an error reading the sensor if 'check probe' in ec_list: self.logger.error('"check probe" returned from sensor') # if a string resembling a float value is returned, this # is our measurement value elif str_is_float(float_value): electrical_conductivity = float(float_value) self.logger.debug('Found float value: {val}'.format( val=electrical_conductivity)) else: self.logger.error( 'Value or "check probe" not found in list: {val}'. format(val=ec_list)) # Read sensor via I2C elif self.interface == 'I2C': ec_status, ec_str = self.atlas_device.query('R') if ec_status == 'error': self.logger.error( "Sensor read unsuccessful: {err}".format(err=ec_str)) elif ec_status == 'success': electrical_conductivity = float(ec_str) self.value_set(0, electrical_conductivity) return self.return_dict def set_i2c_address(self, args_dict): if 'new_i2c_address' not in args_dict: self.logger.error( "Cannot set new I2C address without an I2C address") return try: i2c_address = int(str(args_dict['new_i2c_address']), 16) write_cmd = "I2C,{}".format(i2c_address) self.logger.debug("I2C Change command: {}".format(write_cmd)) self.atlas_device.write(write_cmd) except: self.logger.exception("Exception changing I2C address")
class InputModule(AbstractInput): """A sensor support class that monitors the Atlas Scientific sensor ORP.""" def __init__(self, input_dev, testing=False): super().__init__(input_dev, testing=testing, name=__name__) self.atlas_device = None self.interface = None self.atlas_command = None self.temperature_comp_meas_device_id = None self.temperature_comp_meas_measurement_id = None self.max_age = None if not testing: self.setup_custom_options(INPUT_INFORMATION['custom_options'], input_dev) self.try_initialize() def initialize(self): self.interface = self.input_dev.interface try: self.atlas_device = setup_atlas_device(self.input_dev) if self.temperature_comp_meas_measurement_id: self.atlas_command = AtlasScientificCommand( self.input_dev, sensor=self.atlas_device) except Exception: self.logger.exception("Exception while initializing sensor") # Throw out first measurement of Atlas Scientific sensor, as it may be prone to error self.get_measurement() def get_measurement(self): """Gets the sensor's ORP measurement.""" if not self.atlas_device.setup: self.logger.error( "Error 101: Device not set up. See https://kizniche.github.io/Mycodo/Error-Codes#error-101 for more info." ) return orp = None self.return_dict = copy.deepcopy(measurements_dict) # Compensate measurement based on a temperature measurement if self.temperature_comp_meas_measurement_id and self.atlas_command: self.logger.debug("pH sensor set to calibrate temperature") last_measurement = self.get_last_measurement( self.temperature_comp_meas_device_id, self.temperature_comp_meas_measurement_id, max_age=self.max_age) if last_measurement and len(last_measurement) > 1: device_measurement = get_measurement( self.temperature_comp_meas_measurement_id) conversion = db_retrieve_table_daemon( Conversion, unique_id=device_measurement.conversion_id) _, unit, _ = return_measurement_info(device_measurement, conversion) if unit != "C": out_value = convert_from_x_to_y_unit( unit, "C", last_measurement[1]) else: out_value = last_measurement[1] self.logger.debug( "Latest temperature used to calibrate: {temp}".format( temp=out_value)) ret_value, ret_msg = self.atlas_command.calibrate( 'temperature', set_amount=out_value) time.sleep(0.5) self.logger.debug("Calibration returned: {val}, {msg}".format( val=ret_value, msg=ret_msg)) else: self.logger.error( "Calibration measurement not found within the past {} seconds" .format(self.max_age)) # Read device atlas_status, atlas_return = self.atlas_device.query('R') self.logger.debug("Device Returned: {}: {}".format( atlas_status, atlas_return)) if atlas_status == 'error': self.logger.error( "Sensor read unsuccessful: {err}".format(err=atlas_return)) return # Parse device return data if self.interface in ['FTDI', 'UART']: # Find float value in list float_value = None for each_split in atlas_return: if str_is_float(each_split): float_value = each_split break if 'check probe' in atlas_return: self.logger.error('"check probe" returned from sensor') elif str_is_float(float_value): orp = float(float_value) self.logger.debug('Found float value: {val}'.format(val=orp)) else: self.logger.error( 'Value or "check probe" not found in list: {val}'.format( val=atlas_return)) elif self.interface == 'I2C': orp = float(atlas_return) self.value_set(0, orp) return self.return_dict def calibrate(self, write_cmd): try: self.logger.info("Command: {}".format(write_cmd)) self.logger.info("Command returned: {}".format( self.atlas_device.query(write_cmd))) self.logger.info("Device Calibrated?: {}".format( self.atlas_device.query("Cal,?"))) except: self.logger.exception("Exception calibrating") def calibrate_mv(self, args_dict): if 'solution_mV' not in args_dict: self.logger.error("Cannot calibrate without Solution mV") return self.calibrate("Cal,{}".format(args_dict['solution_mV'])) def calibrate_clear(self, args_dict): self.calibrate("Cal,clear") def set_i2c_address(self, args_dict): if 'new_i2c_address' not in args_dict: self.logger.error( "Cannot set new I2C address without an I2C address") return try: i2c_address = int(str(args_dict['new_i2c_address']), 16) write_cmd = "I2C,{}".format(i2c_address) self.logger.info("I2C Change command: {}".format(write_cmd)) self.logger.info("Command returned: {}".format( self.atlas_device.query(write_cmd))) self.atlas_device = None except: self.logger.exception("Exception changing I2C address")
class InputModule(AbstractInput): """A sensor support class that monitors the Atlas Scientific sensor ORP""" def __init__(self, input_dev, testing=False): super(InputModule, self).__init__(input_dev, testing=testing, name=__name__) self.atlas_device = None self.interface = None self.atlas_command = None self.temperature_comp_meas_device_id = None self.temperature_comp_meas_measurement_id = None self.max_age = None if not testing: self.setup_custom_options(INPUT_INFORMATION['custom_options'], input_dev) self.initialize_input() def initialize_input(self): self.interface = self.input_dev.interface try: self.atlas_device = setup_atlas_device(self.input_dev) if self.temperature_comp_meas_measurement_id: self.atlas_command = AtlasScientificCommand( self.input_dev, sensor=self.atlas_device) except Exception: self.logger.exception("Exception while initializing sensor") # Throw out first measurement of Atlas Scientific sensor, as it may be prone to error self.get_measurement() def get_measurement(self): """ Gets the sensor's ORP measurement """ if not self.atlas_device.setup: self.logger.error("Input not set up") return orp = None self.return_dict = copy.deepcopy(measurements_dict) # Compensate measurement based on a temperature measurement if self.temperature_comp_meas_measurement_id and self.atlas_command: self.logger.debug("pH sensor set to calibrate temperature") device_measurement = get_measurement( self.temperature_comp_meas_measurement_id) conversion = db_retrieve_table_daemon( Conversion, unique_id=device_measurement.conversion_id) channel, unit, measurement = return_measurement_info( device_measurement, conversion) last_measurement = self.get_last_measurement( self.temperature_comp_meas_device_id, self.temperature_comp_meas_measurement_id, max_age=self.max_age) out_value = convert_from_x_to_y_unit(unit, "C", last_measurement[1]) if last_measurement: self.logger.debug( "Latest temperature used to calibrate: {temp}".format( temp=out_value)) ret_value, ret_msg = self.atlas_command.calibrate( 'temperature', set_amount=out_value) time.sleep(0.5) self.logger.debug("Calibration returned: {val}, {msg}".format( val=ret_value, msg=ret_msg)) else: self.logger.error( "Calibration measurement not found within the past {} seconds" .format(self.max_age)) # Read sensor via FTDI or UART if self.interface in ['FTDI', 'UART']: orp_status, orp_list = self.atlas_device.query('R') if orp_list: self.logger.debug( "Returned list: {lines}".format(lines=orp_list)) # Find float value in list float_value = None for each_split in orp_list: if str_is_float(each_split): float_value = each_split break if 'check probe' in orp_list: self.logger.error('"check probe" returned from sensor') elif str_is_float(float_value): orp = float(float_value) self.logger.debug('Found float value: {val}'.format(val=orp)) else: self.logger.error( 'Value or "check probe" not found in list: {val}'.format( val=orp_list)) # Read sensor via I2C elif self.interface == 'I2C': ec_status, ec_str = self.atlas_device.query('R') if ec_status == 'error': self.logger.error( "Sensor read unsuccessful: {err}".format(err=ec_str)) elif ec_status == 'success': orp = float(ec_str) self.value_set(0, orp) return self.return_dict def calibrate(self, args_dict): if 'solution_mV' not in args_dict: self.logger.error("Cannot calibrate without Solution mV") return try: write_cmd = "Cal,{}".format(args_dict['solution_mV']) self.logger.debug("Command to send: {}".format(write_cmd)) ret_val = self.atlas_device.atlas_write(write_cmd) self.logger.info("Command returned: {}".format(ret_val)) # Verify calibration saved write_cmd = "Cal,?" self.logger.info("Device Calibrated?: {}".format( self.atlas_device.atlas_write(write_cmd))) except: self.logger.exception("Exception calibrating sensor") def calibrate_clear(self, args_dict): try: write_cmd = "Cal,clear" self.logger.debug("Calibration command: {}".format(write_cmd)) ret_val = self.atlas_device.atlas_write(write_cmd) self.logger.info("Command returned: {}".format(ret_val)) except: self.logger.exception("Exception clearing calibration") def set_i2c_address(self, args_dict): if 'new_i2c_address' not in args_dict: self.logger.error( "Cannot set new I2C address without an I2C address") return try: i2c_address = int(str(args_dict['new_i2c_address']), 16) write_cmd = "I2C,{}".format(i2c_address) self.logger.debug("I2C Change command: {}".format(write_cmd)) ret_val = self.atlas_device.atlas_write(write_cmd) self.logger.info("Command returned: {}".format(ret_val)) except: self.logger.exception("Exception changing I2C address")
class InputModule(AbstractInput): """A sensor support class that monitors the Atlas Scientific sensor pH.""" def __init__(self, input_dev, testing=False): super().__init__(input_dev, testing=testing, name=__name__) self.atlas_device = None self.interface = None self.atlas_command = None self.temperature_comp_meas_device_id = None self.temperature_comp_meas_measurement_id = None self.max_age = None if not testing: self.setup_custom_options(INPUT_INFORMATION['custom_options'], input_dev) self.try_initialize() def initialize(self): self.interface = self.input_dev.interface try: self.atlas_device = setup_atlas_device(self.input_dev) self.logger.debug("Lockfile: {}".format( self.atlas_device.lock_file)) if self.temperature_comp_meas_measurement_id: self.atlas_command = AtlasScientificCommand( self.input_dev, sensor=self.atlas_device) except Exception: self.logger.exception("Exception while initializing sensor") # Throw out first measurement of Atlas Scientific sensor, as it may be prone to error self.get_measurement() def get_measurement(self): """Gets the sensor's pH measurement.""" if not self.atlas_device.setup: self.logger.error( "Error 101: Device not set up. See https://kizniche.github.io/Mycodo/Error-Codes#error-101 for more info." ) return ph = None self.return_dict = copy.deepcopy(measurements_dict) # Compensate measurement based on a temperature measurement if self.temperature_comp_meas_measurement_id and self.atlas_command: self.logger.debug("pH sensor set to calibrate temperature") last_measurement = self.get_last_measurement( self.temperature_comp_meas_device_id, self.temperature_comp_meas_measurement_id, max_age=self.max_age) if last_measurement and len(last_measurement) > 1: device_measurement = get_measurement( self.temperature_comp_meas_measurement_id) conversion = db_retrieve_table_daemon( Conversion, unique_id=device_measurement.conversion_id) _, unit, _ = return_measurement_info(device_measurement, conversion) if unit != "C": out_value = convert_from_x_to_y_unit( unit, "C", last_measurement[1]) else: out_value = last_measurement[1] self.logger.debug( "Latest temperature used to calibrate: {temp}".format( temp=out_value)) ret_value, ret_msg = self.atlas_command.calibrate( 'temperature', set_amount=out_value) time.sleep(0.5) self.logger.debug("Calibration returned: {val}, {msg}".format( val=ret_value, msg=ret_msg)) else: self.logger.error( "Calibration measurement not found within the past {} seconds" .format(self.max_age)) # Read device atlas_status, atlas_return = self.atlas_device.query('R') self.logger.debug("Device Returned: {}: {}".format( atlas_status, atlas_return)) if atlas_status == 'error': self.logger.error( "Sensor read unsuccessful: {err}".format(err=atlas_return)) return # Parse device return data if self.interface in ['FTDI', 'UART']: # Find float value in list float_value = None for each_split in atlas_return: if str_is_float(each_split): float_value = each_split break if 'check probe' in atlas_return: self.logger.error('"check probe" returned from sensor') elif str_is_float(float_value): ph = float(float_value) self.logger.debug('Found float value: {val}'.format(val=ph)) else: self.logger.error( 'Value or "check probe" not found in list: {val}'.format( val=atlas_return)) elif self.interface == 'I2C': if ',' in atlas_return and str_is_float( atlas_return.split(',')[2]): ph = float(atlas_return.split(',')[2]) elif str_is_float(atlas_return): ph = float(atlas_return) else: self.logger.error( "Could not determine pH from returned value: '{}'".format( atlas_return)) self.value_set(0, ph) return self.return_dict def compensation_temp_set(self, args_dict): if 'compensation_temp_c' not in args_dict: self.logger.error( "Cannot set temperature compensation without temperature") return try: write_cmd = "T,{:.2f}".format(args_dict['compensation_temp_c']) self.logger.info("Command: {}".format(write_cmd)) self.logger.info("Command returned: {}".format( self.atlas_device.query(write_cmd))) except: self.logger.exception("Exception compensating temperature") def calibrate(self, level, ph): try: if level == "clear": write_cmd = "Cal,clear" else: write_cmd = "Cal,{},{:.2f}".format(level, ph) self.logger.info("Calibration command: {}".format(write_cmd)) self.logger.info("Command returned: {}".format( self.atlas_device.query(write_cmd))) self.logger.info("Calibrated: {}".format( self.atlas_device.query("Cal,?"))) self.logger.info("Slope: {}".format( self.atlas_device.query("Slope,?"))) time.sleep(2) except: self.logger.exception("Exception calibrating") def clear_calibrate(self, args_dict): self.calibrate('clear', None) def mid_calibrate(self, args_dict): if 'mid_point_ph' not in args_dict: self.logger.error( "Cannot calibrate without calibration solution pH") return self.calibrate('mid', args_dict['mid_point_ph']) def low_calibrate(self, args_dict): if 'low_point_ph' not in args_dict: self.logger.error( "Cannot calibrate without calibration solution pH") return self.calibrate('low', args_dict['low_point_ph']) def high_calibrate(self, args_dict): if 'high_point_ph' not in args_dict: self.logger.error( "Cannot calibrate without calibration solution pH") return self.calibrate('high', args_dict['high_point_ph']) def calibration_export(self, args_dict): try: atlas_status, atlas_return = self.atlas_device.query("Export,?") self.logger.info("Command returned: {}".format(atlas_return)) if atlas_return and ',' in atlas_return: list_return = atlas_return.split(',') length = None bytes = None for each_item in list_return: if is_int(each_item): if length is None: length = int(each_item) elif bytes is None: bytes = int(each_item) break list_export = [] for _ in range(length): atlas_status, atlas_return = self.atlas_device.query( "Export") if atlas_return: list_export.append(atlas_return) atlas_status, atlas_return = self.atlas_device.query("Export") if atlas_return != "*DONE": self.logger.error( "Did not receive *DONE response indicating export ended" ) self.logger.info("pH Calibration export string: {}".format( ",".join(list_export))) atlas_status, atlas_return = self.atlas_device.query("Slope,?") if atlas_status == "success": self.logger.info("Slope: {}".format(atlas_return)) except: self.logger.exception("Exception exporting calibrating") def calibration_import(self, args_dict): if 'calibration_import_str' not in args_dict: self.logger.error( "Cannot import calibration without calibration string") return try: if "," in args_dict['calibration_import_str']: list_strings = args_dict['calibration_import_str'].split(',') self.logger.info("Importing calibration string...") for each_str in list_strings: try: self.atlas_device.query("Import,{}".format(each_str)) except: pass time.sleep(1) self.logger.info( "Calibration imported. There bay be a Remote I/O Error, but this doesn't mean the calibration import failed. Verify it was successful by exporting it. Getting calibration slope..." ) atlas_status, atlas_return = self.atlas_device.query("Slope,?") if atlas_status == "success": self.logger.info( "pH Calibration Slope: {}".format(atlas_return)) else: self.logger.error( 'Calibration string does not contain a comma (",")') time.sleep(2) except: self.logger.exception("Exception importing calibrating") def set_i2c_address(self, args_dict): if 'new_i2c_address' not in args_dict: self.logger.error( "Cannot set new I2C address without an I2C address") return try: i2c_address = int(str(args_dict['new_i2c_address']), 16) write_cmd = "I2C,{}".format(i2c_address) self.logger.info("I2C Change command: {}".format(write_cmd)) self.logger.info("Command returned: {}".format( self.atlas_device.query(write_cmd))) self.atlas_device = None except: self.logger.exception("Exception changing I2C address")