niolabs / python-xbee

Python tools for working with XBee radios
MIT License
101 stars 45 forks source link

IS Response not parsing correctly? #69

Open mypiandrew opened 5 years ago

mypiandrew commented 5 years ago

Hi

Running the current version against a S8 868LP Module

This code :


# Import and init an XBee device
from xbee.thread import XBee
import serial

ser = serial.Serial('/dev/ttyAMA0', 9600)

# Use an XBee 802.15.4 device
xbee = XBee(ser,escaped = True)

# Blink LED
xbee.remote_at(   frame_id='1',
                  dest_addr_long='\x00\x13\xA2\x00\x41\x87\xB5\xD4',
                  options='\x02',
                  command='P8',
                  parameter='\x05')

xbee.remote_at(   frame_id='2',
                  dest_addr_long='\x00\x13\xA2\x00\x41\x87\xB5\xD4',
                  options='\x02',
                  command='P8',
                  parameter='\x04')

xbee.remote_at(   frame_id='3',
                  dest_addr_long='\x00\x13\xA2\x00\x41\x87\xB5\xD4',
                  options='\x02',
                  command='P8',
                  parameter='\x05')

# Analogues AD0-AD3
xbee.remote_at(   frame_id='4',
                  dest_addr_long='\x00\x13\xA2\x00\x41\x87\xB5\xD4',
                  command='D0')

xbee.remote_at(   frame_id='5',
                  dest_addr_long='\x00\x13\xA2\x00\x41\x87\xB5\xD4',
                  command='D1')

xbee.remote_at(   frame_id='6',
                  dest_addr_long='\x00\x13\xA2\x00\x41\x87\xB5\xD4',
                  command='D2')

xbee.remote_at(   frame_id='7',
                  dest_addr_long='\x00\x13\xA2\x00\x41\x87\xB5\xD4',
                  command='D3')

# Dig In D4,D6,D7 & D11
xbee.remote_at(   frame_id='8',
                  dest_addr_long='\x00\x13\xA2\x00\x41\x87\xB5\xD4',
                  command='D4')

xbee.remote_at(   frame_id='9',
                  dest_addr_long='\x00\x13\xA2\x00\x41\x87\xB5\xD4',
                  command='D6')

xbee.remote_at(   frame_id='A',
                  dest_addr_long='\x00\x13\xA2\x00\x41\x87\xB5\xD4',
                  command='D7')

xbee.remote_at(   frame_id='B',
                  dest_addr_long='\x00\x13\xA2\x00\x41\x87\xB5\xD4',
                  command='P1')

xbee.remote_at(   frame_id='F',
                  dest_addr_long='\x00\x13\xA2\x00\x41\x87\xB5\xD4',
                  command='IS')

# Show XBee responses?
while True:
    try:
        response = xbee.wait_read_frame()
        print response
    except KeyboardInterrupt:
        break

ser.close()

Produces this output

{'status': '\x00', 'source_addr': '\xff\xfe', 'source_addr_long': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'frame_id': '1', 'command': 'P8', 'id': 'remote_at_response'}
{'status': '\x00', 'source_addr': '\xff\xfe', 'source_addr_long': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'frame_id': '2', 'command': 'P8', 'id': 'remote_at_response'}
{'status': '\x00', 'source_addr': '\xff\xfe', 'source_addr_long': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'frame_id': '3', 'command': 'P8', 'id': 'remote_at_response'}
{'status': '\x00', 'source_addr': '\xff\xfe', 'source_addr_long': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'frame_id': '4', 'command': 'D0', 'parameter': '\x02', 'id': 'remote_at_response'}
{'status': '\x00', 'source_addr': '\xff\xfe', 'source_addr_long': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'frame_id': '5', 'command': 'D1', 'parameter': '\x02', 'id': 'remote_at_response'}
{'status': '\x00', 'source_addr': '\xff\xfe', 'source_addr_long': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'frame_id': '6', 'command': 'D2', 'parameter': '\x02', 'id': 'remote_at_response'}
{'status': '\x00', 'source_addr': '\xff\xfe', 'source_addr_long': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'frame_id': '7', 'command': 'D3', 'parameter': '\x02', 'id': 'remote_at_response'}
{'status': '\x00', 'source_addr': '\xff\xfe', 'source_addr_long': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'frame_id': '8', 'command': 'D4', 'parameter': '\x03', 'id': 'remote_at_response'}
{'status': '\x00', 'source_addr': '\xff\xfe', 'source_addr_long': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'frame_id': '9', 'command': 'D6', 'parameter': '\x03', 'id': 'remote_at_response'}
{'status': '\x00', 'source_addr': '\xff\xfe', 'source_addr_long': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'frame_id': 'A', 'command': 'D7', 'parameter': '\x03', 'id': 'remote_at_response'}
{'status': '\x00', 'source_addr': '\xff\xfe', 'source_addr_long': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'frame_id': 'B', 'command': 'P1', 'parameter': '\x03', 'id': 'remote_at_response'}
{'status': '\x00', 'source_addr': '\xff\xfe', 'source_addr_long': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'frame_id': 'F', 'command': 'IS', 'parameter': [{'adc-6': 10241, 'adc-2': 32769, 'dio-6': False, 'dio-7': False, 'dio-4': False}], 'id': 'remote_at_response'}

The parsed response from IS makes no sense to me, there should be 4x Dig ins (4,6,7 &11) and 4x Analogs, (AD0-3),

{'adc-6': 10241, 'adc-2': 32769, 'dio-6': False, 'dio-7': False, 'dio-4': False}

What's gone wrong here with the lib decoding (or am I just being very fat fingered with my code?)

Thanks

Andrew.

mypiandrew commented 5 years ago

Have changed the mode from 802 to DigiMesh (which I think is the only mode the S8 868LP can operate in)

# XBee 802.15.4 Mode?
from xbee.thread import XBee
# DigiMesh Mode?
from xbee.thread import DigiMesh
import serial

ser = serial.Serial('/dev/ttyAMA0', 9600)

# Use an XBee 802.15.4 device
#xbee = XBee(ser,escaped = True)
# Use an XBee DigiMesh device
xbee = DigiMesh(ser,escaped = True)

I'm now getting

# ./test.py
{'status': '\x00', 'reserved': '\xff\xfe', 'frame_id': '1', 'command': 'P8', 'source_addr': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'id': 'remote_at_response'}
{'status': '\x00', 'reserved': '\xff\xfe', 'frame_id': '2', 'command': 'P8', 'source_addr': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'id': 'remote_at_response'}
{'status': '\x00', 'reserved': '\xff\xfe', 'frame_id': '3', 'command': 'P8', 'source_addr': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'id': 'remote_at_response'}
{'status': '\x00', 'reserved': '\xff\xfe', 'frame_id': '4', 'command': 'D0', 'source_addr': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'parameter': '\x02', 'id': 'remote_at_response'}
{'status': '\x00', 'reserved': '\xff\xfe', 'frame_id': '5', 'command': 'D1', 'source_addr': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'parameter': '\x02', 'id': 'remote_at_response'}
{'status': '\x00', 'reserved': '\xff\xfe', 'frame_id': '6', 'command': 'D2', 'source_addr': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'parameter': '\x02', 'id': 'remote_at_response'}
{'status': '\x00', 'reserved': '\xff\xfe', 'frame_id': '7', 'command': 'D3', 'source_addr': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'parameter': '\x02', 'id': 'remote_at_response'}
{'status': '\x00', 'reserved': '\xff\xfe', 'frame_id': '8', 'command': 'D4', 'source_addr': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'parameter': '\x03', 'id': 'remote_at_response'}
{'status': '\x00', 'reserved': '\xff\xfe', 'frame_id': '9', 'command': 'D6', 'source_addr': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'parameter': '\x03', 'id': 'remote_at_response'}
{'status': '\x00', 'reserved': '\xff\xfe', 'frame_id': 'A', 'command': 'D7', 'source_addr': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'parameter': '\x03', 'id': 'remote_at_response'}
{'status': '\x00', 'reserved': '\xff\xfe', 'frame_id': 'B', 'command': 'P1', 'source_addr': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'parameter': '\x03', 'id': 'remote_at_response'}
{'status': '\x00', 'reserved': '\xff\xfe', 'frame_id': 'F', 'command': 'IS', 'source_addr': '\x00\x13\xa2\x00A\x87\xb5\xd4', 'parameter': '\x01\x88\xd0\x0f\x08\x80\x01"\x01!\x01#\x01 ', 'id': 'remote_at_response'}

I'm not sure if that's better or worse...

mattdodge commented 5 years ago

Disclaimer: I'm really not that familiar with this codebase at all. But it looks like the parsing is fine (at least in your first example). It has taken the parameter response and parsed it into a dictionary. Is your question why some of the pins you were expecting to see there aren't there? I don't think I could answer that for you if that's the question.

The parsing code for IS responses happens here though if you want to take a look: https://github.com/niolabs/python-xbee/blob/master/xbee/backend/zigbee.py#L254

mypiandrew commented 5 years ago

Hi Matt

The S8 868LP SMT Modules we're using only allow digimesh mode (so barking up the wrong tree using the 802 mode, and would explain why it's giving duff results when doing so).

The digimesh class looks like it's had much less love compared to the zigbee/802 classes and is indeed missing the parameter decoding functions that the other classes enjoy (sad Andrew).

https://github.com/niolabs/python-xbee/blob/master/xbee/backend/digimesh.py#L148

Sadly my python isn't up to the task of fudging this in (and getting it to work) so I figured the next best thing would be to document my findings here and hope someone with better Python abilities might take up the baton ;-)

There's also a few other quirks I've found and noted in a second ticket.

Thanks for the response though