Esempio n. 1
0
    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()
Esempio n. 2
0
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)
Esempio n. 3
0
    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()
Esempio n. 4
0
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
Esempio n. 5
0
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)
Esempio n. 6
0
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
Esempio n. 7
0
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")
Esempio n. 8
0
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")
Esempio n. 9
0
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")
Esempio n. 10
0
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")
Esempio n. 11
0
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")
Esempio n. 12
0
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")