From 3a2966f08eba8bc6a9fe63650b42c4f1a024fdfa Mon Sep 17 00:00:00 2001 From: Tat-Chee Wan (USM) Date: Tue, 8 Mar 2011 09:14:17 +0800 Subject: python fantom wrapper using ctypes --- PyFantom/pyfantom.py | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 PyFantom/pyfantom.py diff --git a/PyFantom/pyfantom.py b/PyFantom/pyfantom.py new file mode 100644 index 0000000..ba3eedd --- /dev/null +++ b/PyFantom/pyfantom.py @@ -0,0 +1,109 @@ +from ctypes import * +import ctypes.util +import platform + +# Check platform. +if platform.system() == 'Darwin': + import sys + if sys.maxsize > 2**32: + raise RuntimeError("fantom drivers not available in 64 bit mode.\n" + "You can run python in 32 bit mode using:\n" + "arch -i386 python2.6\n") + libpath = '/Library/Frameworks/Fantom.framework/Fantom' + #libpath = ctypes.util.find_library('Fantom') +else: + raise RuntimeError('unsupported platform') + +# Load library. +dll = cdll.LoadLibrary(libpath) +dll.nFANTOM100_createNXTIterator.argtypes = [c_ushort, c_uint, POINTER(c_int)] +dll.nFANTOM100_createNXTIterator.restype = c_uint +dll.nFANTOM100_destroyNXTIterator.argtypes = [c_int, POINTER(c_int)] +dll.nFANTOM100_destroyNXTIterator.restype = None +dll.nFANTOM100_iNXTIterator_advance.argtypes = [c_uint, POINTER(c_int)] +dll.nFANTOM100_iNXTIterator_advance.restype = None +dll.nFANTOM100_iNXTIterator_getNXT.argtypes = [c_uint, POINTER(c_int)] +dll.nFANTOM100_iNXTIterator_getNXT.restype = c_uint +dll.nFANTOM100_iNXTIterator_getName.argtypes = [c_uint, c_char_p, POINTER(c_int)] +dll.nFANTOM100_iNXTIterator_getName.restype = None + +# Status codes. +StatusOffset = -142000 +StatusNoMoreItemsFound = StatusOffset - 17 +StatusSuccess = 0 + +def check_status (status): + """Check status, raise on error.""" + if status.value < StatusSuccess: + raise FantomException('bad status') + +class FantomException(RuntimeError): + pass + +class NXTIterator: + """Interface to an iterator, to find connected NXT.""" + + def __init__(self, search_bluetooth, + bluetooth_search_timeout_in_seconds = 5): + """Initialize iterator.""" + self.search_bluetooth = search_bluetooth + self.bluetooth_search_timeout_in_seconds = \ + bluetooth_search_timeout_in_seconds + self.handle = None + self.stop = False + + def __iter__(self): + """Return the iterator object itself.""" + return self + + def next(self): + """Implement the iterator protocol.""" + if self.stop: + raise StopIteration() + # Find first, or find next. + status = c_int(0) + if self.handle is None: + handle = dll.nFANTOM100_createNXTIterator(self.search_bluetooth, + self.bluetooth_search_timeout_in_seconds, byref(status)) + else: + handle = self.handle + dll.nFANTOM100_iNXTIterator_advance(handle, byref(status)) + # Check result. + if status.value == StatusNoMoreItemsFound: + self.stop = True + raise StopIteration() + check_status (status) + self.handle = handle + # Return itself (not part of the protocol, but it has get_nxt and + # get_name). + return self + + def get_nxt(self): + """Get the NXT instance.""" + if self.handle is None or self.stop: + raise FantomException('invalid iterator') + status = c_int(0) + nxt = dll.nFANTOM100_iNXTIterator_getNXT(self.handle, byref(status)) + check_status (status) + # XXX + return nxt.value + + def get_name(self): + """Get the NXT resource name.""" + if self.handle is None or self.stop: + raise FantomException('invalid iterator') + status = c_int(0) + name = create_string_buffer (256) + dll.nFANTOM100_iNXTIterator_getName(self.handle, name, byref(status)) + check_status (status) + return name.value + + def __del__(self): + """Destroy iterator.""" + if self.handle is not None: + status = c_int(0) + dll.nFANTOM100_destroyNXTIterator(self.handle, byref(status)) + +if __name__ == '__main__': + for i in NXTIterator(False): + print i.get_name() -- cgit v1.2.3