diff --git a/README.md b/README.md index aa95ee5..af0adb8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -#Thorpy +# Thorpy Python library implementing Thorlabs APT communication protocol diff --git a/setup.py b/setup.py index 6c6ad5b..8e61e68 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ setup(name="thorpy", version="0.0.0", description="", - packages = ['thorpy', 'thorpy.comm', 'thorpy.message', 'thorpy.stages'], + packages = ['thorpy', 'thorpy.comm', 'thorpy.message', 'thorpy.stages', 'thorpy.flipmount'], package_data = {'thorpy.stages': ['*.ini']}, include_package_data = True, zip_safe = True, diff --git a/thorpy/comm/discovery.py b/thorpy/comm/discovery.py index cafc998..414bec7 100644 --- a/thorpy/comm/discovery.py +++ b/thorpy/comm/discovery.py @@ -1,4 +1,4 @@ -def discover_stages(): +def discover_stages(serial_number): import usb import os from .port import Port @@ -9,28 +9,33 @@ def discover_stages(): for dev in usb.core.find(find_all=True, custom_match= lambda x: x.bDeviceClass != 9): try: + #FIXME: this avoids an error related to https://github.com/walac/pyusb/issues/139 #FIXME: this could maybe be solved in a better way? dev._langids = (1033, ) # KDC101 3-port is recognized as FTDI in newer kernels - if not (dev.manufacturer == 'Thorlabs' or dev.manufacturer == 'FTDI'): + #check if device is a thorlabs product excluding the thorlabs powermeter + if not (dev.manufacturer == 'Thorlabs' or dev.manufacturer == 'FTDI') or ('pm' in dev.product.lower()): continue except usb.core.USBError: continue + if str(dev.serial_number) == serial_number: + if platform.system() == 'Linux': + port_candidates = [x[0] for x in serial_ports if x[2].get('SER', None) == dev.serial_number] + else: + raise NotImplementedError("Implement for platform.system()=={0}".format(platform.system())) - if platform.system() == 'Linux': - port_candidates = [x[0] for x in serial_ports if x[2].get('SER', None) == dev.serial_number] - else: - raise NotImplementedError("Implement for platform.system()=={0}".format(platform.system())) - - assert len(port_candidates) == 1 - - port = port_candidates[0] + assert len(port_candidates) == 1 + + port = port_candidates[0] + + p = Port.create(port, dev.serial_number) + for stage in p.get_stages().values(): + return stage + + raise NotImplementedError("Device not found with serial number: " + serial_number) + return 0 - p = Port.create(port, dev.serial_number) - for stage in p.get_stages().values(): - yield stage - if __name__ == '__main__': print(list(discover_stages())) diff --git a/thorpy/comm/port.py b/thorpy/comm/port.py index a4c9508..d74a502 100644 --- a/thorpy/comm/port.py +++ b/thorpy/comm/port.py @@ -55,7 +55,9 @@ def __init__(self, port, sn): except: # TODO: Be more specific on what we catch here self._buffer = b'' self._serial.flushInput() - +# print(self._info_message['serial_number']) +# self._info_message.__serial_number = sn +# print(self._info_message) self._serial_number = int(sn) if self._serial_number is None: self._serial_number = self._info_message['serial_number'] @@ -244,7 +246,7 @@ def get_stages(self, only_chan_idents = None): ret = dict([(k, self._stages.get(k, None)) for k in only_chan_idents]) for k in only_chan_idents: if ret[k] is None: - ret[k] = GenericStage(self, 0x01, stage_name_from_get_hw_info(self._info_message)) + ret[k] = GenericStage(self, 0x01, stage_name_from_get_hw_info(self._info_message, self._serial_number)) self._stages[k] = ret[k] return ret diff --git a/thorpy/flipmount/flipmount.py b/thorpy/flipmount/flipmount.py new file mode 100644 index 0000000..15669ec --- /dev/null +++ b/thorpy/flipmount/flipmount.py @@ -0,0 +1,30 @@ +import thorpy.comm.discovery as thc + +class flipMount: + + def __init__(self, sn): + self.__stage = thc.discover_stages(sn) + + def identify(self): + self.__stage.identify() + + def open(self): + self.__stage.move_jog_forward() + + def close(self): + self.__stage.move_jog_backward() + + def is_open(self): + return self.__stage.status_forward_hardware_limit_switch_active + + def is_close(self): + return self.__stage.status_reverse_hardware_limit_switch_active + + def is_moving(self): + return self.__stage.status_in_motion_forward + + def flip(self): + if self.is_open(): + self.close() + else: + self.open() diff --git a/thorpy/stages/__init__.py b/thorpy/stages/__init__.py index fe212d0..41c21ef 100644 --- a/thorpy/stages/__init__.py +++ b/thorpy/stages/__init__.py @@ -10,8 +10,12 @@ def _print_stage_detection_improve_message(m): '- stage type\n' + \ '- this data: {0}'.format(m), file = sys.stderr) -def stage_name_from_get_hw_info(m): - controller_type = m['serial_number'] // 1000000 #v7 +def stage_name_from_get_hw_info(m, sn=None): + if sn is None: + controller_type = m['serial_number'] // 1000000 #v7 + else: + controller_type = int(sn) // 1000000 #v7 + stage_type = m['empty_space'][-2] #Reverse engineered hw_version = m['hw_version'] model_number = m['model_number'].decode('ascii').strip('\x00') @@ -164,7 +168,7 @@ def __init__(self, port, chan_ident, ini_section): self._port.send_message(MGMSG_MOD_SET_CHANENABLESTATE(chan_ident = self._chan_ident, chan_enable_state = 0x01)) - print("Constructed: {0!r}".format(self)) + print("Test: "+"Constructed: {0!r}".format(self)) #STATUSUPDATE self._state_position = None @@ -474,7 +478,18 @@ def _wait_for_properties(self, properties, timeout = None, message = None, messa def __repr__(self): return '<{0} on {1!r} channel {2}>'.format(self._name, self._port, self._chan_ident) - + + + def identify(self): + self._port.send_message(MGMSG_MOD_IDENTIFY()) + + def move_jog_forward(self): + self._port.send_message(MGMSG_MOT_MOVE_JOG(chan_ident = self._chan_ident, direction = 0x01)) + + def move_jog_backward(self): + self._port.send_message(MGMSG_MOT_MOVE_JOG(chan_ident = self._chan_ident, direction = 0x02)) + + #Message which should maybe be implemented? #Should be in port: MGMSG_HUB_REQ_BAYUSED, MGMSG_HUB_GET_BAYUSED,