Something like this would work
class Cascade12000b(object):
"""A Cascade12000b driver.
:param connection: A connection object, used to communicate with the real device.
The connection interface should conform to the following interface.
It must have two methods:
* `.write()` taking a string message
* `.ask()` taking a string message, returning a string response
:param int id: The device id
"""
def __init__(self, connection, id=2):
self.connection = connection
self.id = int(id)
def position(self):
"""Returns a tuple `(x,y,z)` with the position coordinates."""
response = self.connection.ask(':MOV:ABS? {0:d}'.format(self.id))
# assuming whitespace separated response
return tuple(int(x) for x in reponse.split())
def move_absolute(self, x, y, z=None):
"""Sets the position in absolute coordinates."""
if z is None:
_, _, z = self.position()
self.connection.write(':MOV:ABS {0:d} {1:d} {2:d} {3:d}'.format(self.id, x, y, z)
def move_relative(self, dx, dy, dz=0):
"""Sets the position in relative coordinates."""
self.connection.write(':MOV:REL {0:d} {1:d} {2:d} {3:d}'.format(self.id, dx, dy, dz)
You would use it like this
# Injecting the connection has the advantage that you can change the implementation, e.g. # to linux-gpib
>>>connection = visa.instrument('GPIB::28')
>>>device = Cascade12000b(connection)
>>>device.move_absolute(10, 13, 20)
>>>device.position()
10, 13, 20
>>>device.move_relative(2,2)
>>>device.position()
12,15,20
If you have to write more than one device driver, you might want to look at some python packages like slave (Note: I'm the author of slave) or lantz.