5 from pylibcerebrum
.ganglion
import Ganglion
6 from pylibcerebrum
.timeout_exception
import TimeoutException
8 class SerialMux(object):
10 def __init__(self
, device
=None, baudrate
=115200, ser
=None):
11 s
= ser
or LockableSerial(port
=device
, baudrate
=baudrate
, timeout
=1)
12 #Trust me, without the following two lines it *wont* *work*. Fuck serial ports.
19 def open(self
, node_id
):
20 """ Open a Ganglion by node ID """
21 return Ganglion(node_id
, ser
=self
.ser
)
23 def discover(self
, mask
=0, address
=0, found
=[]):
24 """ Discover all node IDs connected to the bus
26 Note: You do not need to set any of the arguments. These are used for the recursive discovery process.
28 for a
in [address
, 1<<mask | address
]:
29 if self
._send
_probe
(a
, 15-mask
):
31 self
.discover(mask
+1, a
, found
)
36 def _send_probe(self
, address
, mask
):
37 #print('Discovery: address', address, 'mask', mask)
39 s
.write(b
'\\#\xFF\xFF' + struct
.pack('>HH', address
, mask
))
40 timeout_tmp
= s
.timeout
44 s
.timeout
= timeout_tmp
46 except TimeoutException
:
47 s
.timeout
= timeout_tmp
53 class LockableSerial(serial
.Serial
):
54 def __init__(self
, *args
, **kwargs
):
55 super(serial
.Serial
, self
).__init
__(*args
, **kwargs
)
56 self
.lock
= threading
.RLock()
62 def __exit__(self
, *args
):
63 self
.lock
.__exit
__(*args
)
66 """Read n bytes from the serial device and raise a TimeoutException in case of a timeout."""
67 data
= serial
.Serial
.read(self
, n
)
69 raise TimeoutException('Read {} bytes trying to read {}'.format(len(data
), n
))