Beispiel #1
0
    def get_measurement(self):
        """ Gets the sensor's Electrical Conductivity measurement via UART/I2C """
        self._electrical_conductivity = None
        electrical_conductivity = None

        # Read sensor via UART
        if self.interface == 'UART':
            if self.atlas_sensor_uart.setup:
                lines = self.atlas_sensor_uart.query('R')
                if lines:
                    self.logger.debug("All Lines: {lines}".format(lines=lines))

                    # 'check probe' indicates an error reading the sensor
                    if 'check probe' in lines:
                        self.logger.error('"check probe" returned from sensor')
                    # if a string resembling a float value is returned, this
                    # is out measurement value
                    elif str_is_float(lines[0]):
                        electrical_conductivity = float(lines[0])
                        self.logger.debug('Value[0] is float: {val}'.format(
                            val=electrical_conductivity))
                    else:
                        # During calibration, the sensor is put into
                        # continuous mode, which causes a return of several
                        # values in one string. If the return value does
                        # not represent a float value, it is likely to be a
                        # string of several values. This parses and returns
                        # the first value.
                        if str_is_float(lines[0].split(b'\r')[0]):
                            electrical_conductivity = lines[0].split(b'\r')[0]
                        # Lastly, this is called if the return value cannot
                        # be determined. Watchthe output in the GUI to see
                        # what it is.
                        else:
                            electrical_conductivity = lines[0]
                            self.logger.error(
                                'Value[0] is not float or "check probe": '
                                '{val}'.format(val=electrical_conductivity))
            else:
                self.logger.error('UART device is not set up.'
                                  'Check the log for errors.')

        # Read sensor via I2C
        elif self.interface == 'I2C':
            if self.atlas_sensor_i2c.setup:
                ec_status, ec_str = self.atlas_sensor_i2c.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)
            else:
                self.logger.error(
                    'I2C device is not set up. Check the log for errors.')

        electrical_conductivity = convert_units('electrical_conductivity',
                                                'μS_cm', self.convert_to_unit,
                                                electrical_conductivity)

        return electrical_conductivity
Beispiel #2
0
    def get_measurement(self):
        """ Gets the Atlas PT1000's temperature in Celsius """
        temp = None
        self.return_dict = measurements_dict.copy()

        if self.interface == 'FTDI':
            if self.atlas_sensor_ftdi.setup:
                lines = self.atlas_sensor_ftdi.query('R')
                self.logger.debug("All Lines: {lines}".format(lines=lines))

                if 'check probe' in lines:
                    self.logger.error('"check probe" returned from sensor')
                elif isinstance(lines, list):
                    if str_is_float(lines[0]):
                        temp = float(lines[0])
                        self.logger.debug(
                            'Value[0] is float: {val}'.format(val=temp))
                elif str_is_float(lines):
                    temp = float(lines)
                    self.logger.debug('Value is float: {val}'.format(val=temp))
                else:
                    self.logger.error('Unknown value: {val}'.format(val=lines))
            else:
                self.logger.error('FTDI device is not set up. '
                                  'Check the log for errors.')

        elif self.interface == 'UART':
            if self.atlas_sensor_uart.setup:
                lines = self.atlas_sensor_uart.query('R')
                self.logger.debug("All Lines: {lines}".format(lines=lines))

                if 'check probe' in lines:
                    self.logger.error('"check probe" returned from sensor')
                elif str_is_float(lines[0]):
                    temp = float(lines[0])
                    self.logger.debug(
                        'Value[0] is float: {val}'.format(val=temp))
                else:
                    self.logger.error(
                        'Value[0] is not float or "check probe": '
                        '{val}'.format(val=lines[0]))
            else:
                self.logger.error('UART device is not set up. '
                                  'Check the log for errors.')

        elif self.interface == 'I2C':
            if self.atlas_sensor_i2c.setup:
                temp_status, temp_str = self.atlas_sensor_i2c.query('R')
                if temp_status == 'error':
                    self.logger.error(
                        "Sensor read unsuccessful: {err}".format(err=temp_str))
                elif temp_status == 'success':
                    temp = float(temp_str)
            else:
                self.logger.error('I2C device is not set up.'
                                  'Check the log for errors.')

        self.value_set(0, temp)

        return self.return_dict
Beispiel #3
0
    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
Beispiel #4
0
def output_mod(output_id, state, out_type, amount):
    """ Manipulate output (using non-unique ID) """
    if not utils_general.user_has_permission('edit_controllers'):
        return 'Insufficient user permissions to manipulate outputs'

    daemon = DaemonControl()
    if (state in ['on', 'off'] and out_type == 'sec' and
            (str_is_float(amount) and float(amount) >= 0)):
        return daemon.output_on_off(output_id, state, float(amount))
    elif (state == 'on' and out_type in ['pwm', 'command_pwm'] and
              (str_is_float(amount) and float(amount) >= 0)):
        return daemon.output_on(output_id, duty_cycle=float(amount))
Beispiel #5
0
    def get_measurement(self):
        """Gets the Atlas Scientific pressure sensor 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

        pressure = None
        self.return_dict = copy.deepcopy(measurements_dict)

        if self.led == 'measure':
            self.atlas_device.query('L,1')

        # Read device
        atlas_status, atlas_return = self.atlas_device.query('R')
        self.logger.debug("Device Returned: {}: {}".format(
            atlas_status, atlas_return))

        if self.led == 'measure':
            self.atlas_device.query('L,0')

        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):
                pressure = float(float_value)
                self.logger.debug(
                    'Found float value: {val}'.format(val=pressure))
            else:
                self.logger.error(
                    'Value or "check probe" not found in list: {val}'.format(
                        val=atlas_return))

        elif self.interface == 'I2C':
            pressure = float(atlas_return)

        self.value_set(0, pressure)

        return self.return_dict
Beispiel #6
0
def output_mod(output_id, state, out_type, amount):
    """ Manipulate output (using non-unique ID) """
    if not utils_general.user_has_permission('edit_controllers'):
        return 'Insufficient user permissions to manipulate outputs'

    daemon = DaemonControl()
    if (state in ['on', 'off'] and out_type == 'sec'
            and (str_is_float(amount) and float(amount) >= 0)):
        return daemon.output_on_off(output_id, state, float(amount))
    elif (state == 'on' and out_type in ['pwm', 'command_pwm']
          and (str_is_float(amount) and float(amount) >= 0)):
        return daemon.output_on(output_id, state, duty_cycle=float(amount))
Beispiel #7
0
    def get_measurement(self):
        """ Gets the Atlas Scientific pressure sensor measurement """
        if not self.atlas_device.setup:
            self.logger.error("Input not set up")
            return

        pressure = None
        self.return_dict = copy.deepcopy(measurements_dict)

        if self.led == 'measure':
            self.atlas_device.query('L,1')

        # Read sensor via FTDI or UART
        if self.interface in ['FTDI', 'UART']:
            press_status, press_list = self.atlas_device.query('R')
            if press_list:
                self.logger.debug(
                    "Returned list: {lines}".format(lines=press_list))

            # Find float value in list
            float_value = None
            for each_split in press_list:
                if str_is_float(each_split):
                    float_value = each_split
                    break

            if 'check probe' in press_list:
                self.logger.error('"check probe" returned from sensor')
            elif str_is_float(float_value):
                pressure = float(float_value)
                self.logger.debug(
                    'Found float value: {val}'.format(val=pressure))
            else:
                self.logger.error(
                    'Value or "check probe" not found in list: {val}'.format(
                        val=press_list))

        elif self.interface == 'I2C':
            pressure_status, pressure_str = self.atlas_device.query('R')
            if pressure_status == 'error':
                self.logger.error(
                    "Sensor read unsuccessful: {err}".format(err=pressure_str))
            elif pressure_status == 'success':
                pressure = float(pressure_str)

        if self.led == 'measure':
            self.atlas_device.query('L,0')

        self.value_set(0, pressure)

        return self.return_dict
Beispiel #8
0
def setup_atlas_ec_measure(input_id):
    """
    Acquire a measurement from the Atlas Scientific EC input and return it
    Used during calibration to display the current EC to the user
    """
    if not utils_general.user_has_permission('edit_controllers'):
        return redirect(url_for('routes_page.page_atlas_ec_calibrate'))

    selected_input = Input.query.filter_by(unique_id=input_id).first()

    ec = None
    error = None

    atlas_command = setup_atlas_device(selected_input)

    if selected_input.interface in ['FTDI', 'UART']:
        ec_status, ec_list = atlas_command.query('R')
        if ec_list:
            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:
                error = '"check probe" returned from input'
            # if a string resembling a float value is returned, this
            # is our measurement value
            elif str_is_float(float_value):
                ec = float(float_value)
                logger.debug('Found float value: {val}'.format(val=ec))
            else:
                logger.error('Value or "check probe" not found in list: '
                             '{val}'.format(val=ec_list))

    elif selected_input.interface == 'I2C':
        ec_status, ec_str = atlas_command.query('R')
        if ec_status == 'error':
            error = "Input read unsuccessful: {err}".format(err=ec_str)
        elif ec_status == 'success':
            ec = ec_str

    if error:
        logger.error(error)
        return error, 204
    else:
        return ec
Beispiel #9
0
def output_mod_unique_id(unique_id, state, out_type, amount):
    """ Manipulate output (using unique ID) """
    if not utils_general.user_has_permission('edit_controllers'):
        return 'Insufficient user permissions to manipulate outputs'

    output = Output.query.filter(Output.unique_id == unique_id).first()

    daemon = DaemonControl()
    if (state in ['on', 'off'] and out_type == 'sec'
            and (str_is_float(amount) and float(amount) >= 0)):
        return daemon.output_on_off(output.id, state, float(amount))
    elif (state == 'on' and out_type == 'pwm'
          and (str_is_float(amount) and float(amount) >= 0)):
        return daemon.relay_on(output.id, state, duty_cycle=float(amount))
Beispiel #10
0
    def get_measurement(self):
        """ Gets the sensor's measurement """
        if not self.atlas_device.setup:
            self.logger.error("Input not set up")
            return

        co2 = None
        self.return_dict = copy.deepcopy(measurements_dict)

        # Read sensor via FTDI or UART
        if self.interface in ['FTDI', 'UART']:
            co2_status, co2_list = self.atlas_device.query('R')
            self.logger.debug("Returned: {}".format(co2_list))

            # Find float value in list
            float_value = None
            for each_split in co2_list:
                if str_is_float(each_split):
                    float_value = each_split
                    break

            if 'check probe' in co2_list:
                self.logger.error('"check probe" returned from sensor')
            elif str_is_float(float_value):
                co2 = float(float_value)
                self.logger.debug('Found float value: {val}'.format(val=co2))
            else:
                self.logger.error(
                    'Value or "check probe" not found in list: {val}'.format(
                        val=co2_list))

        # Read sensor via I2C
        elif self.interface == 'I2C':
            co2_status, co2_str = self.atlas_device.query('R')
            self.logger.debug("Returned: {}".format(co2_str))
            if co2_status == 'error':
                self.logger.error(
                    "Sensor read unsuccessful: {err}".format(err=co2_str))
            elif co2_status == 'success':
                if str_is_float(co2_str):
                    co2 = float(co2_str)
                else:
                    self.logger.error(
                        "Could not determine co2 from returned string: '{}'".
                        format(co2_str))

        self.value_set(0, co2)

        return self.return_dict
Beispiel #11
0
    def get_measurement(self):
        """ Gets the Atlas PT1000's temperature in Celsius """
        if not self.atlas_device.setup:
            self.logger.error("Input not set up")
            return

        temp = None
        self.return_dict = copy.deepcopy(measurements_dict)

        # Read sensor via FTDI or UART
        if self.interface in ['FTDI', 'UART']:
            temp_status, temp_list = self.atlas_device.query('R')
            if temp_list:
                self.logger.debug(
                    "Returned list: {lines}".format(lines=temp_list))

            # Find float value in list
            float_value = None
            for each_split in temp_list:
                if str_is_float(each_split):
                    float_value = each_split
                    break

            if 'check probe' in temp_list:
                self.logger.error('"check probe" returned from sensor')
            elif str_is_float(float_value):
                temp = float(float_value)
                self.logger.debug('Found float value: {val}'.format(val=temp))
            else:
                self.logger.error(
                    'Value or "check probe" not found in list: {val}'.format(
                        val=temp_list))

        # Read sensor via I2C
        elif self.interface == 'I2C':
            temp_status, temp_str = self.atlas_device.query('R')
            if temp_status == 'error':
                self.logger.error(
                    "Sensor read unsuccessful: {err}".format(err=temp_str))
            elif temp_status == 'success':
                temp = float(temp_str)

        if temp == -1023:  # Erroneous measurement
            return

        self.value_set(0, temp)

        return self.return_dict
Beispiel #12
0
def last_data_pid(input_id, input_period):
    """Return the most recent time and value from influxdb"""
    if not str_is_float(input_period):
        return '', 204

    try:
        pid = PID.query.filter(PID.unique_id == input_id).first()
        measure_id = pid.measurement.split(',')[0]
        measure_type = pid.measurement.split(',')[1]

        live_data = {
            'activated': pid.is_activated,
            'paused': pid.is_paused,
            'held': pid.is_held,
            'setpoint': return_point_timestamp('setpoint', input_id, input_period),
            'pid_p_value': return_point_timestamp('pid_p_value', input_id, input_period),
            'pid_i_value': return_point_timestamp('pid_i_value', input_id, input_period),
            'pid_d_value': return_point_timestamp('pid_d_value', input_id, input_period),
            'pid_output': return_point_timestamp('pid_output', input_id, input_period),
            'actual': return_point_timestamp(measure_type, measure_id, input_period)
        }
        return jsonify(live_data)
    except KeyError:
        logger.debug("No Data returned form influxdb")
        return '', 204
    except Exception as e:
        logger.exception("URL for 'last_pid' raised and error: "
                         "{err}".format(err=e))
        return '', 204
Beispiel #13
0
def output_mod(output_id, channel, state, output_type, amount):
    """ Manipulate output (using non-unique ID) """
    if not utils_general.user_has_permission('edit_controllers'):
        return 'Insufficient user permissions to manipulate outputs'

    if is_int(channel):
        # if an integer was returned
        output_channel = int(channel)
    else:
        # if a channel ID was returned
        channel_dev = db_retrieve_table(OutputChannel).filter(
            OutputChannel.unique_id == channel).first()
        if channel_dev:
            output_channel = channel_dev.channel
        else:
            return "Could not determine channel number from channel ID '{}'".format(
                channel)

    daemon = DaemonControl()
    if (state in ['on', 'off'] and str_is_float(amount) and
        ((output_type in ['sec', 'pwm', 'vol'] and float(amount) >= 0) or
         (output_type == 'value'))):
        out_status = daemon.output_on_off(output_id,
                                          state,
                                          output_type=output_type,
                                          amount=float(amount),
                                          output_channel=output_channel)
        if out_status[0]:
            return 'ERROR: {}'.format(out_status[1])
        else:
            return 'SUCCESS: {}'.format(out_status[1])
    else:
        return 'ERROR: unknown parameters: ' \
               'output_id: {}, channel: {}, state: {}, output_type: {}, amount: {}'.format(
                output_id, channel, state, output_type, amount)
Beispiel #14
0
def output_mod(output_id, channel_id, state, output_type, amount):
    """ Manipulate output (using non-unique ID) """
    if not utils_general.user_has_permission('edit_controllers'):
        return 'Insufficient user permissions to manipulate outputs'

    if channel_id == '0':
        # some parts of pages don't have access to the channel ID and only know there is 1 channel
        channel = db_retrieve_table(OutputChannel).filter(and_(
            OutputChannel.output_id == output_id,
            OutputChannel.channel == 0)).first()
    else:
        channel = db_retrieve_table(OutputChannel, unique_id=channel_id)

    daemon = DaemonControl()
    if (state in ['on', 'off'] and output_type in ['sec', 'pwm', 'vol'] and
            (str_is_float(amount) and float(amount) >= 0)):
        out_status = daemon.output_on_off(
            output_id,
            state,
            output_type=output_type,
            amount=float(amount),
            output_channel=channel.channel)
        if out_status[0]:
            return 'ERROR: {}'.format(out_status[1])
        else:
            return 'SUCCESS: {}'.format(out_status[1])
Beispiel #15
0
    def get_measurement(self):
        """ Determine if the return value of the command is a number """
        self.return_dict = measurements_dict.copy()

        self.logger.debug("Command being executed: {}".format(self.command))

        timeout = 360
        if self.command_timeout:
            timeout = self.command_timeout

        out, err, status = cmd_output(
            self.command,
            timeout=timeout,
            user=self.execute_as_user,
            cwd=self.current_working_dir)

        self.logger.debug("Command returned: {}, Status: {}, Error: {}".format(out, err, status))

        if str_is_float(out):
            measurement_value = float(out)
        else:
            self.logger.debug(
                "The command returned a non-numerical value. "
                "Ensure only one numerical value is returned "
                "by the command. Value returned: '{}'".format(out))
            return

        for channel in self.channels_measurement:
            if self.is_enabled(channel):
                self.return_dict[channel]['unit'] = self.channels_measurement[channel].unit
                self.return_dict[channel]['measurement'] = self.channels_measurement[channel].measurement
                self.return_dict[channel]['value'] = measurement_value

        return self.return_dict
Beispiel #16
0
def last_data(input_measure, input_id, input_period):
    """Return the most recent time and value from influxdb"""
    if not str_is_float(input_period):
        return '', 204

    current_app.config['INFLUXDB_USER'] = INFLUXDB_USER
    current_app.config['INFLUXDB_PASSWORD'] = INFLUXDB_PASSWORD
    current_app.config['INFLUXDB_DATABASE'] = INFLUXDB_DATABASE
    dbcon = influx_db.connection
    try:
        query_str = query_string(input_measure,
                                 input_id,
                                 value='LAST',
                                 past_sec=input_period)
        if query_str == 1:
            return '', 204
        raw_data = dbcon.query(query_str).raw
        number = len(raw_data['series'][0]['values'])
        time_raw = raw_data['series'][0]['values'][number - 1][0]
        value = raw_data['series'][0]['values'][number - 1][1]
        value = '{:.3f}'.format(float(value))
        # Convert date-time to epoch (potential bottleneck for data)
        dt = date_parse(time_raw)
        timestamp = calendar.timegm(dt.timetuple()) * 1000
        live_data = '[{},{}]'.format(timestamp, value)
        return Response(live_data, mimetype='text/json')
    except KeyError:
        logger.debug("No Data returned form influxdb")
        return '', 204
    except Exception as e:
        logger.exception("URL for 'last_data' raised and error: "
                         "{err}".format(err=e))
        return '', 204
Beispiel #17
0
    def get_measurement(self):
        """ Gets the Atlas PT1000's temperature in Celsius """
        temp = None
        if self.interface == 'UART':
            if self.atlas_sensor_uart.setup:
                lines = self.atlas_sensor_uart.query('R')
                logger.debug("All Lines: {lines}".format(lines=lines))

                if 'check probe' in lines:
                    logger.error('"check probe" returned from sensor')
                elif str_is_float(lines[0]):
                    temp = float(lines[0])
                    logger.debug('Value[0] is float: {val}'.format(val=temp))
                else:
                    temp = lines[0]
                    logger.error('Value[0] is not float or "check probe": '
                                 '{val}'.format(val=temp))
            else:
                logger.error('UART device is not set up. '
                             'Check the log for errors.')
        elif self.interface == 'I2C':
            if self.atlas_sensor_i2c.setup:
                temp_status, temp_str = self.atlas_sensor_i2c.query('R')
                if temp_status == 'error':
                    logger.error(
                        "Sensor read unsuccessful: {err}".format(err=temp_str))
                elif temp_status == 'success':
                    temp = float(temp_str)
            else:
                logger.error('I2C device is not set up.'
                             'Check the log for errors.')

        return temp
Beispiel #18
0
    def get_measurement(self):
        """ Gets the sensor's DO measurement """
        if not self.atlas_device.setup:
            self.logger.error("Input not set up")
            return

        do = None
        self.return_dict = copy.deepcopy(measurements_dict)

        # Read sensor via FTDI or UART
        if self.interface in ['FTDI', 'UART']:
            do_status, do_list = self.atlas_device.query('R')
            if do_list:
                self.logger.debug(
                    "Returned list: {lines}".format(lines=do_list))

            # Find float value in list
            float_value = None
            for each_split in do_list:
                if str_is_float(each_split):
                    float_value = each_split
                    break

            if 'check probe' in do_list:
                self.logger.error('"check probe" returned from sensor')
            elif str_is_float(float_value):
                do = float(float_value)
                self.logger.debug('Found float value: {val}'.format(val=do))
            else:
                self.logger.error(
                    'Value or "check probe" not found in list: {val}'.format(
                        val=do_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':
                do = float(ec_str)

        self.value_set(0, do)

        return self.return_dict
Beispiel #19
0
    def get_measurement(self):
        """Gets the Atlas Scientific humidity sensor 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

        return_string = None
        self.return_dict = copy.deepcopy(measurements_dict)

        if self.led == 'measure':
            self.atlas_device.query('L,1')

        # Read device
        atlas_status, atlas_return = self.atlas_device.query('R')
        self.logger.debug("Device Returned: {}: {}".format(atlas_status, atlas_return))

        if self.led == 'measure':
            self.atlas_device.query('L,0')

        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']:
            if 'check probe' in atlas_return:
                self.logger.error('"check probe" returned from sensor')
                return

            # Find value(s) in list
            for each_split in atlas_return:
                if "," in each_split or str_is_float(each_split):
                    return_string = each_split
                    break

        elif self.interface == 'I2C':
            return_string = atlas_return

        # Parse return string
        if return_string and ',' in return_string:
            index_place = 0
            return_list = return_string.split(',')
            if self.is_enabled(1):
                self.value_set(1, return_list[index_place])
                index_place += 1
            if self.is_enabled(0):
                self.value_set(0, return_list[index_place])
                index_place += 1
            if self.is_enabled(2):
                self.value_set(2, return_list[index_place + 1])
        elif self.is_enabled(0) and not self.is_enabled(1) and not self.is_enabled(2):
            self.value_set(0, return_string)
        elif not self.is_enabled(0) and self.is_enabled(1) and not self.is_enabled(2):
            self.value_set(1, return_string)

        return self.return_dict
Beispiel #20
0
    def get_measurement(self):
        """ Gets the sensor's pH measurement via UART/I2C """
        try:
            if ',' in self.sensor_sel.calibrate_sensor_measure:
                logger.debug("pH sensor set to calibrate temperature")

                device_id = self.sensor_sel.calibrate_sensor_measure.split(',')[0]
                measurement = self.sensor_sel.calibrate_sensor_measure.split(',')[1]
                last_measurement = read_last_influxdb(
                    device_id, measurement, duration_sec=300)
                if last_measurement:
                    logger.debug("Latest temperature used to calibrate: {temp}".format(
                        temp=last_measurement[1]))

                    atlas_command = AtlasScientificCommand(self.sensor_sel)
                    ret_value, ret_msg = atlas_command.calibrate(
                        'temperature', temperature=last_measurement[1])
                    time.sleep(0.5)

                    logger.debug("Calibration returned: {val}, {msg}".format(
                        val=ret_value, msg=ret_msg))

            ph = None
            if self.interface == 'UART':
                if self.atlas_sensor_uart.setup:
                    lines = self.atlas_sensor_uart.query('R')
                    if lines:
                        logger.debug("All Lines: {lines}".format(lines=lines))

                        if 'check probe' in lines:
                            logger.error('"check probe" returned from sensor')
                        elif str_is_float(lines[0]):
                            ph = float(lines[0])
                            logger.debug('Value[0] is float: {val}'.format(val=ph))
                        else:
                            ph = lines[0]
                            logger.error('Value[0] is not float or "check probe": '
                                         '{val}'.format(val=ph))
                else:
                    logger.error('UART device is not set up.'
                                 'Check the log for errors.')
            elif self.interface == 'I2C':
                if self.atlas_sensor_i2c.setup:
                    ph_status, ph_str = self.atlas_sensor_i2c.query('R')
                    if ph_status == 'error':
                        logger.error("Sensor read unsuccessful: {err}".format(
                            err=ph_str))
                    elif ph_status == 'success':
                        ph = float(ph_str)
                else:
                    logger.error('I2C device is not set up.'
                                 'Check the log for errors.')

            return ph
        except:
            logger.exception(1)
Beispiel #21
0
def output_mod(output_id, state, out_type, amount):
    """ Manipulate output (using non-unique ID) """
    if not utils_general.user_has_permission('edit_controllers'):
        return 'Insufficient user permissions to manipulate outputs'

    daemon = DaemonControl()
    if (state in ['on', 'off'] and out_type == 'sec'
            and (str_is_float(amount) and float(amount) >= 0)):
        out_status = daemon.output_on_off(output_id, state, float(amount))
        if out_status[0]:
            return 'ERROR: {}'.format(out_status[1])
        else:
            return 'SUCCESS: {}'.format(out_status[1])
    elif (state == 'on' and out_type in OUTPUTS_PWM
          and (str_is_float(amount) and float(amount) >= 0)):
        out_status = daemon.output_on(output_id, duty_cycle=float(amount))
        if out_status[0]:
            return 'ERROR: {}'.format(out_status[1])
        else:
            return 'SUCCESS: {}'.format(out_status[1])
Beispiel #22
0
    def get_measurement(self):
        """ Determine if the return value of the command is a number """
        self._measurement = None

        out, _, _ = cmd_output(self.command)
        if str_is_float(out):
            return float(out)
        else:
            logger.error("The command returned a non-numerical value. "
                         "Ensure only one numerical value is returned "
                         "by the command.")
            return None
Beispiel #23
0
 def read(self, num_of_bytes=31):
     """ Read a specified number of bytes from I2C, then parse and display the result """
     res = self.file_read.read(num_of_bytes)  # read from the board
     response = list(filter(lambda x: x != '\x00', res.decode()))  # remove the null characters to get the response
     if ord(response[0]) == 1:  # if the response isn't an error
         # change MSB to 0 for all received characters except the first and get a list of characters
         char_list = map(lambda x: chr(ord(x) & ~0x80), list(response[1:]))
         # NOTE: having to change the MSB to 0 is a glitch in the raspberry pi, and you shouldn't have to do this!
         str_float = ''.join(char_list)
         if str_is_float(str_float):
             return "success", str_float  # convert the char list to a string and returns it
         else:
             return "error", "returned string does not represent a float value: {str}".format(str=str_float)
     else:
         return "error", str(ord(response[0]))
Beispiel #24
0
def past_data(input_measure, input_id, past_seconds):
    """Return data from past_seconds until present from influxdb"""
    if not str_is_float(past_seconds):
        return '', 204

    if input_measure == 'tag':
        notes_list = []

        tag = NoteTags.query.filter(NoteTags.unique_id == input_id).first()
        notes = Notes.query.filter(Notes.date_time >= (
            datetime.datetime.utcnow() -
            datetime.timedelta(seconds=int(past_seconds)))).all()

        for each_note in notes:
            if tag.unique_id in each_note.tags.split(','):
                notes_list.append([
                    each_note.date_time.strftime(
                        "%Y-%m-%dT%H:%M:%S.000000000Z"), each_note.name,
                    each_note.note
                ])

        if notes_list:
            return jsonify(notes_list)
        else:
            return '', 204
    else:
        current_app.config['INFLUXDB_USER'] = INFLUXDB_USER
        current_app.config['INFLUXDB_PASSWORD'] = INFLUXDB_PASSWORD
        current_app.config['INFLUXDB_DATABASE'] = INFLUXDB_DATABASE
        current_app.config['INFLUXDB_TIMEOUT'] = 5
        dbcon = influx_db.connection

        try:
            query_str = query_string(input_measure,
                                     input_id,
                                     past_sec=past_seconds)
            if query_str == 1:
                return '', 204
            raw_data = dbcon.query(query_str).raw
            if raw_data:
                return jsonify(raw_data['series'][0]['values'])
            else:
                return '', 204
        except Exception as e:
            logger.debug("URL for 'past_data' raised and error: "
                         "{err}".format(err=e))
            return '', 204
Beispiel #25
0
def setup_atlas_ph_measure(input_id):
    """
    Acquire a measurement from the Atlas Scientific pH input and return it
    Used during calibration to display the current pH to the user
    """
    if not utils_general.user_has_permission('edit_controllers'):
        return redirect(url_for('routes_page.page_atlas_ph_calibrate'))

    selected_input = Input.query.filter_by(unique_id=input_id).first()

    ph = None
    error = None

    if selected_input.interface == 'UART':
        ph_input_uart = AtlasScientificUART(
            selected_input.device_loc, baudrate=selected_input.baud_rate)
        lines = ph_input_uart.query('R')
        logger.debug("All Lines: {lines}".format(lines=lines))

        if 'check probe' in lines:
            error = '"check probe" returned from input'
        elif not lines:
            error = 'Nothing returned from input'
        elif str_is_float(lines[0]):
            ph = lines[0]
            logger.debug('Value[0] is float: {val}'.format(val=ph))
        else:
            error = 'Value[0] is not float or "check probe": {val}'.format(
                val=lines[0])
    elif selected_input.interface == 'I2C':
        ph_input_i2c = AtlasScientificI2C(
            i2c_address=int(str(selected_input.location), 16),
            i2c_bus=selected_input.i2c_bus)
        ph_status, ph_str = ph_input_i2c.query('R')
        if ph_status == 'error':
            error = "Input read unsuccessful: {err}".format(err=ph_str)
        elif ph_status == 'success':
            ph = ph_str

    if error:
        logger.error(error)
        return error, 204
    else:
        return ph
Beispiel #26
0
    def get_measurement(self):
        """ Determine if the return value of the command is a number """
        self.return_dict = measurements_dict.copy()

        out, _, _ = cmd_output(self.command)

        if str_is_float(out):
            list_measurements = [float(out)]
        else:
            self.logger.error("The command returned a non-numerical value. "
                              "Ensure only one numerical value is returned "
                              "by the command.")
            return

        for channel, meas in enumerate(self.device_measurements.all()):
            if meas.is_enabled:
                self.return_dict[channel]['unit'] = meas.unit
                self.return_dict[channel]['measurement'] = meas.measurement
                self.return_dict[channel]['value'] = list_measurements[channel]

        return self.return_dict
Beispiel #27
0
    def get_measurement(self):
        """ Determine if the return value of the command is a number """
        return_dict = measurements_dict.copy()

        out, _, _ = cmd_output(self.command)

        if str_is_float(out):
            list_measurements = [float(out)]
        else:
            self.logger.error(
                "The command returned a non-numerical value. "
                "Ensure only one numerical value is returned "
                "by the command.")
            return

        for channel, meas in enumerate(self.device_measurements.all()):
            if meas.is_enabled:
                return_dict[channel]['unit'] = meas.unit
                return_dict[channel]['measurement'] = meas.measurement
                return_dict[channel]['value'] = list_measurements[channel]

        return return_dict
Beispiel #28
0
def past_data(input_measure, input_id, past_seconds):
    """Return data from past_seconds until present from influxdb"""
    if not str_is_float(past_seconds):
        return '', 204

    current_app.config['INFLUXDB_USER'] = INFLUXDB_USER
    current_app.config['INFLUXDB_PASSWORD'] = INFLUXDB_PASSWORD
    current_app.config['INFLUXDB_DATABASE'] = INFLUXDB_DATABASE
    dbcon = influx_db.connection
    try:
        query_str = query_string(
            input_measure, input_id, past_sec=past_seconds)
        if query_str == 1:
            return '', 204
        raw_data = dbcon.query(query_str).raw
        if raw_data:
            return jsonify(raw_data['series'][0]['values'])
        else:
            return '', 204
    except Exception as e:
        logger.debug("URL for 'past_data' raised and error: "
                     "{err}".format(err=e))
        return '', 204
Beispiel #29
0
def last_data_pid(pid_id, input_period):
    """Return the most recent time and value from influxdb"""
    if not str_is_float(input_period):
        return '', 204

    try:
        pid = PID.query.filter(PID.unique_id == pid_id).first()
        device_id = pid.measurement.split(',')[0]
        measurement_id = pid.measurement.split(',')[1]

        actual_measurement = DeviceMeasurements.query.filter(
            DeviceMeasurements.unique_id == measurement_id).first()
        if actual_measurement:
            actual_cnversion = Conversion.query.filter(
                Conversion.unique_id == actual_measurement.conversion_id).first()
        else:
            actual_cnversion = None

        (actual_channel,
         actual_unit,
         actual_measurement) = return_measurement_info(
            actual_measurement, actual_cnversion)

        setpoint_measurement = None
        setpoint_unit = None
        setpoint_pid = PID.query.filter(PID.unique_id == pid_id).first()
        if setpoint_pid and ',' in setpoint_pid.measurement:
            pid_measurement = setpoint_pid.measurement.split(',')[1]
            setpoint_measurement = DeviceMeasurements.query.filter(
                DeviceMeasurements.unique_id == pid_measurement).first()
            if setpoint_measurement:
                conversion = Conversion.query.filter(
                    Conversion.unique_id == setpoint_measurement.conversion_id).first()
                _, setpoint_unit, _ = return_measurement_info(setpoint_measurement, conversion)

        p_value = return_point_timestamp(
            pid_id, 'pid_value', input_period, measurement='pid_p_value')
        i_value = return_point_timestamp(
            pid_id, 'pid_value', input_period, measurement='pid_i_value')
        d_value = return_point_timestamp(
            pid_id, 'pid_value', input_period, measurement='pid_d_value')
        pid_value = [p_value[0], '{:.3f}'.format(float(p_value[1]) + float(i_value[1]) + float(d_value[1]))]

        live_data = {
            'activated': pid.is_activated,
            'paused': pid.is_paused,
            'held': pid.is_held,
            'setpoint': return_point_timestamp(
                pid_id, setpoint_unit, input_period, measurement=setpoint_measurement.measurement),
            'pid_p_value': p_value,
            'pid_i_value': i_value,
            'pid_d_value': d_value,
            'pid_pid_value': pid_value,
            'duration_time': return_point_timestamp(
                pid_id, 's', input_period, measurement='duration_time'),
            'duty_cycle': return_point_timestamp(
                pid_id, 'percent', input_period, measurement='duty_cycle'),
            'actual': return_point_timestamp(
                device_id,
                actual_unit,
                input_period,
                measurement=actual_measurement,
                channel=actual_channel)
        }
        return jsonify(live_data)
    except KeyError:
        logger.debug("No Data returned form influxdb")
        return '', 204
    except Exception as e:
        logger.exception("URL for 'last_pid' raised and error: "
                         "{err}".format(err=e))
        return '', 204
Beispiel #30
0
    def get_measurement(self):
        """ Obtain and return the measurements """
        self.return_dict = measurements_dict.copy()

        self.lock_acquire(self.lock_file, timeout=3600)
        if self.locked:
            self.logger.debug("Starting measurement")
            try:
                cmd = 'timeout -k 11 10 /var/mycodo-root/env/bin/python ' \
                      '/var/mycodo-root/mycodo/inputs/scripts/ruuvitag_values.py ' \
                      '--mac_address {mac} --bt_adapter {bta}'.format(
                          mac=self.location, bta=self.bt_adapter)
                cmd = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
                cmd_return, _ = cmd.communicate()
                cmd.wait()

                if not cmd_return:
                    self.logger.debug("Measurement command returned no data")
                    return

                values = cmd_return.decode('ascii').split(',')

                if not str_is_float(values[0]):
                    self.logger.debug(
                        "Error: Could not convert string to float: "
                        "string '{}'".format(str(values[0])))
                    return

                temperature = float(str(values[0]))
                humidity = float(values[1])
                pressure = float(values[2])
                battery = float(values[3]) / 1000
                acceleration_g_force = float(values[4]) / 1000
                acceleration_x_g_force = float(values[5]) / 1000
                acceleration_y_g_force = float(values[6]) / 1000
                acceleration_z_g_force = float(values[7]) / 1000

                if battery < 1 or battery > 4:
                    self.logger.debug(
                        "Not recording measurements: "
                        "Battery outside expected range (1 < battery volts < 4): "
                        "{bat}".format(bat=battery))
                    return

                if self.is_enabled(0):
                    self.value_set(0, temperature)

                if self.is_enabled(1):
                    self.value_set(1, humidity)

                if self.is_enabled(2):
                    self.value_set(2, pressure)

                if self.is_enabled(3):
                    self.value_set(3, battery)

                if self.is_enabled(4):
                    self.value_set(4, acceleration_g_force)

                if self.is_enabled(5):
                    self.value_set(5, acceleration_x_g_force)

                if self.is_enabled(6):
                    self.value_set(6, acceleration_y_g_force)

                if self.is_enabled(7):
                    self.value_set(7, acceleration_z_g_force)

                if (self.is_enabled(8) and self.is_enabled(0)
                        and self.is_enabled(1)):
                    self.value_set(
                        8,
                        calculate_dewpoint(self.value_get(0),
                                           self.value_get(1)))

                if (self.is_enabled(9) and self.is_enabled(0)
                        and self.is_enabled(1)):
                    self.value_set(
                        9,
                        calculate_vapor_pressure_deficit(
                            self.value_get(0), self.value_get(1)))

                self.logger.debug("Completed measurement")
                return self.return_dict

            except Exception as msg:
                self.logger.debug("Error: {}".format(msg))

            finally:
                self.lock_release(self.lock_file)
                time.sleep(1)
Beispiel #31
0
    def get_measurement(self):
        """ Gets the sensor's ORP measurement via UART/I2C """
        orp = None
        self.return_dict = measurements_dict.copy()

        # 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 UART
        if self.interface == 'FTDI':
            if self.atlas_sensor_ftdi.setup:
                lines = self.atlas_sensor_ftdi.query('R')
                if lines:
                    self.logger.debug("All Lines: {lines}".format(lines=lines))

                    # 'check probe' indicates an error reading the sensor
                    if 'check probe' in lines:
                        self.logger.error('"check probe" returned from sensor')
                    # if a string resembling a float value is returned, this
                    # is out measurement value
                    elif str_is_float(lines[0]):
                        orp = float(lines[0])
                        self.logger.debug(
                            'Value[0] is float: {val}'.format(val=orp))
                    else:
                        # During calibration, the sensor is put into
                        # continuous mode, which causes a return of several
                        # values in one string. If the return value does
                        # not represent a float value, it is likely to be a
                        # string of several values. This parses and returns
                        # the first value.
                        if str_is_float(lines[0].split(b'\r')[0]):
                            orp = lines[0].split(b'\r')[0]
                        # Lastly, this is called if the return value cannot
                        # be determined. Watchthe output in the GUI to see
                        # what it is.
                        else:
                            orp = lines[0]
                            self.logger.error(
                                'Value[0] is not float or "check probe": '
                                '{val}'.format(val=orp))
            else:
                self.logger.error('FTDI device is not set up.'
                                  'Check the log for errors.')

        # Read sensor via UART
        elif self.interface == 'UART':
            if self.atlas_sensor_uart.setup:
                lines = self.atlas_sensor_uart.query('R')
                if lines:
                    self.logger.debug("All Lines: {lines}".format(lines=lines))

                    # 'check probe' indicates an error reading the sensor
                    if 'check probe' in lines:
                        self.logger.error('"check probe" returned from sensor')
                    # if a string resembling a float value is returned, this
                    # is out measurement value
                    elif str_is_float(lines[0]):
                        orp = float(lines[0])
                        self.logger.debug(
                            'Value[0] is float: {val}'.format(val=orp))
                    else:
                        # During calibration, the sensor is put into
                        # continuous mode, which causes a return of several
                        # values in one string. If the return value does
                        # not represent a float value, it is likely to be a
                        # string of several values. This parses and returns
                        # the first value.
                        if str_is_float(lines[0].split(b'\r')[0]):
                            orp = lines[0].split(b'\r')[0]
                        # Lastly, this is called if the return value cannot
                        # be determined. Watchthe output in the GUI to see
                        # what it is.
                        else:
                            orp = lines[0]
                            self.logger.error(
                                'Value[0] is not float or "check probe": '
                                '{val}'.format(val=orp))
            else:
                self.logger.error('UART device is not set up.'
                                  'Check the log for errors.')

        # Read sensor via I2C
        elif self.interface == 'I2C':
            if self.atlas_sensor_i2c.setup:
                ec_status, ec_str = self.atlas_sensor_i2c.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)
            else:
                self.logger.error(
                    'I2C device is not set up. Check the log for errors.')

        self.value_set(0, orp)

        return self.return_dict
Beispiel #32
0
    def get_measurement(self):
        """ Gets the sensor's Electrical Conductivity measurement via UART/I2C """
        return_string = None
        self.return_dict = measurements_dict.copy()

        # Read sensor via FTDI
        if self.interface == 'FTDI':
            if self.atlas_sensor.setup:
                lines = self.atlas_sensor.query('R')
                if lines:
                    self.logger.debug("All Lines: {lines}".format(lines=lines))

                    # 'check probe' indicates an error reading the sensor
                    if 'check probe' in lines:
                        self.logger.error('"check probe" returned from sensor')
                    # if a string resembling a float value is returned, this
                    # is out measurement value
                    elif str_is_float(lines[0]):
                        return_string = lines[0]
                        self.logger.debug('Value[0] is float: {val}'.format(
                            val=return_string))
                    else:
                        # During calibration, the sensor is put into
                        # continuous mode, which causes a return of several
                        # values in one string. If the return value does
                        # not represent a float value, it is likely to be a
                        # string of several values. This parses and returns
                        # the first value.
                        if str_is_float(lines[0].split(b'\r')[0]):
                            return_string = lines[0].split(b'\r')[0]
                        # Lastly, this is called if the return value cannot
                        # be determined. Watchthe output in the GUI to see
                        # what it is.
                        else:
                            return_string = lines[0]
                            self.logger.error(
                                'Value[0] is not float or "check probe": '
                                '{val}'.format(val=return_string))
            else:
                self.logger.error('FTDI device is not set up.'
                                  'Check the log for errors.')

        # Read sensor via UART
        elif self.interface == 'UART':
            if self.atlas_sensor.setup:
                lines = self.atlas_sensor.query('R')
                if lines:
                    self.logger.debug("All Lines: {lines}".format(lines=lines))

                    # 'check probe' indicates an error reading the sensor
                    if 'check probe' in lines:
                        self.logger.error('"check probe" returned from sensor')
                    # if a string resembling a float value is returned, this
                    # is out measurement value
                    elif str_is_float(lines[0]):
                        return_string = lines[0]
                        self.logger.debug('Value[0] is float: {val}'.format(
                            val=return_string))
                    else:
                        # During calibration, the sensor is put into
                        # continuous mode, which causes a return of several
                        # values in one string. If the return value does
                        # not represent a float value, it is likely to be a
                        # string of several values. This parses and returns
                        # the first value.
                        if str_is_float(lines[0].split(b'\r')[0]):
                            return_string = lines[0].split(b'\r')[0]
                        # Lastly, this is called if the return value cannot
                        # be determined. Watchthe output in the GUI to see
                        # what it is.
                        else:
                            return_string = lines[0]
                            self.logger.error(
                                'Value[0] is not float or "check probe": '
                                '{val}'.format(val=return_string))
            else:
                self.logger.error('UART device is not set up.'
                                  'Check the log for errors.')

        # Read sensor via I2C
        elif self.interface == 'I2C':
            if self.atlas_sensor.setup:
                ec_status, return_string = self.atlas_sensor.query('R')
                if ec_status == 'error':
                    self.logger.error("Sensor read unsuccessful: {err}".format(
                        err=return_string))
                elif ec_status == 'success':
                    self.logger.debug('Value: {val}'.format(val=return_string))
            else:
                self.logger.error(
                    'I2C device is not set up. Check the log for errors.')

        # Parse return string
        if ',' in return_string:
            index_place = 0
            return_list = return_string.split(',')
            if self.enabled_rgb:
                if self.is_enabled(0):
                    self.value_set(0, int(return_list[index_place + 0]))
                if self.is_enabled(1):
                    self.value_set(1, int(return_list[index_place + 1]))
                if self.is_enabled(2):
                    self.value_set(2, int(return_list[index_place + 2]))
                index_place += 3
            if return_list[index_place] == 'P':
                if self.is_enabled(7):
                    self.value_set(7, int(return_list[index_place + 1]))
                index_place += 2
            if return_list[index_place] == 'Lux':
                if self.is_enabled(6):
                    self.value_set(6, int(return_list[index_place + 1]))
                index_place += 2
            if return_list[index_place] == 'xyY':
                if self.is_enabled(3):
                    self.value_set(3, float(return_list[index_place + 1]))
                if self.is_enabled(4):
                    self.value_set(4, float(return_list[index_place + 2]))
                if self.is_enabled(5):
                    self.value_set(5, int(return_list[index_place + 3]))

        return self.return_dict
Beispiel #33
0
def input_mod(form_mod, request_form):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['modify']['title'],
        controller=TRANSLATIONS['input']['title'])
    error = []

    dict_inputs = parse_input_information()

    try:
        mod_input = Input.query.filter(
            Input.unique_id == form_mod.input_id.data).first()

        if mod_input.is_activated:
            error.append(
                gettext("Deactivate controller before modifying its settings"))

        if (mod_input.device == 'AM2315' and form_mod.period.data < 7):
            error.append(
                gettext("Choose a Read Period equal to or greater than 7. The "
                        "AM2315 may become unresponsive if the period is "
                        "below 7."))

        if (mod_input.device != 'EDGE' and
            (mod_input.pre_output_duration
             and form_mod.period.data < mod_input.pre_output_duration)):
            error.append(
                gettext("The Read Period cannot be less than the Pre Output "
                        "Duration"))

        if (form_mod.uart_location.data
                and not os.path.exists(form_mod.uart_location.data)):
            error.append(
                gettext(
                    "Invalid device or improper permissions to read device"))

        if ('gpio_location' in dict_inputs[mod_input.device]['options_enabled']
                and form_mod.gpio_location.data is None):
            error.append(gettext("Pin (GPIO) must be set"))

        mod_input.name = form_mod.name.data

        if form_mod.location.data:
            mod_input.location = form_mod.location.data
        if form_mod.i2c_location.data:
            mod_input.i2c_location = form_mod.i2c_location.data
        if form_mod.ftdi_location.data:
            mod_input.ftdi_location = form_mod.ftdi_location.data
        if form_mod.uart_location.data:
            mod_input.uart_location = form_mod.uart_location.data
        if form_mod.gpio_location.data and form_mod.gpio_location.data is not None:
            mod_input.gpio_location = form_mod.gpio_location.data

        if form_mod.power_output_id.data:
            mod_input.power_output_id = form_mod.power_output_id.data
        else:
            mod_input.power_output_id = None

        if form_mod.pre_output_id.data:
            mod_input.pre_output_id = form_mod.pre_output_id.data
        else:
            mod_input.pre_output_id = None

        # Enable/disable Channels
        measurements = DeviceMeasurements.query.filter(
            DeviceMeasurements.device_id == form_mod.input_id.data).all()
        if form_mod.measurements_enabled.data:
            for each_measurement in measurements:
                if each_measurement.unique_id in form_mod.measurements_enabled.data:
                    each_measurement.is_enabled = True
                else:
                    each_measurement.is_enabled = False

        mod_input.log_level_debug = form_mod.log_level_debug.data
        mod_input.i2c_bus = form_mod.i2c_bus.data
        mod_input.baud_rate = form_mod.baud_rate.data
        mod_input.pre_output_duration = form_mod.pre_output_duration.data
        mod_input.pre_output_during_measure = form_mod.pre_output_during_measure.data

        if form_mod.period.data:
            mod_input.period = form_mod.period.data

        mod_input.resolution = form_mod.resolution.data
        mod_input.resolution_2 = form_mod.resolution_2.data
        mod_input.sensitivity = form_mod.sensitivity.data
        mod_input.calibrate_sensor_measure = form_mod.calibrate_sensor_measure.data
        mod_input.cmd_command = form_mod.cmd_command.data
        mod_input.thermocouple_type = form_mod.thermocouple_type.data
        mod_input.ref_ohm = form_mod.ref_ohm.data
        # Serial options
        mod_input.pin_clock = form_mod.pin_clock.data
        mod_input.pin_cs = form_mod.pin_cs.data
        mod_input.pin_mosi = form_mod.pin_mosi.data
        mod_input.pin_miso = form_mod.pin_miso.data
        # Bluetooth options
        mod_input.bt_adapter = form_mod.bt_adapter.data

        mod_input.adc_gain = form_mod.adc_gain.data
        mod_input.adc_resolution = form_mod.adc_resolution.data
        mod_input.adc_sample_speed = form_mod.adc_sample_speed.data

        # Switch options
        mod_input.switch_edge = form_mod.switch_edge.data
        mod_input.switch_bouncetime = form_mod.switch_bouncetime.data
        mod_input.switch_reset_period = form_mod.switch_reset_period.data
        # PWM and RPM options
        mod_input.weighting = form_mod.weighting.data
        mod_input.rpm_pulses_per_rev = form_mod.rpm_pulses_per_rev.data
        mod_input.sample_time = form_mod.sample_time.data
        # Server options
        mod_input.port = form_mod.port.data
        mod_input.times_check = form_mod.times_check.data
        mod_input.deadline = form_mod.deadline.data
        # SHT sensor options
        if form_mod.sht_voltage.data:
            mod_input.sht_voltage = form_mod.sht_voltage.data

        if 'test_before_saving' in dict_inputs[mod_input.device]:
            (constraints_pass, constraints_errors,
             mod_input) = dict_inputs[mod_input.device]['test_before_saving'](
                 mod_input, request_form)
            if constraints_pass:
                pass
            elif constraints_errors:
                for each_error in constraints_errors:
                    flash(each_error, 'error')

        # Custom options
        list_options = []
        if 'custom_options' in dict_inputs[mod_input.device]:
            for each_option in dict_inputs[mod_input.device]['custom_options']:
                null_value = True
                for key in request_form.keys():
                    if each_option['id'] == key:
                        constraints_pass = True
                        constraints_errors = []
                        value = None
                        if each_option['type'] == 'float':
                            if str_is_float(request_form.get(key)):
                                if 'constraints_pass' in each_option:
                                    (constraints_pass, constraints_errors,
                                     mod_input
                                     ) = each_option['constraints_pass'](
                                         mod_input,
                                         float(request_form.get(key)))
                                if constraints_pass:
                                    value = float(request_form.get(key))
                            else:
                                error.append(
                                    "{name} must represent a float/decimal value "
                                    "(submitted '{value}')".format(
                                        name=each_option['name'],
                                        value=request_form.get(key)))

                        elif each_option['type'] == 'integer':
                            if is_int(request_form.get(key)):
                                if 'constraints_pass' in each_option:
                                    (constraints_pass, constraints_errors,
                                     mod_input
                                     ) = each_option['constraints_pass'](
                                         mod_input, int(request_form.get(key)))
                                if constraints_pass:
                                    value = int(request_form.get(key))
                            else:
                                error.append(
                                    "{name} must represent an integer value "
                                    "(submitted '{value}')".format(
                                        name=each_option['name'],
                                        value=request_form.get(key)))

                        elif each_option['type'] in ['text', 'select']:
                            if 'constraints_pass' in each_option:
                                (constraints_pass, constraints_errors,
                                 mod_input) = each_option['constraints_pass'](
                                     mod_input, request_form.get(key))
                            if constraints_pass:
                                value = request_form.get(key)

                        elif each_option['type'] == 'bool':
                            value = bool(request_form.get(key))

                        for each_error in constraints_errors:
                            error.append("Error: {name}: {error}".format(
                                name=each_option['name'], error=each_error))

                        if value is not None:
                            null_value = False
                            option = '{id},{value}'.format(id=key, value=value)
                            list_options.append(option)

                if null_value:
                    option = '{id},'.format(id=each_option['id'])
                    list_options.append(option)

        mod_input.custom_options = ';'.join(list_options)

        if not error:
            # Add or delete channels for variable measurement Inputs
            if ('measurements_variable_amount' in dict_inputs[mod_input.device]
                    and dict_inputs[
                        mod_input.device]['measurements_variable_amount']):
                channels = DeviceMeasurements.query.filter(
                    DeviceMeasurements.device_id == form_mod.input_id.data)

                if channels.count() != form_mod.num_channels.data:
                    # Delete channels
                    if form_mod.num_channels.data < channels.count():
                        for index, each_channel in enumerate(channels.all()):
                            if index + 1 >= channels.count():
                                delete_entry_with_id(DeviceMeasurements,
                                                     each_channel.unique_id)

                    # Add channels
                    elif form_mod.num_channels.data > channels.count():
                        start_number = channels.count()
                        for index in range(start_number,
                                           form_mod.num_channels.data):
                            new_measurement = DeviceMeasurements()
                            new_measurement.name = ""
                            new_measurement.device_id = mod_input.unique_id
                            new_measurement.measurement = ""
                            new_measurement.unit = ""
                            new_measurement.channel = index
                            new_measurement.save()

            db.session.commit()

    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_data'))
Beispiel #34
0
def input_mod(form_mod, request_form):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['modify']['title'],
        controller=TRANSLATIONS['input']['title'])
    error = []

    dict_inputs = parse_input_information()

    try:
        mod_input = Input.query.filter(
            Input.unique_id == form_mod.input_id.data).first()

        if mod_input.is_activated:
            error.append(gettext(
                "Deactivate controller before modifying its settings"))

        if (mod_input.device == 'AM2315' and
                form_mod.period.data < 7):
            error.append(gettext(
                "Choose a Read Period equal to or greater than 7. The "
                "AM2315 may become unresponsive if the period is "
                "below 7."))

        if (mod_input.device != 'EDGE' and
                (mod_input.pre_output_duration and
                 form_mod.period.data < mod_input.pre_output_duration)):
            error.append(gettext(
                "The Read Period cannot be less than the Pre Output "
                "Duration"))

        if (form_mod.uart_location.data and
                not os.path.exists(form_mod.uart_location.data)):
            error.append(gettext(
                "Invalid device or improper permissions to read device"))

        mod_input.name = form_mod.name.data

        if form_mod.location.data:
            mod_input.location = form_mod.location.data
        if form_mod.i2c_location.data:
            mod_input.i2c_location = form_mod.i2c_location.data
        if form_mod.ftdi_location.data:
            mod_input.ftdi_location = form_mod.ftdi_location.data
        if form_mod.uart_location.data:
            mod_input.uart_location = form_mod.uart_location.data
        if form_mod.gpio_location.data:
            mod_input.gpio_location = form_mod.gpio_location.data

        if form_mod.power_output_id.data:
            mod_input.power_output_id = form_mod.power_output_id.data
        else:
            mod_input.power_output_id = None

        if form_mod.pre_output_id.data:
            mod_input.pre_output_id = form_mod.pre_output_id.data
        else:
            mod_input.pre_output_id = None

        # Enable/disable Channels
        measurements = DeviceMeasurements.query.filter(
            DeviceMeasurements.device_id == form_mod.input_id.data).all()
        if form_mod.measurements_enabled.data:
            for each_measurement in measurements:
                if each_measurement.unique_id in form_mod.measurements_enabled.data:
                    each_measurement.is_enabled = True
                else:
                    each_measurement.is_enabled = False

        mod_input.i2c_bus = form_mod.i2c_bus.data
        mod_input.baud_rate = form_mod.baud_rate.data
        mod_input.pre_output_duration = form_mod.pre_output_duration.data
        mod_input.pre_output_during_measure = form_mod.pre_output_during_measure.data
        mod_input.period = form_mod.period.data
        mod_input.resolution = form_mod.resolution.data
        mod_input.resolution_2 = form_mod.resolution_2.data
        mod_input.sensitivity = form_mod.sensitivity.data
        mod_input.calibrate_sensor_measure = form_mod.calibrate_sensor_measure.data
        mod_input.cmd_command = form_mod.cmd_command.data
        mod_input.thermocouple_type = form_mod.thermocouple_type.data
        mod_input.ref_ohm = form_mod.ref_ohm.data
        # Serial options
        mod_input.pin_clock = form_mod.pin_clock.data
        mod_input.pin_cs = form_mod.pin_cs.data
        mod_input.pin_mosi = form_mod.pin_mosi.data
        mod_input.pin_miso = form_mod.pin_miso.data
        # Bluetooth options
        mod_input.bt_adapter = form_mod.bt_adapter.data

        mod_input.adc_gain = form_mod.adc_gain.data
        mod_input.adc_resolution = form_mod.adc_resolution.data
        mod_input.adc_sample_speed = form_mod.adc_sample_speed.data

        # Switch options
        mod_input.switch_edge = form_mod.switch_edge.data
        mod_input.switch_bouncetime = form_mod.switch_bouncetime.data
        mod_input.switch_reset_period = form_mod.switch_reset_period.data
        # PWM and RPM options
        mod_input.weighting = form_mod.weighting.data
        mod_input.rpm_pulses_per_rev = form_mod.rpm_pulses_per_rev.data
        mod_input.sample_time = form_mod.sample_time.data
        # Server options
        mod_input.port = form_mod.port.data
        mod_input.times_check = form_mod.times_check.data
        mod_input.deadline = form_mod.deadline.data
        # SHT sensor options
        if form_mod.sht_voltage.data:
            mod_input.sht_voltage = form_mod.sht_voltage.data

        # Custom options
        list_options = []
        if 'custom_options' in dict_inputs[mod_input.device]:
            for each_option in dict_inputs[mod_input.device]['custom_options']:
                null_value = True
                for key in request_form.keys():
                    if each_option['id'] == key:
                        constraints_pass = True
                        constraints_errors = []
                        value = None
                        if each_option['type'] == 'float':
                            if str_is_float(request_form.get(key)):
                                if 'constraints_pass' in each_option:
                                    (constraints_pass,
                                     constraints_errors,
                                     mod_input) = each_option['constraints_pass'](
                                        mod_input, float(request_form.get(key)))
                                if constraints_pass:
                                    value = float(request_form.get(key))
                            else:
                                error.append(
                                    "{name} must represent a float/decimal value "
                                    "(submitted '{value}')".format(
                                        name=each_option['name'],
                                        value=request_form.get(key)))

                        elif each_option['type'] == 'integer':
                            if is_int(request_form.get(key)):
                                if 'constraints_pass' in each_option:
                                    (constraints_pass,
                                     constraints_errors,
                                     mod_input) = each_option['constraints_pass'](
                                        mod_input, int(request_form.get(key)))
                                if constraints_pass:
                                    value = int(request_form.get(key))
                            else:
                                error.append(
                                    "{name} must represent an integer value "
                                    "(submitted '{value}')".format(
                                        name=each_option['name'],
                                        value=request_form.get(key)))

                        elif each_option['type'] in ['text', 'select']:
                            if 'constraints_pass' in each_option:
                                (constraints_pass,
                                 constraints_errors,
                                 mod_input) = each_option['constraints_pass'](
                                    mod_input, request_form.get(key))
                            if constraints_pass:
                                value = request_form.get(key)

                        elif each_option['type'] == 'bool':
                            value = bool(request_form.get(key))

                        for each_error in constraints_errors:
                            error.append(
                                "Error: {name}: {error}".format(
                                    name=each_option['name'],
                                    error=each_error))

                        if value:
                            null_value = False
                            option = '{id},{value}'.format(
                                id=key,
                                value=value)
                            list_options.append(option)

                if null_value:
                    option = '{id},'.format(id=each_option['id'])
                    list_options.append(option)

        mod_input.custom_options = ';'.join(list_options)

        if not error:
            db.session.commit()

    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_data'))
Beispiel #35
0
def action_mod(form):
    """Modify a Conditional Action"""
    error = []
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['modify']['title'],
        controller='{} {}'.format(TRANSLATIONS['conditional']['title'], TRANSLATIONS['actions']['title']))

    error = check_form_actions(form, error)

    try:
        mod_action = Actions.query.filter(
            Actions.unique_id == form.function_action_id.data).first()

        if mod_action.action_type == 'pause_actions':
            mod_action.pause_duration = form.pause_duration.data

        elif mod_action.action_type == 'output':
            mod_action.do_unique_id = form.do_unique_id.data
            mod_action.do_output_state = form.do_output_state.data
            mod_action.do_output_duration = form.do_output_duration.data

        elif mod_action.action_type == 'output_pwm':
            mod_action.do_unique_id = form.do_unique_id.data
            mod_action.do_output_pwm = form.do_output_pwm.data

        elif mod_action.action_type in ['activate_controller',
                                        'deactivate_controller']:
            mod_action.do_unique_id = form.do_unique_id.data

        elif mod_action.action_type in ['activate_pid',
                                        'deactivate_pid',
                                        'resume_pid',
                                        'pause_pid']:
            mod_action.do_unique_id = form.do_unique_id.data

        elif mod_action.action_type in ['activate_timer',
                                        'deactivate_timer']:
            mod_action.do_unique_id = form.do_unique_id.data

        elif mod_action.action_type == 'setpoint_pid':
            if not str_is_float(form.do_action_string.data):
                error.append("Setpoint must be an integer or float value")
            mod_action.do_unique_id = form.do_unique_id.data
            mod_action.do_action_string = form.do_action_string.data

        elif mod_action.action_type == 'method_pid':
            mod_action.do_unique_id = form.do_unique_id.data
            mod_action.do_action_string = form.do_action_string.data

        elif mod_action.action_type == 'email':
            mod_action.do_action_string = form.do_action_string.data

        elif mod_action.action_type in ['photo_email',
                                        'video_email']:
            mod_action.do_action_string = form.do_action_string.data
            mod_action.do_unique_id = form.do_unique_id.data
            mod_action.do_camera_duration = form.do_camera_duration.data

        elif mod_action.action_type in ['flash_lcd_on',
                                        'flash_lcd_off',
                                        'lcd_backlight_off',
                                        'lcd_backlight_on']:
            mod_action.do_unique_id = form.do_unique_id.data

        elif mod_action.action_type == 'photo':
            mod_action.do_unique_id = form.do_unique_id.data

        elif mod_action.action_type == 'video':
            mod_action.do_unique_id = form.do_unique_id.data
            mod_action.do_camera_duration = form.do_camera_duration.data

        elif mod_action.action_type in ['command', 'create_note']:
            mod_action.do_action_string = form.do_action_string.data

        if not error:
            db.session.commit()

    except sqlalchemy.exc.OperationalError as except_msg:
        error.append(except_msg)
    except sqlalchemy.exc.IntegrityError as except_msg:
        error.append(except_msg)
    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_function'))
Beispiel #36
0
    def get_measurement(self):
        """ Gets the Atlas PT1000's temperature in Celsius """
        temp = None

        return_dict = measurements_dict.copy()

        if self.interface == 'FTDI':
            if self.atlas_sensor_ftdi.setup:
                lines = self.atlas_sensor_ftdi.query('R')
                self.logger.debug("All Lines: {lines}".format(lines=lines))

                if 'check probe' in lines:
                    self.logger.error('"check probe" returned from sensor')
                elif isinstance(lines, list):
                    if str_is_float(lines[0]):
                        temp = float(lines[0])
                        self.logger.debug(
                            'Value[0] is float: {val}'.format(val=temp))
                elif str_is_float(lines):
                    temp = float(lines)
                    self.logger.debug(
                        'Value is float: {val}'.format(val=temp))
                else:
                    self.logger.error(
                        'Unknown value: {val}'.format(val=lines))
            else:
                self.logger.error('FTDI device is not set up. '
                                  'Check the log for errors.')

        elif self.interface == 'UART':
            if self.atlas_sensor_uart.setup:
                lines = self.atlas_sensor_uart.query('R')
                self.logger.debug("All Lines: {lines}".format(lines=lines))

                if 'check probe' in lines:
                    self.logger.error('"check probe" returned from sensor')
                elif str_is_float(lines[0]):
                    temp = float(lines[0])
                    self.logger.debug(
                        'Value[0] is float: {val}'.format(val=temp))
                else:
                    self.logger.error(
                        'Value[0] is not float or "check probe": '
                        '{val}'.format(val=lines[0]))
            else:
                self.logger.error('UART device is not set up. '
                                  'Check the log for errors.')

        elif self.interface == 'I2C':
            if self.atlas_sensor_i2c.setup:
                temp_status, temp_str = self.atlas_sensor_i2c.query('R')
                if temp_status == 'error':
                    self.logger.error(
                        "Sensor read unsuccessful: {err}".format(
                            err=temp_str))
                elif temp_status == 'success':
                    temp = float(temp_str)
            else:
                self.logger.error('I2C device is not set up.'
                                  'Check the log for errors.')

        return_dict[0]['value'] = temp

        return return_dict
Beispiel #37
0
def last_data(unique_id, measure_type, measurement_id, period):
    """Return the most recent time and value from influxdb"""
    if not str_is_float(period):
        return '', 204

    if measure_type in ['input', 'math', 'output', 'pid']:
        current_app.config['INFLUXDB_USER'] = INFLUXDB_USER
        current_app.config['INFLUXDB_PASSWORD'] = INFLUXDB_PASSWORD
        current_app.config['INFLUXDB_DATABASE'] = INFLUXDB_DATABASE
        current_app.config['INFLUXDB_TIMEOUT'] = 5
        dbcon = influx_db.connection

        if measure_type in ['input', 'math', 'pid']:
            measure = DeviceMeasurements.query.filter(
                DeviceMeasurements.unique_id == measurement_id).first()
        elif measure_type == 'output':
            measure = Output.query.filter(
                Output.unique_id == unique_id).first()
        else:
            return '', 204

        if measure:
            conversion = Conversion.query.filter(
                Conversion.unique_id == measure.conversion_id).first()
        else:
            conversion = None

        channel, unit, measurement = return_measurement_info(
            measure, conversion)

        if hasattr(measure, 'measurement_type') and measure.measurement_type == 'setpoint':
            setpoint_pid = PID.query.filter(PID.unique_id == measure.device_id).first()
            if setpoint_pid and ',' in setpoint_pid.measurement:
                pid_measurement = setpoint_pid.measurement.split(',')[1]
                setpoint_measurement = DeviceMeasurements.query.filter(
                    DeviceMeasurements.unique_id == pid_measurement).first()
                if setpoint_measurement:
                    conversion = Conversion.query.filter(
                        Conversion.unique_id == setpoint_measurement.conversion_id).first()
                    _, unit, measurement = return_measurement_info(setpoint_measurement, conversion)

        try:
            if period != '0':
                query_str = query_string(
                    unit, unique_id,
                    measure=measurement, channel=channel,
                    value='LAST', past_sec=period)
            else:
                query_str = query_string(
                    unit, unique_id,
                    measure=measurement, channel=channel,
                    value='LAST')
            if query_str == 1:
                return '', 204
            raw_data = dbcon.query(query_str).raw
            number = len(raw_data['series'][0]['values'])
            time_raw = raw_data['series'][0]['values'][number - 1][0]
            value = raw_data['series'][0]['values'][number - 1][1]
            value = float(value)
            # Convert date-time to epoch (potential bottleneck for data)
            dt = date_parse(time_raw)
            timestamp = calendar.timegm(dt.timetuple()) * 1000
            live_data = '[{},{}]'.format(timestamp, value)
            return Response(live_data, mimetype='text/json')
        except KeyError:
            logger.debug("No Data returned form influxdb")
            return '', 204
        except Exception as e:
            logger.exception("URL for 'last_data' raised and error: "
                             "{err}".format(err=e))
            return '', 204
Beispiel #38
0
def past_data(unique_id, measure_type, measurement_id, past_seconds):
    """Return data from past_seconds until present from influxdb"""
    if not str_is_float(past_seconds):
        return '', 204

    if measure_type == 'tag':
        notes_list = []

        tag = NoteTags.query.filter(NoteTags.unique_id == unique_id).first()
        notes = Notes.query.filter(
            Notes.date_time >= (datetime.datetime.utcnow() - datetime.timedelta(seconds=int(past_seconds)))).all()

        for each_note in notes:
            if tag.unique_id in each_note.tags.split(','):
                notes_list.append(
                    [each_note.date_time.strftime("%Y-%m-%dT%H:%M:%S.000000000Z"), each_note.name, each_note.note])

        if notes_list:
            return jsonify(notes_list)
        else:
            return '', 204

    elif measure_type in ['input', 'math', 'output', 'pid']:
        current_app.config['INFLUXDB_USER'] = INFLUXDB_USER
        current_app.config['INFLUXDB_PASSWORD'] = INFLUXDB_PASSWORD
        current_app.config['INFLUXDB_DATABASE'] = INFLUXDB_DATABASE
        current_app.config['INFLUXDB_TIMEOUT'] = 5
        dbcon = influx_db.connection

        if measure_type in ['input', 'math', 'pid']:
            measure = DeviceMeasurements.query.filter(
                DeviceMeasurements.unique_id == measurement_id).first()
        elif measure_type == 'output':
            measure = Output.query.filter(
                Output.unique_id == unique_id).first()
        else:
            measure = None

        if not measure:
            return "Could not find measurement"

        if measure:
            conversion = Conversion.query.filter(
                Conversion.unique_id == measure.conversion_id).first()
        else:
            conversion = None

        channel, unit, measurement = return_measurement_info(
            measure, conversion)

        if hasattr(measure, 'measurement_type') and measure.measurement_type == 'setpoint':
            setpoint_pid = PID.query.filter(PID.unique_id == measure.device_id).first()
            if setpoint_pid and ',' in setpoint_pid.measurement:
                pid_measurement = setpoint_pid.measurement.split(',')[1]
                setpoint_measurement = DeviceMeasurements.query.filter(
                    DeviceMeasurements.unique_id == pid_measurement).first()
                if setpoint_measurement:
                    conversion = Conversion.query.filter(
                        Conversion.unique_id == setpoint_measurement.conversion_id).first()
                    _, unit, measurement = return_measurement_info(setpoint_measurement, conversion)

        try:
            query_str = query_string(
                unit, unique_id,
                measure=measurement,
                channel=channel,
                past_sec=past_seconds)

            if query_str == 1:
                return '', 204

            raw_data = dbcon.query(query_str).raw

            if 'series' in raw_data:
                return jsonify(raw_data['series'][0]['values'])
            else:
                return '', 204
        except Exception as e:
            logger.debug("URL for 'past_data' raised and error: "
                         "{err}".format(err=e))
            return '', 204