Reputation: 1837
I can't get the python-xbee library to receive a response from my remote router. They're connected. The local Xbee is a Coordinator API, the remote is a Router AT.
It doesn't seem to be a connection issue because I can use XCTU to send and receive remote packets without a problem. I'm using Series 2 Xbees.
I added a class to help parse the serial responses. It prints out fine for local 'at' commands, but all 'remote_at' commands hang, with no response printed. I can issue a remote_at command (without waiting for a response) and it is processed correctly by the remote XBee. Issuing the remote command hangs at wait_read_frame(). I've tried waiting a few minutes, but it's just stuck.
I'm trying to query the D1 input pin and get its status back (high \x05
, low \x04
or off \x00
)
Here's the code I've been using to debug. What am I doing wrong?
from xbee import XBee
import time
from serial import Serial
PORT = '/dev/ttyAMA0'
myRouter = 'a big long hex string...'
def message_received(data):
print data
class TappedSerial(Serial):
def __init__(self, *args, **kwargs):
super(TappedSerial, self).__init__(*args, **kwargs)
def read(self, *args, **kwargs):
data = super(Serial, self).read(*args, **kwargs)
print ("read: ", repr(data))
return data
def write(self, data, **kwargs):
print("wrote: ", repr(data))
return super(Serial, self).write(data, **kwargs)
def main():
tapped_ser = TappedSerial(port=PORT, baudrate=9600)
xbee = XBee(tapped_ser) #, callback=message_received)
try:
xbee.remote_at(dest_addr_long=myRouter, command='D1', options='\x00')
response = xbee.wait_read_frame()
print(response)
except KeyboardInterrupt:
pass
finally:
tapped_ser.close()
print("exiting program")
if __name__ == '__main__':
main()
Upvotes: 1
Views: 1808
Reputation: 1165
Two things I noticed setting up the library:
In the version I checked out, in base.py line 74, the code to start the background thread if the callback was set is commented out. Since you got read requests, I don't think that's your issue, but keeping in in case anyone else gets here with a similar problem. You can call xbee.start() manually to make the thread run.
I found that enabling python logging was a bit more useful than the tappedSerial in this case - I enabled logging by adding the following at the top:
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
logger.addHandler(ch)
This revealed that I was adding 4 bytes to my ND responses because I had NO set to 3 instead of 0. I'll send a pull request that appends the DD value to parameters if it's defined, as determined by the length being off by 4.
Upvotes: 1
Reputation: 1837
Answer: You need to include a frame_id with the packet. From John Foster's XBee Cookbook:
Byte: frame id. This is an arbitrary value chosen by the host. The value will be returned in the response packet, except that a value of 0 will suppress the response packet.
Adding a frame_id to the packet gets a response back. Any arbitrary character (other than 0) works.
try:
xbee.remote_at(dest_addr_long=myRouter, command='D1', frame_id='A')
response = xbee.wait_read_frame()
print(response)
except KeyboardInterrupt:
pass
Upvotes: 0