Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/nxt_plugin/nxt/locator.py
diff options
context:
space:
mode:
Diffstat (limited to 'nxt_plugin/nxt/locator.py')
-rw-r--r--nxt_plugin/nxt/locator.py177
1 files changed, 177 insertions, 0 deletions
diff --git a/nxt_plugin/nxt/locator.py b/nxt_plugin/nxt/locator.py
new file mode 100644
index 0000000..46b5ec8
--- /dev/null
+++ b/nxt_plugin/nxt/locator.py
@@ -0,0 +1,177 @@
+# nxt.locator module -- Locate LEGO Minstorms NXT bricks via USB or Bluetooth
+# Copyright (C) 2006, 2007 Douglas P Lau
+# Copyright (C) 2009 Marcus Wanner
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+import traceback, ConfigParser, os
+
+class BrickNotFoundError(Exception):
+ pass
+
+class NoBackendError(Exception):
+ pass
+
+class Method():
+ """Used to indicate which comm backends should be tried by find_bricks/
+find_one_brick. Any or all can be selected."""
+ def __init__(self, usb=True, bluetooth=True, fantomusb=False, fantombt=False):
+ #new method options MUST default to False!
+ self.usb = usb
+ self.bluetooth = bluetooth
+ self.fantom = fantomusb or fantombt
+ self.fantomusb = fantomusb
+ self.fantombt = fantombt
+
+def find_bricks(host=None, name=None, silent=False, method=Method()):
+ """Used by find_one_brick to look for bricks ***ADVANCED USERS ONLY***"""
+ methods_available = 0
+
+ if method.usb:
+ try:
+ import usbsock
+ methods_available += 1
+ socks = usbsock.find_bricks(host, name)
+ for s in socks:
+ yield s
+ except ImportError:
+ import sys
+ if not silent: print >>sys.stderr, "USB module unavailable, not searching there"
+
+ if method.bluetooth:
+ try:
+ import bluesock
+ methods_available += 1
+ try:
+ socks = bluesock.find_bricks(host, name)
+ for s in socks:
+ yield s
+ except (bluesock.bluetooth.BluetoothError, IOError): #for cases such as no adapter, bluetooth throws IOError, not BluetoothError
+ pass
+ except ImportError:
+ import sys
+ if not silent: print >>sys.stderr, "Bluetooth module unavailable, not searching there"
+
+ if method.fantom:
+ try:
+ import fantomsock
+ methods_available += 1
+ if method.fantomusb:
+ usbsocks = fantomsock.find_bricks(host, name, False)
+ for s in usbsocks:
+ yield s
+ if method.fantombt:
+ btsocks = fantomsock.find_bricks(host, name, True)
+ for s in btsocks:
+ yield s
+ except ImportError:
+ import sys
+ if not silent: print >>sys.stderr, "Fantom module unavailable, not searching there"
+
+ if methods_available == 0:
+ raise NoBackendError("No selected backends are available! Did you install the comm modules?")
+
+
+def find_one_brick(host=None, name=None, silent=False, strict=None, debug=False, method=None, confpath=None):
+ """Use to find one brick. The host and name args limit the search to
+a given MAC or brick name. Set silent to True to stop nxt-python from
+printing anything during the search. This function by default
+automatically checks to see if the brick found has the correct host/name
+(if either are provided) and will not return a brick which doesn't
+match. This can be disabled (so the function returns any brick which can
+be connected to and provides a valid reply to get_device_info()) by
+passing strict=False. This will, however, still tell the comm backends
+to only look for devices which match the args provided. The confpath arg
+specifies the location of the configuration file which brick location
+information will be read from if no brick location directives (host,
+name, strict, or method) are provided."""
+ if debug and silent:
+ silent=False
+ print "silent and debug can't both be set; giving debug priority"
+
+ conf = read_config(confpath, debug)
+ if not (host or name or strict or method):
+ host = conf.get('Brick', 'host')
+ name = conf.get('Brick', 'name')
+ strict = bool(int(conf.get('Brick', 'strict')))
+ method = eval('Method(%s)' % conf.get('Brick', 'method'))
+ if not strict: strict = True
+ if not method: method = Method()
+ if debug:
+ print "Host: %s Name: %s Strict: %s" % (host, name, str(strict))
+ print "USB: %s BT: %s Fantom: %s FUSB: %s FBT: %s" % (method.usb, method.bluetooth, method.fantom, method.fantombt, method.fantomusb)
+
+ for s in find_bricks(host, name, silent, method):
+ try:
+ if host and 'host' in dir(s) and s.host != host:
+ if debug:
+ print "Warning: the brick found does not match the host provided (s.host)."
+ if strict: continue
+ b = s.connect()
+ info = b.get_device_info()
+ if host and info[1] != host:
+ if debug:
+ print "Warning: the brick found does not match the host provided (get_device_info)."
+ if strict:
+ s.close()
+ continue
+ if name and info[0].strip('\0') != name:
+ if debug:
+ print "Warning; the brick found does not match the name provided."
+ if strict:
+ s.close()
+ continue
+ return b
+ except:
+ if debug:
+ traceback.print_exc()
+ print "Failed to connect to possible brick"
+ #raise BrickNotFoundError
+
+
+def server_brick(host, port = 2727):
+ import ipsock
+ sock = ipsock.IpSock(host, port)
+ return sock.connect()
+
+
+def read_config(confpath=None, debug=False):
+ conf = ConfigParser.RawConfigParser({'host': None, 'name': None, 'strict': True, 'method': ''})
+ if not confpath: confpath = os.path.expanduser('~/.nxt-python')
+ if conf.read([confpath]) == [] and debug:
+ print "Warning: Config file (should be at %s) was not read. Use nxt.locator.make_config() to create a config file." % confpath
+ if conf.has_section('Brick') == False:
+ conf.add_section('Brick')
+ return conf
+
+def make_config(confpath=None):
+ conf = ConfigParser.RawConfigParser()
+ if not confpath: confpath = os.path.expanduser('~/.nxt-python')
+ print "Welcome to the nxt-python config file generator!"
+ print "This function creates an example file which find_one_brick uses to find a brick."
+ try:
+ if os.path.exists(confpath): raw_input("File already exists at %s. Press Enter to overwrite or Ctrl+C to abort." % confpath)
+ except KeyboardInterrupt:
+ print "Not writing file."
+ return
+ conf.add_section('Brick')
+ conf.set('Brick', 'name', 'MyNXT')
+ conf.set('Brick', 'host', '54:32:59:92:F9:39')
+ conf.set('Brick', 'strict', 0)
+ conf.set('Brick', 'method', 'usb=True, bluetooth=False, fantomusb=True')
+ conf.write(open(confpath, 'w'))
+ print "The file has been written at %s" % confpath
+ print "The file contains less-than-sane default values to get you started."
+ print "You must now edit the file with a text editor and change the values to match what you would pass to find_one_brick"
+ print "The fields for name, host, and strict correspond to the similar args accepted by find_one_brick"
+ print "The method field contains the string which would be passed to Method()"
+ print "Any field whose corresponding option does not need to be passed to find_one_brick should be commented out (using a # at the start of the line) or simply removed."
+ print "If you have questions, check the wiki and then ask on the mailing list."