def send_command(self, address, command, data=None): """Sends a command to the sensor's address specified. The command can optionally contain a data string. This method is mostly for internal use, as the higher-level API is exposed via dedicated methods. Parameters ---------- address : :obj:`int` PosCon3D sensors have an address assigned, which defaults to 1. There's also a broadcast address (``PosCon3D.BROADCAST_ADDRESS``) that can be used to query the address of the sensor connected to the RS-485 bus. Only one sensor can be in the bus when using the broadcast address to query for sensor's address. command : :obj:`string` A string indicating the command number to be executed. data : :obj:`string` An optional string of data that is sent together with the command. Returns ------- `list` or value Result of the command. It can be a list or a single value depending on the operation. """ cmd = self.format_command(address, command, data) # Python 2 vs 3 if hasattr(cmd, 'decode'): self.serial.write(cmd) result = self.serial.readline() else: self.serial.write(cmd.encode('ascii')) result = self.serial.readline().decode('ascii') if result: frame_head = result[:-4] checksum = result[-4:-1] expected = self.calculate_checksum(frame_head) if expected != checksum: raise ProtocolError( 'Invalid response, checksum mismatch. Expected=%s, Got=%s' % (expected, checksum)) expected_frame_head = self.FRAME_HEAD % (address, command, '') if not result.startswith(expected_frame_head): raise ProtocolError( 'Invalid response, command/address mismatch. Expected to start with="%s", Got="%s"' % (expected_frame_head, result)) return self.get_payload(result) return None
def set_measurement_type(self, measurement_type): """Defines the measurement type to use. =================== ====== Measurement type Value =================== ====== "Diameter" 28 "X-Center position" 29 "Z-Center position" 30 "X-Left position" 31 "X-Right position" 32 "Z-Top position" 33 =================== ====== Parameters ---------- measurement_type : :obj:`string` Measurement type. """ if measurement_type not in self.MEASUREMENT_TYPES: raise ProtocolError('Unsupported measure type, must be one of ' + str(self.MEASUREMENT_TYPES)) return self.send_command(self.address, 'W020', str(self.MEASUREMENT_TYPES[measurement_type]))
def set_measurement_type(self, measurement_type): """Defines the measurement type to use. =================== =========== ====== Measurement type Function Value =================== =========== ====== "Edge L rise" Edge 0 "Edge L fall" Edge 1 "Edge R rise" Edge 2 "Edge R fall" Edge 3 "Width" Width 4 "Center width" Width 5 "Gap" Gap 6 "Center gap" Gap 7 =================== =========== ====== Parameters ---------- measurement_type : :obj:`string` Measurement type. """ if measurement_type not in self.MEASUREMENT_TYPES: raise ProtocolError('Unsupported measure type, must be one of ' + str(self.MEASUREMENT_TYPES)) return self.send_command( self.address, '020', str(self.MEASUREMENT_TYPES.index(measurement_type)))
def set_measurement_type(self, measurement_type): """Defines the measurement type to use. ================ ======== Measurement type Function ================ ======== "Edge L rise" Edge "Edge L fall" Edge "Edge R rise" Edge "Edge R fall" Edge "Width" Width "Center width" Width "Gap" Gap "Center gap" Gap ================ ======== Args: measurement_type (:obj:`string`): Measurement type. """ if measurement_type not in self.MEASUREMENT_TYPES: raise ProtocolError('Unsupported measure type, must be one of ' + str(self.MEASUREMENT_TYPES)) return self.send_command( self.address, '020', str(self.MEASUREMENT_TYPES.index(measurement_type)))
def get_payload(self, result): """Gets payload.""" frame_head = result[:-6] result_type = frame_head[3] if result_type == 'a': raise SensorTimeoutError('Sensor has not completed reading') if result_type == 'E': error_index = frame_head.split(';') raise ProtocolError('Application error, Result=%s' % frame_head + 'Error type: ' + str(self.ERROR_CODES[str(error_index[1])])) if result_type == 'B': raise ProtocolError('Sensor is busy, Result=%s' % frame_head) return result[5:-6].split(';')
def get_measurement(self): """Retrieves the current measurement of the sensor according to the current settings. Returns: tuple: The current measurement and additionally a value indicating the quality of the measured value. """ result = self.send_command(self.address, '031') if len(result) != 2: raise ProtocolError('Unexpected result: ' + str(result)) return (result[0], self.QUALITY[int(result[1])])
def get_payload(result): data = result.split(',')[2:-1] if not data: return None elif len(data) == 1: return data[0] else: if data[0] == 'E': raise ProtocolError(ERROR_CODES[int(data[1])]) return data
def get_payload(self, result): """Gets payload.""" data = result.split(',')[2:-1] if not data: return None elif len(data) == 1: return data[0] else: if data[0] == 'E': raise ProtocolError(self.ERROR_CODES[str(data[1])]) return data
def get_live_monitor_data(self): """Retrieves the distance to the surface in the center of the laser beam and the angle at which it's found. Returns: list: angle and distance to the reference surface. .. note:: This function is designed to aid in the installation of the sensor at an angle. """ result = self.send_command(self.address, '093') if len(result) != 2: raise ProtocolError('Unexpected result: ' + str(result)) return map(float, result)
def set_precision(self, precision): """Defines the precision the sensor will use to determine edges: ===== ========= =============== Value Precision Function values ===== ========= =============== ``0`` Standard Median=off, Moving Average=off ``1`` High Median=7, Moving Average=16 ``2`` Very High Median=15, Moving Average=128 ===== ========= =============== Args: precision (:obj:`int`): Sensor precision to use. .. note:: The higher the precision, the slower the measurement gets. """ if precision < 0 or precision > 2: raise ProtocolError('Precision must be 0 (standard), 1 (high) or 2 (very high)') return self.send_command(self.address, '040', str(precision))
def get_measurement(self): """Retrieves the current measurement of the sensor according to the current settings. Returns ------- `tuple` The current measurement and additionally a value indicating the quality of the measured value. """ result = self.send_command(self.address, 'R021') if len(result) != 3: raise ProtocolError('Unexpected result: ' + str(result)) value = result[0] quality = int(result[1]) # If Valid if quality == 0: value = float(value) return (value, self.QUALITY[quality])