Reputation: 1137
My script is monitoring changes to the state of my remote xbee. To do this I need to send the destination long address to the router which I get from the coordinator. It all works well if I explicitly type in the destination long address like this:
addr = '\x00\x13\xA2\x00@\n!\x1C'
xbee.remote_at(dest_addr_long=addr, command=mycommand, frame_id='\x01')
and it gives me the desired data output which is
{'status': '\x00', 'source_addr': '\x7fD', 'source_addr_long': '\x00\x13\xa2\x00@\n!\x1c', 'frame_id': '\x01', 'command': 'D0', 'parameter': '\x05', 'id': 'remote_at_response'}
from which I can read the parameter to determine the state of the xbee.
The problem I am having is that I don't know the addr up front. I get it when I run this command
mysourceaddrlong = repr(data['source_addr_long'])[1:-1]
addr = "\\".join([(i[0]+i[1:].upper()) for i in mysourceaddrlong.split('\\') if i])
addr = addr[1:] #remove the x in front
addr = r"\x"+addr #add \x to the front and save it as a raw string
print "Formatted addr: %s" % addr
Which outputs:
Formatted addr: \x00\x13\xA2\x00@\n!\x1C This formatted addr appears to me to be exactly the same, but it does not work when I run my at command like this:
xbee.remote_at(dest_addr_long=addr, command=mycommand, frame_id='\x01')
I get an error saying
ValueError: The data provided for 'dest_addr_long' was not 8 bytes long
I've included the entire script below:
#! /usr/bin/python
import serial
import time
from xbee import XBee
ser = serial.Serial('/dev/ttyUSB0', 9600)
xbee = XBee(ser)
def print_data(data):
print data
mycommand = data['command']
mysourceaddrlong = repr(data['source_addr_long'])[1:-1]
addr = "\\".join([(i[0]+i[1:].upper()) for i in mysourceaddrlong.split('\\') if i])
print "incorrectly formatted addr: %s" % addr
addr = addr[1:] #remove the x in front
addr = r"\x"+addr #add \x to the front and save it as a raw string
print "formatted addr: %s" % addr
try:
xbee.remote_at(dest_addr_long=addr, command=mycommand, frame_id='\x01')
response = xbee.wait_read_frame()
myhexparameter = response['parameter']
myparameter = ord (myhexparameter)
if myparameter == 4:
print "Which means pin %s is OFF" % mycommand
if myparameter == 5:
print "Which means pin %s is ON" % mycommand
except KeyboardInterrupt:
pass
xbee = XBee(ser, callback=print_data)
while True:
try:
time.sleep(0.001)
except KeyboardInterrupt:
break
xbee.halt()
ser.close()
Upvotes: 0
Views: 345
Reputation: 881745
formatted_addr
(my name for the addr
you compute in your second snippet) only appears to be the same as addr
(as you set it in the first snippet) because you're passing both through the wringer of __str__
(indirectly via print
) which strives for aesthetically nice output at the cost of possible ambiguity. Try instead:
print(repr(addr))
vs
print(repr(formatted_addr))
and you'll see the differences -- all those backslash characters are actually in the formatted_addr
string (and get doubled in repr
) while they aren't in addr
(they're only displayed as part of escape sequences).
I can't repro the issue myself as I don't have access to your setup, but I suspect
actual_addr = data['source_addr_long']
is actually what you want, without all the string processing gyrations around it. Try
print(repr(actual_addr))
and unless the problem is fixed tell us what exactly you see from these three print(repr(...))
and I bet it will be easy to fix any discrepancy that might remain.
Upvotes: 2