# HG changeset patch # User darius@inchoate.localdomain # Date 1193896836 -37800 # Node ID 9c499d92354440a7822299957a0fe95d161d9457 # Parent 5d5963d542bc095e600d1a5aeb078f0170262069 Many fixes. - Make AT_Cmd constructor smarter/useful. - Flesh out AT_Response, TX_*_Bit and TX_Status - Make writedata() and getdata() simpler to use (hold reference to serial port inside the class) diff -r 5d5963d542bc -r 9c499d923544 zb.py --- a/zb.py Wed Oct 31 20:47:32 2007 +1030 +++ b/zb.py Thu Nov 01 16:30:36 2007 +1030 @@ -22,27 +22,32 @@ def __init__(self, *args): if (len(args) == 1): - super(AT_Cmd, self).__init__(args[0]) + if (type(args[0]) == type(str())): + super(AT_Cmd, self).__init__([]) + self.cmd = args[0] + else: + super(AT_Cmd, self).__init__(args[0]) elif (len(args) == 2): super(AT_Cmd, self).__init__([]) self.cmd = args[0] - if (args[1] != None): - self.cmdarg = args[1] + self.cmdarg = args[1] else: - raise TypeError("__init__ takes 1 list of ordinals or 2 strings") + raise TypeError("__init__ takes 1 list of ordinals, 1 string, or 2 strings") + + self.data[0] = 1 # XXX: could be smarter about Frame ID def setcmd(self, value): - self.resize(2) - self.data[0] = ord(value[0]) - self.data[1] = ord(value[1]) - cmd = property(lambda s: chr(s.data[0]) + chr(s.data[1]), setcmd) + self.resize(3) + self.data[1] = ord(value[0]) + self.data[2] = ord(value[1]) + cmd = property(lambda s: chr(s.data[1]) + chr(s.data[2]), setcmd) def setcmdarg(self, value): - self.resize(2 + len(value)) - self.data = self.data[0:2] + map(ord, value) + self.resize(3 + len(value)) + self.data = self.data[0:3] + map(ord, value) def delcmdarg(self): - self.data = self.data[0:2] - cmdarg = property(lambda s: map(chr, s.data[2:]), setcmdarg, delcmdarg) + self.data = self.data[0:3] + cmdarg = property(lambda s: map(chr, s.data[3:]), setcmdarg, delcmdarg) class AT_Cmd_Queue(AT_Cmd): PKT_TYPE = 0x09 @@ -51,6 +56,10 @@ class AT_Response(PktBase): PKT_TYPE = 0x88 PKT_DESC = "AT Command response" + frameid = property(lambda s: s.data[0], None) + cmd = property(lambda s: chr(s.data[1]) + chr(s.data[2]), None) + statusOK = property(lambda s: s.data[3] == 0, None) + payload = property(lambda s: s.data[4:], None) class Modem_Status(PktBase): PKT_TYPE = 0x8a @@ -124,23 +133,59 @@ ADDR_SIZE = 8 class TX_16_Bit(RX_64_Bit): - PKT_TYPE = 0x00 + PKT_TYPE = 0x01 PKT_DESC = "TX Packet: 16 bit address" + ADDR_SIZE = 2 + + def __init__(self, *args): + if (len(args) == 1): + if (type(args[0]) == type(int())): + super(TX_16_Bit, self).__init__([]) + self.recipient = args[0] + else: + super(TX_16_Bit, self).__init__(args[0]) + elif (len(args) == 2): + super(TX_16_Bit, self).__init__([]) + self.recipient = args[0] + self.payload = args[1] + else: + raise TypeError("__init__ takes 1 list of ordinals or 2 strings") - def setsender(self, value): - self.resize(self.ADDR_SIZE) + self.resize(self.ADDR_SIZE + 2) + self.data[0] = 1 # XXX: could be smarter about Frame ID + self.data[3] = 0 # XXX: should be able to set flags + + def getrecipient(self): + value = 0 for i, j in zip(reversed(range(self.ADDR_SIZE)), range(0, self.ADDR_SIZE * 8, 8)): - self.data[i] = (value & (0xff << j)) >> j - sender = property(RX_64_Bit.getsender, setsender) + value |= self.data[i + 1] << j + return value + + def setrecipient(self, value): + self.resize(self.ADDR_SIZE + 1) + self.data[0] = 1 # XXX: could be smarter about Frame ID + for i, j in zip(reversed(range(self.ADDR_SIZE)), range(0, self.ADDR_SIZE * 8, 8)): + self.data[i + 1] = (value & (0xff << j)) >> j + recipient = property(getrecipient, setrecipient) -class TX_64_Bit(RX_64_Bit): + def setpayload(self, value): + self.resize(self.ADDR_SIZE + 2) + self.data[self.ADDR_SIZE + 2:] = value + payload = property(lambda s: s.data[self.ADDR_SIZE + 2:], setpayload) + +class TX_64_Bit(TX_16_Bit): PKT_TYPE = 0x00 PKT_DESC = "TX Packet: 64 bit address" + ADDR_SIZE = 8 class TX_Status(PktBase): PKT_TYPE = 0x89 PKT_DESC = "TX Status" - + statusTxt = ['OK', 'No Ack', 'CCA failure', 'Purged'] + frameid = property(lambda s: s.data[0], None) + status = property(lambda s: s.data[1], None) + statusMsg = property(lambda s: s.statusTxt[s.data[1]], None) + class Packets(object): PKT_CLASSES = None @@ -169,7 +214,7 @@ Encapsulate = staticmethod(Encapsulate) - def __init__(self): + def __init__(self, s): print str(inspect.getmodule(self)) self.buffer = [] self.state = 'init' @@ -183,14 +228,15 @@ self.rx_cnt = 0 # Packet count self.pktq = [] - - def writedata(self, s, data): - s.write("".join(map(str, data))) + self.s = s + + def writedata(self, data): + self.s.write("".join(map(str, data))) - def getdata(self, s): + def getdata(self): l = [] while (1): - a = s.read() + a = self.s.read() if (a == ''): break l.append(ord(a)) @@ -229,7 +275,7 @@ print "Checksum error, got 0x%02x, expected 0x%02x" % \ (rxcksum, 0xff - pktsum) else: - #print "Got a packet - " + str(self.buffer) + print "Got a packet - " + str(self.buffer) p = Packets.Build(self.buffer) self.pktq.append(p) self.buffer = [] @@ -264,7 +310,7 @@ # Exception badpkttypetest = [126, 0, 3, 10, 86, 76, 83] -up = Packets() +up = Packets(s) up.process(goodtest) up.process(badtest) up.process(adctest)