Frank Hayward
Frank Hayward

Reputation: 1137

Manipulate strings in python

I need to control my xbee using data stored in mysql. Included in the database is the long address of the xbee that is used to identify which xbee I am communicating with on the network.

The following code works perfectly, but in this example I am not retrieving the address from the database. It is just an example of what does work.

addr3 = '\x00\x13\xa2\x00@\n!\x1c'
xbee.send('remote_at', 
                    frame_id='\x01',
                    dest_addr_long=addr3, #<- this works!
                    command='D0',
                    parameter='\x04')

Now as soon as I retrieve \x00\x13\xa2\x00@\n!\x1c from the database (it is stored as a varchar), I get an error saying: "% (field['name'], field['len'])) ValueError: The data provided for 'dest_addr_long' was not 8 bytes long"

Here is the code (I included the output of the six print lines below to help with debugging)

        with con: 
        cur = con.cursor()
        cur.execute("SELECT addrlong, pinStatus FROM deviceStatus WHERE addrlong <>''")
        for i in range(cur.rowcount):
            row = cur.fetchone()
            addr1 = row[0]
            Status = row[1]
            addr2 = repr(addr1)
            addr3 = '\x00\x13\xa2\x00@\n!\x1c' 
            print "Address1: %s" % addr1
            print "Address2: %s" % addr2
            print "Address3: %s" % addr3
            print "Size of Addr1: %s" % sys.getsizeof(addr1)
            print "Size of Addr2: %s" % sys.getsizeof(addr2)
            print "Size of Addr3: %s" % sys.getsizeof(addr3)
            if Status == 0: #turn off
                xbee.send('remote_at', 
                    frame_id='\x01',
                    dest_addr_long=addr2,  #<-problem is here
                    command='D0',
                    parameter='\x04')
            if Status == 1: #turn on
                xbee.send('remote_at', 
                    frame_id='\x01',
                    dest_addr_long=addr2, #<-problem is here
                    command='D0',
                    parameter='\x05')

and the output is

Address1: \x00\x13\xa2\x00@\n!\x1c

Address2: '\\x00\\x13\\xa2\\x00@\\n!\\x1c'

Address3: ?@

!

Size of Addr1: 45

Size of Addr2: 53

Size of Addr3: 29

I've obviously tried simply dest_addr_long=addr1, to no avail.

I have tried many combinations of string manipulation such as adding and removing the parenthesis and dozens of combinations of str and repr but I think I am on the wrong path completely.

I guess what I need to ask is why does

addr3 = '\x00\x13\xa2\x00@\n!\x1c' print "Address3: %s" % addr3

output

Address3: ?@ !

and once I understand that, then how do I manipulate addr1 from the database to match addr3 because the line dest_addr_long=addr3, works perfectly.

Upvotes: 1

Views: 256

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599590

That is an ASCII representation of a byte string. \x00, for example, means 00 ie NUL, and \x13 is ESC; @ and ! are literal characters, but \n means a newline character. That's how it is 8 bytes long.

You can get the actual bytes back by decoding with 'string-escape':

>>> s='\x00\x13\xa2\x00@\n!\x1c'
>>> print s.decode('string-escape')
�@
!

(although the result of print will look different on a terminal).

Upvotes: 1

Related Questions