@@ -18,136 +18,159 @@ class XBee(XBeeBase):
1818 Commands may be sent to a device by instansiating this class with
1919 a serial port object (see PySerial) and then calling the send
2020 method with the proper information specified by the API. Data may
21- be read from a device syncronously by calling wait_read_frame. For
21+ be read from a device synchronously by calling wait_read_frame. For
2222 asynchronous reads, see the definition of XBeeBase.
2323 """
2424 # Packets which can be sent to an XBee
25-
25+
2626 # Format:
27- # {name of command:
28- # [{name:field name, len:field length, default: default value sent}
29- # ...
30- # ]
31- # ...
32- # }
33- api_commands = {"at" :
34- [{'name' :'id' , 'len' :1 , 'default' :b'\x08 ' },
35- {'name' :'frame_id' , 'len' :1 , 'default' :b'\x00 ' },
36- {'name' :'command' , 'len' :2 , 'default' :None },
37- {'name' :'parameter' , 'len' :None , 'default' :None }],
38- "queued_at" :
39- [{'name' :'id' , 'len' :1 , 'default' :b'\x09 ' },
40- {'name' :'frame_id' , 'len' :1 , 'default' :b'\x00 ' },
41- {'name' :'command' , 'len' :2 , 'default' :None },
42- {'name' :'parameter' , 'len' :None , 'default' :None }],
43- "remote_at" :
44- [{'name' :'id' , 'len' :1 , 'default' :b'\x17 ' },
45- {'name' :'frame_id' , 'len' :1 , 'default' :b'\x00 ' },
46- # dest_addr_long is 8 bytes (64 bits), so use an unsigned long long
47- {'name' :'dest_addr_long' , 'len' :8 , 'default' :struct .pack ('>Q' , 0 )},
48- {'name' :'dest_addr' , 'len' :2 , 'default' :b'\xFF \xFE ' },
49- {'name' :'options' , 'len' :1 , 'default' :b'\x02 ' },
50- {'name' :'command' , 'len' :2 , 'default' :None },
51- {'name' :'parameter' , 'len' :None , 'default' :None }],
52- "tx_long_addr" :
53- [{'name' :'id' , 'len' :1 , 'default' :b'\x00 ' },
54- {'name' :'frame_id' , 'len' :1 , 'default' :b'\x00 ' },
55- {'name' :'dest_addr' , 'len' :8 , 'default' :None },
56- {'name' :'options' , 'len' :1 , 'default' :b'\x00 ' },
57- {'name' :'data' , 'len' :None , 'default' :None }],
58- "tx" :
59- [{'name' :'id' , 'len' :1 , 'default' :b'\x01 ' },
60- {'name' :'frame_id' , 'len' :1 , 'default' :b'\x00 ' },
61- {'name' :'dest_addr' , 'len' :2 , 'default' :None },
62- {'name' :'options' , 'len' :1 , 'default' :b'\x00 ' },
63- {'name' :'data' , 'len' :None , 'default' :None }]
64- }
27+ # {
28+ # name of command: [
29+ # {name: field name, len: field length, default: default value sent}
30+ # ...
31+ # ]
32+ # ...
33+ # }
34+ api_commands = {
35+ "at" : [
36+ {'name' : 'id' , 'len' : 1 , 'default' : b'\x08 ' },
37+ {'name' : 'frame_id' , 'len' : 1 , 'default' : b'\x00 ' },
38+ {'name' : 'command' , 'len' : 2 , 'default' : None },
39+ {'name' : 'parameter' , 'len' : None , 'default' : None }
40+ ],
41+ "queued_at" : [
42+ {'name' : 'id' , 'len' : 1 , 'default' : b'\x09 ' },
43+ {'name' : 'frame_id' , 'len' : 1 , 'default' : b'\x00 ' },
44+ {'name' : 'command' , 'len' : 2 , 'default' : None },
45+ {'name' : 'parameter' , 'len' : None , 'default' : None }
46+ ],
47+ "remote_at" : [
48+ {'name' : 'id' , 'len' : 1 , 'default' : b'\x17 ' },
49+ {'name' : 'frame_id' , 'len' : 1 , 'default' : b'\x00 ' },
50+ # dest_addr_long is 8 bytes (64 bits), so use an unsigned long
51+ {'name' : 'dest_addr_long' , 'len' : 8 , 'default' : struct .pack ('>Q' , 0 )},
52+ {'name' : 'dest_addr' , 'len' : 2 , 'default' : b'\xFF \xFE ' },
53+ {'name' : 'options' , 'len' : 1 , 'default' : b'\x02 ' },
54+ {'name' : 'command' , 'len' : 2 , 'default' : None },
55+ {'name' : 'parameter' , 'len' : None , 'default' : None }
56+ ],
57+ "tx_long_addr" : [
58+ {'name' : 'id' , 'len' : 1 , 'default' : b'\x00 ' },
59+ {'name' : 'frame_id' , 'len' : 1 , 'default' : b'\x00 ' },
60+ {'name' : 'dest_addr' , 'len' : 8 , 'default' : None },
61+ {'name' : 'options' , 'len' : 1 , 'default' : b'\x00 ' },
62+ {'name' : 'data' , 'len' : None , 'default' : None }
63+ ],
64+ "tx" : [
65+ {'name' : 'id' , 'len' : 1 , 'default' : b'\x01 ' },
66+ {'name' : 'frame_id' , 'len' : 1 , 'default' : b'\x00 ' },
67+ {'name' : 'dest_addr' , 'len' : 2 , 'default' : None },
68+ {'name' : 'options' , 'len' : 1 , 'default' : b'\x00 ' },
69+ {'name' : 'data' , 'len' : None , 'default' : None }
70+ ]
71+ }
6572
6673 # Packets which can be received from an XBee
67-
68- # Format:
69- # {id byte received from XBee:
70- # {name: name of response
71- # structure:
72- # [ {'name': name of field, 'len':length of field}
73- # ...
74- # ]
75- # parsing: [(name of field to parse,
76- # function which accepts an xbee object and the
77- # partially-parsed dictionary of data received
78- # and returns bytes to replace the
79- # field to parse's data with
80- # )]},
81- # }
82- # ...
83- # }
84- #
85- api_responses = {b"\x80 " :
86- {'name' :'rx_long_addr' ,
87- 'structure' :
88- [{'name' :'source_addr' , 'len' :8 },
89- {'name' :'rssi' , 'len' :1 },
90- {'name' :'options' , 'len' :1 },
91- {'name' :'rf_data' , 'len' :None }]},
92- b"\x81 " :
93- {'name' :'rx' ,
94- 'structure' :
95- [{'name' :'source_addr' , 'len' :2 },
96- {'name' :'rssi' , 'len' :1 },
97- {'name' :'options' , 'len' :1 },
98- {'name' :'rf_data' , 'len' :None }]},
99- b"\x82 " :
100- {'name' :'rx_io_data_long_addr' ,
101- 'structure' :
102- [{'name' :'source_addr_long' ,'len' :8 },
103- {'name' :'rssi' , 'len' :1 },
104- {'name' :'options' , 'len' :1 },
105- {'name' :'samples' , 'len' :None }],
106- 'parsing' : [('samples' ,
107- lambda xbee ,original : xbee ._parse_samples (original ['samples' ])
108- )]},
109- b"\x83 " :
110- {'name' :'rx_io_data' ,
111- 'structure' :
112- [{'name' :'source_addr' , 'len' :2 },
113- {'name' :'rssi' , 'len' :1 },
114- {'name' :'options' , 'len' :1 },
115- {'name' :'samples' , 'len' :None }],
116- 'parsing' : [('samples' ,
117- lambda xbee ,original : xbee ._parse_samples (original ['samples' ])
118- )]},
119- b"\x89 " :
120- {'name' :'tx_status' ,
121- 'structure' :
122- [{'name' :'frame_id' , 'len' :1 },
123- {'name' :'status' , 'len' :1 }]},
124- b"\x8a " :
125- {'name' :'status' ,
126- 'structure' :
127- [{'name' :'status' , 'len' :1 }]},
128- b"\x88 " :
129- {'name' :'at_response' ,
130- 'structure' :
131- [{'name' :'frame_id' , 'len' :1 },
132- {'name' :'command' , 'len' :2 },
133- {'name' :'status' , 'len' :1 },
134- {'name' :'parameter' , 'len' :None }],
135- 'parsing' : [('parameter' ,
136- lambda xbee ,original : xbee ._parse_IS_at_response (original ))]
137- },
138- b"\x97 " :
139- {'name' :'remote_at_response' ,
140- 'structure' :
141- [{'name' :'frame_id' , 'len' :1 },
142- {'name' :'source_addr_long' ,'len' :8 },
143- {'name' :'source_addr' , 'len' :2 },
144- {'name' :'command' , 'len' :2 },
145- {'name' :'status' , 'len' :1 },
146- {'name' :'parameter' , 'len' :None }],
147- 'parsing' : [('parameter' ,
148- lambda xbee ,original : xbee ._parse_IS_at_response (original ))]
149- },
150- }
74+
75+ # Format:
76+ # {
77+ # id byte received from XBee: {
78+ # name: name of response
79+ # structure: [
80+ # {'name': name of field, 'len': length of field}
81+ # ...
82+ # ],
83+ # parsing: [(name of field to parse,
84+ # function which accepts an xbee object and the
85+ # partially-parsed dictionary of data received
86+ # and returns bytes to replace the field to
87+ # parse's data with.
88+ # )],
89+ # }
90+ # ...
91+ # }
92+ api_responses = {
93+ b'\x80 ' : {
94+ 'name' : 'rx_long_addr' ,
95+ 'structure' : [
96+ {'name' : 'source_addr' , 'len' : 8 },
97+ {'name' : 'rssi' , 'len' : 1 },
98+ {'name' : 'options' , 'len' : 1 },
99+ {'name' : 'rf_data' , 'len' : None }
100+ ]
101+ },
102+ b'\x81 ' : {
103+ 'name' : 'rx' ,
104+ 'structure' : [
105+ {'name' : 'source_addr' , 'len' : 2 },
106+ {'name' : 'rssi' , 'len' : 1 },
107+ {'name' : 'options' , 'len' : 1 },
108+ {'name' : 'rf_data' , 'len' : None }
109+ ]
110+ },
111+ b'\x82 ' : {
112+ 'name' : 'rx_io_data_long_addr' ,
113+ 'structure' : [
114+ {'name' : 'source_addr_long' , 'len' : 8 },
115+ {'name' : 'rssi' , 'len' : 1 },
116+ {'name' : 'options' , 'len' : 1 },
117+ {'name' : 'samples' , 'len' : None }
118+ ],
119+ 'parsing' : [
120+ ('samples' , lambda xbee , original : xbee ._parse_samples (original ['samples' ]))
121+ ]
122+ },
123+ b'\x83 ' : {
124+ 'name' : 'rx_io_data' ,
125+ 'structure' : [
126+ {'name' : 'source_addr' , 'len' : 2 },
127+ {'name' : 'rssi' , 'len' : 1 },
128+ {'name' : 'options' , 'len' : 1 },
129+ {'name' : 'samples' , 'len' : None }
130+ ],
131+ 'parsing' : [
132+ ('samples' , lambda xbee , original : xbee ._parse_samples (original ['samples' ]))
133+ ]
134+ },
135+ b'\x89 ' : {
136+ 'name' : 'tx_status' ,
137+ 'structure' : [
138+ {'name' : 'frame_id' , 'len' : 1 },
139+ {'name' : 'status' , 'len' : 1 }
140+ ]
141+ },
142+ b'\x8A ' : {
143+ 'name' : 'status' ,
144+ 'structure' : [
145+ {'name' : 'status' , 'len' : 1 }
146+ ]
147+ },
148+ b'\x88 ' : {
149+ 'name' : 'at_response' ,
150+ 'structure' : [
151+ {'name' : 'frame_id' , 'len' : 1 },
152+ {'name' : 'command' , 'len' : 2 },
153+ {'name' : 'status' , 'len' : 1 },
154+ {'name' : 'parameter' , 'len' : None }
155+ ],
156+ 'parsing' : [
157+ ('parameter' , lambda xbee , original : xbee ._parse_IS_at_response (original ))
158+ ]
159+ },
160+ b'\x97 ' : {
161+ 'name' : 'remote_at_response' ,
162+ 'structure' : [
163+ {'name' : 'frame_id' , 'len' : 1 },
164+ {'name' : 'source_addr_long' , 'len' : 8 },
165+ {'name' : 'source_addr' , 'len' : 2 },
166+ {'name' : 'command' , 'len' : 2 },
167+ {'name' : 'status' , 'len' : 1 },
168+ {'name' : 'parameter' , 'len' : None }],
169+ 'parsing' : [
170+ ('parameter' , lambda xbee , original : xbee ._parse_IS_at_response (original ))
171+ ]
172+ }
173+ }
151174
152175 def _parse_IS_at_response (self , packet_info ):
153176 """
@@ -160,5 +183,7 @@ def _parse_IS_at_response(self, packet_info):
160183 return packet_info ['parameter' ]
161184
162185 def __init__ (self , * args , ** kwargs ):
163- # Call the super class constructor to save the serial port
186+ """
187+ Call the super class constructor to save the serial port
188+ """
164189 super (XBee , self ).__init__ (* args , ** kwargs )
0 commit comments