def get_serial_number(self): """return the serial number string of the spectrometer Returns ------- serial_number: str """ try: protocol = self._transport.protocol if protocol is None: raise AttributeError("transport not opened") elif isinstance(protocol, OOIProtocol): # The serial is stored in slot 0 # noinspection PyUnresolvedReferences return self.f.eeprom.eeprom_read_slot(0) elif isinstance(protocol, OBPProtocol): return protocol.query(0x00000100).decode("utf8") else: raise NotImplementedError( "No serial number for protocol class {}".format( protocol.__class__.__name__)) except AttributeError: raise SeaBreezeError("device not open")
def set_integration_time_micros(self, integration_time_micros): t_min = self._integration_time_min t_max = self._integration_time_max if t_min <= integration_time_micros < t_max: i_time = int(integration_time_micros / self._integration_time_base) self.protocol.send(0x02, i_time) else: raise SeaBreezeError("Integration not in [{:d}, {:d}]".format(t_min, t_max))
def __init__(self, protocol, feature_id, **kwargs): """SeaBreezeFeature base class Parameters ---------- protocol : Type[seabreeze.pyseabreeze.protocol.ProtocolInterface} feature_id : int """ if self.identifier == "base_feature": raise SeaBreezeError( "Don't instantiate SeaBreezeFeature directly. Use derived feature classes." ) assert set(self._required_kwargs) == set(kwargs), "{} vs {}".format( str(set(self._required_kwargs)), str(set(kwargs))) # check protocol support if not isinstance(protocol, self._required_protocol_cls): raise SeaBreezeError( "FeatureError: Protocol not supported by feature") self.protocol = weakref.proxy(protocol) self.feature_id = feature_id
def _func_eeprom_read_slot(protocol, slot_number, strip_zero_bytes=False, raw=False): protocol.send(0x05, slot_number) ret = protocol.receive(size=17, mode='low_speed') if ret[0] != 0x05 or ret[1] != int(slot_number) % 0xFF: raise SeaBreezeError('read_eeprom_slot_raw: wrong answer: "%s"' % ret) if raw: return ret data = ret[2:ret[2:].index(0) + 2].tostring().decode('utf-8') if not strip_zero_bytes: return data return data.rstrip('\x00')
def _check_incoming_message_header(self, header): """check the incoming message header Parameters ---------- header : `str` a obp header of length 44 Returns ------- bytes_and_checksum_type : tuple[`int`, `int`] bytes_remaining after the header (returns 20 for a 64 byte message) checksum_type only supports self.OBP.CHECKSUM_TYPE_MD5 for now """ if len(header) != 44: raise SeaBreezeError("header has wrong length! len(header): %d" % len(header)) data = struct.unpack(self.OBP.HEADER_FMT, header) if data[0] != self.OBP.HEADER_START_BYTES: raise SeaBreezeError('Header start_bytes wrong: "%d"' % data[0]) if data[1] != self.OBP.HEADER_PROTOCOL_VERSION: raise SeaBreezeError("Header protocol version wrong: %d" % data[1]) flags = data[2] if flags == 0: pass if flags & self.OBP.FLAG_RESPONSE_TO_REQUEST: pass # TODO: propagate? if flags & self.OBP.FLAG_ACK: pass # TODO: propagate? if flags & self.OBP.FLAG_REQUEST_ACK: pass # TODO: only the host should be able to set this? if (flags & self.OBP.FLAG_NACK) or (flags & self.OBP.FLAG_HW_EXCEPTION): error = data[3] if error != 0: # != SUCCESS raise SeaBreezeError(self.OBP.ERROR_CODES[error]) else: pass # TODO: should we do something here? if flags & self.OBP.FLAG_PROTOCOL_DEPRECATED: raise SeaBreezeError("Protocol deprecated?!?") # msg_type = data[4] # regarding = data[5] checksum_type = data[7] # TODO: implement checksums. if checksum_type not in [ self.OBP.CHECKSUM_TYPE_NONE, self.OBP.CHECKSUM_TYPE_MD5, ]: raise SeaBreezeError('the checksum type is unknown: "%d"' % checksum_type) # immediate_length = data[8] # immediate_data = data[9] bytes_remaining = data[10] return bytes_remaining, checksum_type
def __new__(cls, raw_device=None): if raw_device is None: raise SeaBreezeError( "Don't instantiate SeaBreezeDevice directly. Use `SeabreezeAPI.list_devices()`." ) for transport in {USBTransport}: supported_model = transport.supported_model(raw_device) if supported_model is not None: break else: raise TypeError("No transport supports device.") specialized_cls = _model_class_registry[supported_model] return super(SeaBreezeDevice, cls).__new__(specialized_cls)
def _extract_message_data(self, msg): """extract the payload data from a obp message Parameters ---------- msg : `str` a obp message Returns ------- data : `str` the payload contained in the message """ payload_length = len(msg) - 44 - 20 # - HeaderLength - FooterLength if not (payload_length >= 0): raise SeaBreezeError("Received message < 64 bytes: %d" % payload_length) payload_fmt = "%ds" % payload_length FMT = self.OBP.HEADER_FMT + payload_fmt + self.OBP.FOOTER_FMT data = struct.unpack(FMT, msg) msg_type = data[4] immediate_length = data[8] immediate_data = data[9] payload = data[11] if (immediate_length > 0) and len(payload) > 0: raise SeaBreezeError("Got immediate AND payload data? cmd: '%d'" % msg_type) elif immediate_length > 0: return immediate_data[:immediate_length] elif payload_length > 0: return payload else: return b""
def receive(self, size=None, timeout_ms=None, **kwargs): """receive data from the spectrometer Parameters ---------- size : int, optional number of bytes to receive. if `None` (default) uses the default size as specified in the transport layer. timeout_ms : int, optional the timeout after which the transport layer should error. `None` means no timeout (default) kwargs : ignored and only present to provide compatible caller interfaces Returns ------- data : str data returned from the spectrometer """ response = self.transport.read(size=64, timeout_ms=timeout_ms) try: remaining_bytes, checksum_type = self._check_incoming_message_header( response[:44]) except SeaBreezeError: # empty buffer if error raised self.transport.read(size=None, timeout_ms=500) raise length_payload_footer = remaining_bytes # we already received some data remaining_bytes -= len(response[44:]) if remaining_bytes > 0: response += self.transport.read(size=remaining_bytes, timeout_ms=timeout_ms) if length_payload_footer != len(response[44:]): raise SeaBreezeError( "remaining packet length mismatch: {:d} != {:d}".format( remaining_bytes, len(response[44:]))) checksum = self._check_incoming_message_footer(response[-20:]) if (checksum_type == self.OBP.CHECKSUM_TYPE_MD5 and checksum != hashlib.md5(response[:-20]).digest()): warnings.warn( "WARNING OBP: The checksums differ, but we ignore this for now." ) return self._extract_message_data(response)
def __init__(self, raw_device=None): if raw_device is None: raise SeaBreezeError( "Don't instantiate SeaBreezeDevice directly. Use `SeabreezeAPI.list_devices()`." ) self._raw_device = raw_device for transport in self._transport_classes: if transport.supported_model(self._raw_device) is not None: self._transport = transport() break else: raise TypeError("No transport supports device.") try: self._serial_number = self.get_serial_number() except SeaBreezeError: pass
def _func_eeprom_read_slot( protocol, slot_number, strip_zero_bytes=False, raw=False ): protocol.send(0x05, slot_number) ret = protocol.receive(size=17, mode="low_speed") if ret[0] != 0x05 or ret[1] != int(slot_number) % 0xFF: raise SeaBreezeError('read_eeprom_slot_raw: wrong answer: "%s"' % ret) if raw: return ret try: data = ret[2 : ret[2:].index(0) + 2].tobytes().decode("utf-8") except AttributeError: # Python27 data = ret[2 : ret[2:].index(0) + 2].tostring().decode("utf-8") if not strip_zero_bytes: return data return data.rstrip("\x00")
def __init__(self, raw_device=None): if raw_device is None: raise SeaBreezeError( "Don't instantiate SeaBreezeDevice directly. Use `SeabreezeAPI.list_devices()`." ) self._raw_device = raw_device for transport in self._transport_classes: if transport.supported_model(self._raw_device) is not None: self._transport = transport() break else: raise TypeError("No transport supports device.") try: # sneakily switch in the correct subclass in case it's needed self.__class__ = self.__class__._substitute_compatible_subclass( self._transport ) except AttributeError: pass try: self._serial_number = self.get_serial_number() except SeaBreezeError: pass
def set_trigger_mode(self, mode): if mode in self._trigger_modes: self.protocol.send(0x0A, mode) else: raise SeaBreezeError("Only supports: %s" % str(self._trigger_modes))
def set_trigger_mode(self, mode): if mode in self._trigger_modes: self.protocol.send(0x00110110, mode, request_ack=False) else: raise SeaBreezeError("Only supports: %s" % str(self._trigger_modes))