Git Product home page Git Product logo

sllurp's Introduction

https://circleci.com/gh/ransford/sllurp.svg?style=svg

sllurp is a Python library to interface with RFID readers. It is a pure-Python implementation of the Low Level Reader Protocol (LLRP).

These readers are known to work well with sllurp, but it should be adaptable with not much effort to other LLRP-compatible readers:

  • Impinj Speedway (R1000)
  • Impinj Speedway Revolution (R220, R420)
  • Impinj Speedway xPortal
  • Motorola MC9190-Z (handheld)

File an issue on GitHub if you would like help getting another kind of reader to work.

sllurp is distributed under version 3 of the GNU General Public License. See LICENSE.txt for details.

Quick Start

Install from PyPI:

$ virtualenv .venv
$ source .venv/bin/activate
$ pip install sllurp
$ sllurp inventory ip.add.re.ss

Run sllurp --help and sllurp inventory --help to see options.

Or install from GitHub:

$ git clone https://github.com/ransford/sllurp.git
$ cd sllurp
$ virtualenv .venv
$ source .venv/bin/activate
$ pip install .
$ sllurp inventory ip.add.re.ss

If the reader gets into a funny state because you're debugging against it (e.g., if your program or sllurp has crashed), you can set it back to an idle state by running sllurp reset ip.add.re.ss.

Reader API

sllurp spawn his own "thread" to manage network interaction with the reader. To make a connection, create a LLRPReaderClient and connect() it:

# Minimal example; see sllurp/verb/inventory.py for more.
from sllurp import llrp
from sllurp.llrp import LLRPReaderConfig, LLRPReaderClient, LLRP_DEFAULT_PORT
import logging
logging.getLogger().setLevel(logging.INFO)

def tag_report_cb (reader, tag_reports):
    for tag in tag_reports:
        print('tag: %r' % tag)

config = LLRPReaderConfig()
reader = LLRPReaderClient(host, LLRP_DEFAULT_PORT, config)
reader.add_tag_report_callback(tag_report_cb)

reader.connect()
# We are now connected to the reader and inventory is running.

try:
    # Block forever or until a disconnection of the reader
    reader.join(None)
except (KeyboardInterrupt, SystemExit):
    # catch ctrl-C and stop inventory before disconnecting
    reader.disconnect()

Note

Sllurp used to depend on python twisted and was using its mainloop. This is not the case anymore. Once connected to a reader, Sllurp will spawn his own "thread" to process the received messages and to call user defined callbacks. is_alive() and join(timeout) thread api are exposed by the LLRPReaderClient instance.

Getting More Information From Tag Reports

When initializing LLRPReaderConfig, set flags in the tag_content_selector dictionary argument:

llrp.LLRPReaderConfig({
    'tag_content_selector': {
        'EnableROSpecID': False,
        'EnableSpecIndex': False,
        'EnableInventoryParameterSpecID': False,
        'EnableAntennaID': True,
        'EnableChannelIndex': False,
        'EnablePeakRSSI': True,
        'EnableFirstSeenTimestamp': False,
        'EnableLastSeenTimestamp': True,
        'EnableTagSeenCount': True,
        'EnableAccessSpecID': False,
    }
})

Logging

sllurp logs under the name sllurp, so if you wish to log its output, you can do this the application that imports sllurp:

sllurp_logger = logging.getLogger('sllurp')
sllurp_logger.setLevel(logging.DEBUG)
sllurp_logger.setHandler(logging.FileHandler('sllurp.log'))
# or .setHandler(logging.StreamHandler()) to log to stderr...

Vendor Extensions

sllurp has limited support for vendor extensions through LLRP's custom message facilities. For example, sllurp inventory --impinj-search-mode N allows you to set the Impinj search mode to single target (1) or dual target (2).

Handy Reader Commands

To see what inventory settings an Impinj reader is currently using (i.e., to fetch the current ROSpec), ssh to the reader and

> show rfid llrp rospec 0

The "nuclear option" for resetting a reader is:

> reboot

If You Find a Bug

Start an issue on GitHub! Please follow Simon Tatham's guide on writing good bug reports.

Bug reports are most useful when they're accompanied by verbose error messages. Turn sllurp's log level up to DEBUG, which you can do by specifying the -d command-line option to sllurp. You can log to a logfile with the -l [filename] option. Or simply put this at the beginning of your own code:

import logging
logging.getLogger('sllurp').setLevel(logging.DEBUG)

Known Issues

Reader mode selection is confusing, not least because most readers seem to conflate ModeIndex and ModeIdentifier. If you're using sllurp inventory, use --mode-identifier N. Check your reader's manual to see what mode identifiers it supports via the C1G2RFControl parameter, or run sllurp --debug inventory against a reader to see a dump of the supported modes in the capabilities description.

Contributing

Want to contribute? Here are some areas that need improvement:

  • Encode more protocol messages in the construct branch.
  • Write tests for common encoding and decoding tasks.

Authors

Much of the code in sllurp is by Ben Ransford, although it began its life in August 2013 as a fork of LLRPyC. Many fine citizens of GitHub have contributed code to sllurp since the fork.

sllurp's People

Contributors

daemacles avatar dependabot[bot] avatar donkikos avatar ewfuentes avatar fifieldt avatar fviard avatar ivarveen avatar jettan avatar jonasgroeger avatar lqf96 avatar nhlien93 avatar ransford avatar reingart avatar sheeley avatar thijmenketel avatar ukrutt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sllurp's Issues

Basic tags reading

Hello,

I know it's maybe stupid question, but we can't get it at all.
We want to use Sllurp in our app and read every tag that is in antena range. So when tag is in range we check it for example every second and put it to array so we could use this information next.

Basically our problem is that when we try to read tags by sllurp command or by using code connection we just get only tags that are new to reader. So easily saying tags that where read before don't get read any more. What we do wrong?

Syntax error running inventory 1.2.3.4

[root bin]# ./inventory 1.2.3.4
Traceback (most recent call last):
  File "/usr/lib64/python2.6/runpy.py", line 122, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib64/python2.6/runpy.py", line 34, in _run_code
    exec code in run_globals
  File "/home/neil/llrp/sllurp/sllurp/inventory.py", line 8, in <module>
    import sllurp.llrp as llrp
  File "/home/neil/llrp/sllurp/sllurp/llrp.py", line 251
    bandtbl = {k: v for k, v in bandtbl.items() \
                      ^
SyntaxError: invalid syntax

TransmitPower out of range with some readers

The TransmitPower setting is reader dependent.

$ bin/inventory x.y.z.aa
2014-01-14 17:25:01,518 sllurp: INFO: log level: INFO
2014-01-14 17:25:01,528 sllurp: INFO: connecting...
2014-01-14 17:25:03,363 sllurp: INFO: got READER_EVENT_NOTIFICATION
2014-01-14 17:25:04,036 sllurp: WARNING: ADD_ROSPEC failed with status FieldError: LLRP [310] : //RFTransmitter/TransmitPower : out-of-range
2014-01-14 17:25:04,039 sllurp: INFO: stopping politely
2014-01-14 17:25:04,184 sllurp: INFO: reader finished inventory
2014-01-14 17:25:04,192 sllurp: INFO: lost connection: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.]
2014-01-14 17:25:04,208 sllurp: INFO: total # of tags seen by callback: 0

The correct fix is to issue a GET_READER_CAPABILITIES and receive & parse the GET_READER_CAPABILITIES_RESPONSE before adding any ROSpecs. TransmitPower goes up to 91 on the Speedway Revolution, for instance, but only 61 on the original Speedway.

Modulation problem

Hi, I tried to use R420 reader to communicate with my WISP5 tag. My command line was this

sllurp inventory -M WISP5 -T 7140 (my reader's ip address)

But unfortunately I got this massage

WARNING: Could not find reader mode matching modulation=WISP5 and Tari=7140

And sllurp just ignore my modulation setting. I tried other modulation settings like FM0 or M2 etc but none of these are working.

Can you help me out with this problem?

Fix parameter shifting bug.

When startAccess is called from another function, sometimes the parameters of startAccess would be shifted to the right for no apparent reason. This also happens when changing accessSpecs frequently and can be seen by this log message:

2015-02-17 16:58:11,477 sllurp.llrp: ERROR: panic(): ('ADD_ACCESSSPEC failed',)
2015-02-17 16:58:11,477 sllurp.llrp: ERROR: 6
2015-02-17 16:58:11,477 sllurp.llrp: ERROR: Traceback (most recent call last):
Failure: builtin.int: 6

Basically, it received the STATE of the system instead of the real 1st parameter of startAccess causing the weird behavior.

Switch to more permissive license

Goal: BSD or MIT license.

We inherited the GPL from LLRPyC (and updated it to v3 along the way). This license makes it difficult to include sllurp in software that can't be open sourced for whatever reason.

https://tldrlegal.com/license/gnu-general-public-license-v3-(gpl-3)

The way forward is to expunge all LLRPyC source code, which at this moment is just the protocol messages in llrp_proto.py, in favor of novel code that we can license differently. The construct branch is well underway but isn't yet the default way of handling LLRP messages.

Once the expunging is done, we can make a new release under a new license.

malformed ADD_ACCESSSPEC message

@lqf96 reports that, with the code in https://gist.github.com/lqf96/5addd0962cabbfbce728711785aa4ddf, sllurp (presumably the latest develop) produces the following ADD_ACCESSSPEC message and response:

2017-08-15 16:36:08,296 sllurp.llrp: DEBUG: serializing ADD_ACCESSSPEC command
2017-08-15 16:36:08,296 sllurp.llrp: DEBUG: serialized bytes: 04280000004e0000000000cf004400000001000001000000000000d0000701000100d1002801520015015300116000200010ffffff00101000000155000f000100000000c00000000100ef000501
2017-08-15 16:36:08,296 sllurp.llrp: DEBUG: done serializing ADD_ACCESSSPEC command
[...]
2017-08-15 16:36:08,306 sllurp.llrp: DEBUG: LLRPMessage received in state 18: <ADD_ACCESSSPEC_RESPONSE>
	<Ver>1</Ver>
	<Type>50</Type>
	<ID>0</ID>
	<LLRPStatus>
		<StatusCode>FieldError</StatusCode>
		<ErrorDescription>LLRP decode failure at byte offset 52 (status -217)</ErrorDescription>
	</LLRPStatus>
</ADD_ACCESSSPEC_RESPONSE>

Picking apart the message, we get:

# ADD_ACCESSSPEC header
0428       # type = 40
0000004e   # length = 78
00000000   # message ID = 0

# AccessSpec param, see section 17.2.5.1
00cf 0044  # type = 207, len = 68
00000001   # access spec ID = 1
0000       # antenna ID = 0 (all)
01         # protocol ID = 1
00         # reserved
00000000   # rospec ID
  # AccessSpecStopTrigger param, see section 17.2.5.1.1
  00d0 0007  # type = 208, len = 7
  01         # AccessSpecStopTrigger = 1
  0001       # OperationCountValue = 1
  # AccessCommand param, see section 17.2.5.1.2
  00d1 0028  # type = 209, len = 40
    # C1G2TagSpec param, see section 17.3.1.3.1
    0152 0015  # type = 338, len = 21
      # C1G2TargetTag param, see section 17.3.1.3.1.1
      0153 0011  # type = 339, len = 17
      60         # MB = 1, M = 1
      0020       # pointer = 32
      0010       # MaskBitCount = 16
      ffff       # tag mask = 0xffff
      ff00       # data bit count = 65280 -- THIS IS WRONG!!!!! SHOULD BE 0x0020
      10100000   # tag data
    # C1G2Read param, see section 17.3.1.3.2.1
    0155 000f  # type = 341, len = 15
    0001       # opspec ID = 1
    00000000   # access password = 0
    c0         # MB = 3
    0000       # word pointer = 0
    0001       # word count = 1
  # AccessReportSpec param, see section 17.2.7.2
  00ef 0005  # type = 239, len = 5
  01         # AccessReport trigger = 1

... with a clear bug in the DataBitCount parameter of the C1G2TargetTag param.

Update Tornado example

The Tornado example is useful but hasn't been updated in a while; some API changes broke it.

Support multiple antenna power settings (map)

#54 has been available for almost a year but has not yet been merged due to conflicts. I have a need to support multiple antenna power settings and was about to do a pull request for this feature when I noticed there is already one sitting there with basically the same changes I had made. Can you please resolve the conflicts and add this in to the main branch?

Thanks!!

ThingMagic Sargas: Unsupported StopTrigger 3

Hi,

I was trying to use the inventory script with the ThingMagic Sargas and get the following error.

2017-02-27 11:57:01,481 sllurp: INFO: log level: INFO
2017-02-27 11:57:01,482 sllurp.llrp: INFO: connecting...
2017-02-27 11:57:01,485 sllurp.llrp: INFO: will reset reader state on connect
2017-02-27 11:57:01,485 sllurp.llrp: INFO: will start inventory on connect
2017-02-27 11:57:01,485 sllurp.llrp: INFO: using antennas: [1]
2017-02-27 11:57:01,485 sllurp.llrp: INFO: connected to ('sargas-836c20.local', 5084) (10.129.1.197:5084)
2017-02-27 11:57:01,649 sllurp.llrp: INFO: requested modulation: M4
2017-02-27 11:57:01,649 sllurp.llrp: INFO: using reader mode: {'C': 0, 'MaxTari': 25000, 'M': 3, 'PIE': 1700, 'StepTari': 12500, 'R': 1, 'FLM': 0, 'MinTari': 12500, 'ModeIdentifier': 1, 'BDR': 250000, 'Mod': 2}
2017-02-27 11:57:01,649 sllurp.llrp: INFO: stopping politely
2017-02-27 11:57:01,656 sllurp.llrp: INFO: reader finished inventory
2017-02-27 11:57:01,657 sllurp.llrp_proto: INFO: will report every ~N=0 tags
2017-02-27 11:57:01,657 sllurp.llrp: INFO: starting inventory
2017-02-27 11:57:01,677 sllurp.llrp: CRITICAL: Error ParameterError adding ROSpec: ADD_ROSPEC: Error: Adding AISpec with unsupported StopTrigger 3

It's not obvious to me how to change the StopTrigger. I'd appreciate any help.

Thanks!

Support for Python 3?

Both the sllurp CLI and the library fail to run under Python 3.6. Since official support for Python 2 is going to end at 2020, maybe we should update the code to make it work with Python 3.

Get info from the reader

Hi ransford,

I'm on a project to build a tag based management system that runs on the web, and I use Sllurp to get data from tags, that's cool!. all is working well. I haven't much knowledge about RFID systems and I'am a beginner of python, I just want you ask a simple question, is possible to get data from reader inside the TagReportData?

selection_002

What happens is I got two readers, I am reading from both an listing the tags, I get the antenna id from each reader, no problem. But I need to know from where reader comes data.

I mean maybe host IP, mac address or some id that identifies a reader. If this can be done, how can I get that data into tag data returned by the report?.

I tested these parameters but no one distinguishes one reader from another

                                 'EnableROSpecID': True,
                                 'EnableSpecIndex': True,
                                 'EnableInventoryParameterSpecID': True,
                                 'EnableAntennaID': True,
                                 'EnableChannelIndex': True,
                                 'EnablePeakRRSI': True,
                                 'EnableFirstSeenTimestamp': True,
                                 'EnableLastSeenTimestamp': True,
                                 'EnableTagSeenCount': True,
                                 'EnableAccessSpecID': True

I appreciate your answer, sorry for my english, is not my native language.

Thank you.

Unify command-line tools

Into a single sllurp command. click can help with the CLI heavy lifting.

In the process, fix setup.py (doc) and use an entry_point.

All this grooming will help with #6.

Antenna configuration problems

Hi! I have some problems to configure the antennas in my LLRP reader, in order to run a simple inventory. I would like to receive only data from antennas 5, 6 and 7. Then, I'm running the inventory like this:

python inventory.py -t 2 -a 5,6,7 10.0.1.57

When I do this, only receive data from the first antenna that I set up, in this case, the 5.

2017-05-31 11:20:53,525 sllurp: INFO: no tags seen
2017-05-31 11:20:53,530 sllurp.llrp: WARNING: message None received in unknown state!
2017-05-31 11:20:53,534 sllurp.llrp: WARNING: message None received in unknown state!
2017-05-31 11:20:53,569 sllurp: INFO: saw tag(s): [{'AccessSpecID': (0,),
  'AntennaID': (5,),
  'ChannelIndex': (1,),
  'EPCData': {'EPC': '08000000000000001dc184bf8b218400',
              'EPCLengthBits': 128},
  'FirstSeenTimestampUTC': (1496222831128366,),
  'InventoryParameterSpecID': (1,),
  'LastSeenTimestampUTC': (1496222831128366,),
  'PeakRSSI': (-59,),
  'ROSpecID': (1,),
  'SpecIndex': (1,),
  'TagSeenCount': (1,)}]
2017-05-31 11:20:53,571 sllurp: INFO: no tags seen
2017-05-31 11:20:53,576 sllurp.llrp: WARNING: message None received in unknown state!
2017-05-31 11:20:53,581 sllurp.llrp: WARNING: message None received in unknown state!
2017-05-31 11:20:53,697 sllurp: INFO: saw tag(s): [{'AccessSpecID': (0,),
  'AntennaID': (5,),
  'ChannelIndex': (1,),
  'EPCData': {'EPC': '080000000000000020a13c3233c28400',
              'EPCLengthBits': 128},
  'FirstSeenTimestampUTC': (1496222831192767,),
  'InventoryParameterSpecID': (1,),
  'LastSeenTimestampUTC': (1496222831192767,),
  'PeakRSSI': (-58,),
  'ROSpecID': (1,),
  'SpecIndex': (1,),
  'TagSeenCount': (1,)}]
python inventory.py -t 2 -a 6,7,8 10.0.1.57

In this case, only antenna 6:

2017-05-31 11:22:46,310 sllurp: INFO: no tags seen
2017-05-31 11:22:46,315 sllurp.llrp: WARNING: message None received in unknown state!
2017-05-31 11:22:46,320 sllurp.llrp: WARNING: message None received in unknown state!
2017-05-31 11:22:46,433 sllurp: INFO: saw tag(s): [{'AccessSpecID': (0,),
  'AntennaID': (6,),
  'ChannelIndex': (1,),
  'EPCData': {'EPC': '0800000000000000314489b334008400',
              'EPCLengthBits': 128},
  'FirstSeenTimestampUTC': (1496222943928948,),
  'InventoryParameterSpecID': (1,),
  'LastSeenTimestampUTC': (1496222943928948,),
  'PeakRSSI': (-60,),
  'ROSpecID': (1,),
  'SpecIndex': (1,),
  'TagSeenCount': (1,)}]
2017-05-31 11:22:46,435 sllurp: INFO: no tags seen
2017-05-31 11:22:46,441 sllurp.llrp: WARNING: message None received in unknown state!
2017-05-31 11:22:46,449 sllurp.llrp: WARNING: message None received in unknown state!
2017-05-31 11:22:46,472 sllurp: INFO: saw tag(s): [{'AccessSpecID': (0,),
  'AntennaID': (6,),
  'ChannelIndex': (1,),
  'EPCData': {'EPC': '08000000000000002f3b33930e808400',
              'EPCLengthBits': 128},
  'FirstSeenTimestampUTC': (1496222944051346,),
  'InventoryParameterSpecID': (1,),
  'LastSeenTimestampUTC': (1496222944051346,),
  'PeakRSSI': (-71,),
  'ROSpecID': (1,),
  'SpecIndex': (1,),
  'TagSeenCount': (1,)}]

If I see the LLRP packets, in the ADD_ROSPEC message, I can see that the Antenna Configuration is correct:

config

And the ADD_ROSPEC_RESPONSE is Succes:

image

But I only receive 'Reader Event Notification' messages from the first antenna configured:

image

One card of five is not detected as often

Speedway R640

One of my five test cards under-reports. I discovered the problem with my own software (a horrible fork of yours for the time being), where the issue was much worse for some bizarre reason. The problem does not occur with the Multireader software from Impinj. I just have five cards on the desk in front of the reader.

Your program, with a bit of script-fu, I hope I am doing that right.

./bin/inventory -n 1 192.168.5.149 2>&1 | grep EPC-96 | head -1000 | sort | uniq -c | sort -rn
    245   'EPC-96': 'e2007523231602420540dfbf',
    245   'EPC-96': 'e2001021511801290360ea9a',
    245   'EPC-96': 'e2001021511800940490e14b',
    239   'EPC-96': 'e2001021511800880490e133',
     26   'EPC-96': 'e2007523231602410890be9a',

My software (count is the last column). I only report on a card once every ten seconds:

2014-09-15 18:54:42 e2001021511800880490e133 1
2014-09-15 18:54:42 e2007523231602420540dfbf 1
2014-09-15 18:54:42 e2001021511801290360ea9a 1
2014-09-15 18:54:42 e2001021511800940490e14b 1
2014-09-15 18:54:46 e2007523231602410890be9a 1
2014-09-15 18:54:52 e2001021511800880490e133 345
2014-09-15 18:54:52 e2001021511801290360ea9a 347
2014-09-15 18:54:52 e2007523231602420540dfbf 348
2014-09-15 18:54:52 e2001021511800940490e14b 347
2014-09-15 18:55:02 e2001021511800880490e133 691
2014-09-15 18:55:02 e2001021511801290360ea9a 695
2014-09-15 18:55:02 e2001021511800940490e14b 696
2014-09-15 18:55:02 e2007523231602420540dfbf 696
2014-09-15 18:55:12 e2001021511800880490e133 1035
2014-09-15 18:55:12 e2001021511801290360ea9a 1039
2014-09-15 18:55:12 e2001021511800940490e14b 1040
2014-09-15 18:55:12 e2007523231602420540dfbf 1040
2014-09-15 18:55:22 e2007523231602410890be9a 2
2014-09-15 18:55:22 e2001021511800880490e133 1376
2014-09-15 18:55:22 e2001021511801290360ea9a 1382
2014-09-15 18:55:22 e2001021511800940490e14b 1382
2014-09-15 18:55:22 e2007523231602420540dfbf 1383
2014-09-15 18:55:32 e2001021511800880490e133 1720
2014-09-15 18:55:32 e2001021511801290360ea9a 1726
2014-09-15 18:55:32 e2001021511800940490e14b 1727
2014-09-15 18:55:32 e2007523231602420540dfbf 1729
2014-09-15 18:55:34 e2007523231602410890be9a 3

exception.TypeError: Data must not be unicode.

Got this error while in send_KEEPALIVE_ACK. This function is in llrp.py. I am using a Zebra RFID reader. Would you please look at this issue? Thanks.

The dump is below,

Unhandled Error
Traceback (most recent call last):
File "c:\python27\lib\site-packages\twisted\python\log.py", line 103, in callWithLogger
return callWithContext({"system": lp}, func, *args, **kw)
File "c:\python27\lib\site-packages\twisted\python\log.py", line 86, in callWithContext
return context.call({ILogContext: newCtx}, func, *args, **kw)
File "c:\python27\lib\site-packages\twisted\python\context.py", line 122, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "c:\python27\lib\site-packages\twisted\python\context.py", line 85, in callWithContext
return func(*args,**kw)
--- ---
File "c:\python27\lib\site-packages\twisted\internet\selectreactor.py", line 149, in _doReadOrWrite
why = getattr(selectable, method)()
File "c:\python27\lib\site-packages\twisted\internet\tcp.py", line 208, in doRead
return self._dataReceived(data)
File "c:\python27\lib\site-packages\twisted\internet\tcp.py", line 214, in _dataReceived
rval = self.protocol.dataReceived(data)
File "c:\python27\lib\site-packages\twisted\protocols\basic.py", line 578, in dataReceived
why = self.rawDataReceived(data)
File "c:\python27\lib\site-packages\sllurp\llrp.py", line 661, in rawDataReceived
self.handleMessage(lmsg)
File "c:\python27\lib\site-packages\sllurp\llrp.py", line 375, in handleMessage
self.send_KEEPALIVE_ACK()
File "c:\python27\lib\site-packages\sllurp\llrp.py", line 687, in send_KEEPALIVE_ACK
self.sendLLRPMessage(llrpmsg)
File "c:\python27\lib\site-packages\sllurp\llrp.py", line 1153, in sendLLRPMessage
self.transport.write(llrp_msg.msgbytes)
File "c:\python27\lib\site-packages\twisted\internet_newtls.py", line 191, in write
FileDescriptor.write(self, bytes)
File "c:\python27\lib\site-packages\twisted\internet\abstract.py", line 348, in write
raise TypeError("Data must not be unicode")
exceptions.TypeError: Data must not be unicode

2017-09-12 22:25:05,571 sllurp.llrp: INFO: lost connection: Data must not be unicode
2017-09-12 22:25:05,572 sllurp: INFO: total # of tags seen: 700 (41 tags/second)

List reader modes and exit

In #64, it would have been helpful to have a --list-modes option to fetch the reader's capabilities blob and print the available mode settings. Right now it's necessary to call sllurp --debug inventory <ip.add.re.ss>, find the capabilities section, and dig through it to find the mode settings we want.

CSV logging doesn't make sense

Quick & hacky sllurp log stinks. How should logging to CSV work?

  • One CSV line every n milliseconds
  • Include count of tags with each line
  • File should be tail-able, not dumped at end

implement CLOSE_CONNECTION for graceful shutdown

As specified in 13.1.5. The current "polite" behavior is to delete all ROSpecs, but this way is even more polite. Execute CLOSE_CONNECTION and wait for CLOSE_CONNECTION_RESPONSE after deleting all ROSpecs.

Trouble reading temperature sensor data from EM 4325 IC

Hi
EM 4325 IC has the on board temperature sensor on it. I am trying to read the 256th word in its user memory bank using the access.py .However, I am not understanding this tag read rata. Here is it for example:

2018-05-11 16:01:42,200 sllurp: INFO: saw tag(s): [{'AccessSpecID': (1,),
'AntennaID': (1,),
'EPC-96': b'0080b0443c0000001210b4b6',
'LastSeenTimestampUTC': (1526056288899394,),
'OpSpecResult': {'OpSpecID': 0,
'ReadData': b'\x00^\x00\x00',
'ReadDataWordCount': 2,
'Result': 0},
'PeakRSSI': (-49,),
'TagSeenCount': (1,)}]

Why is it reading \x00^\ does this mean there is a decoding issue? But it works well if I am reading any other data for example EPC code. I have tested reading using the impinj's multi reader software and it works perfectly fine. So I am guessing something is not happening right when I use Sllurp.

Did anyone successfully read EM 4325's temperature data using sllurp?

Also, how do I selectively read only one tag from access.py instead of reading all tags. Thanks for your help in advance.

ERROR: Problem with READER_EVENT_NOTIFICATION message format

$ bin/inventory 169.254.1.1
2016-12-07 14:40:04,190 sllurp: INFO: log level: INFO
2016-12-07 14:40:04,191 sllurp.llrp: INFO: connecting...
2016-12-07 14:40:04,192 sllurp.llrp: INFO: will reset reader state on connect
2016-12-07 14:40:04,192 sllurp.llrp: INFO: will start inventory on connect
2016-12-07 14:40:04,192 sllurp.llrp: INFO: using antennas: [1]
2016-12-07 14:40:04,193 sllurp.llrp: INFO: connected to ('169.254.1.1', 5084) (169.254.1.1:5084)
2016-12-07 14:40:04,461 sllurp.llrp: INFO: requested modulation: M4
2016-12-07 14:40:04,461 sllurp.llrp: INFO: using reader mode: {'C': 0, 'MaxTari': 20000, 'M': 3, 'PIE': 2000, 'StepTari': 0, 'R': 1, 'FLM': 0, 'MinTari': 20000, 'ModeIdentifier': 2, 'BDR': 274000, 'Mod': 2}
2016-12-07 14:40:04,461 sllurp.llrp: INFO: stopping politely
2016-12-07 14:40:04,472 sllurp.llrp: INFO: reader finished inventory
2016-12-07 14:40:04,472 sllurp.llrp_proto: INFO: will report every ~N=1 tags
2016-12-07 14:40:04,472 sllurp.llrp: INFO: starting inventory
2016-12-07 14:40:04,505 sllurp.llrp: ERROR: Problem with READER_EVENT_NOTIFICATION message format
Traceback (most recent call last):
File "sllurp/llrp.py", line 84, in deserialize
name: dict(decoder(body))
File "sllurp/llrp_proto.py", line 645, in decode_ReaderEventNotification
raise LLRPError('junk at end of message: ' + bin2dump(body))
LLRPError: junk at end of message: 00 f9 00 0d 00 00 00 00 01 00 00 00 00 .............
2016-12-07 14:40:04,505 sllurp.llrp: ERROR: unexpected response None when enabling ROSpec
Unhandled Error
Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/twisted/python/log.py", line 103, in callWithLogger
return callWithContext({"system": lp}, func, *args, **kw)
File "/usr/local/lib/python2.7/site-packages/twisted/python/log.py", line 86, in callWithContext
return context.call({ILogContext: newCtx}, func, *args, **kw)
File "/usr/local/lib/python2.7/site-packages/twisted/python/context.py", line 118, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/usr/local/lib/python2.7/site-packages/twisted/python/context.py", line 81, in callWithContext
return func(*args,**kw)
--- ---
File "/usr/local/lib/python2.7/site-packages/twisted/internet/selectreactor.py", line 149, in _doReadOrWrite
why = getattr(selectable, method)()
File "/usr/local/lib/python2.7/site-packages/twisted/internet/tcp.py", line 208, in doRead
return self._dataReceived(data)
File "/usr/local/lib/python2.7/site-packages/twisted/internet/tcp.py", line 214, in _dataReceived
rval = self.protocol.dataReceived(data)
File "/usr/local/lib/python2.7/site-packages/twisted/protocols/basic.py", line 578, in dataReceived
why = self.rawDataReceived(data)
File "sllurp/llrp.py", line 544, in rawDataReceived
self.handleMessage(lmsg)
File "sllurp/llrp.py", line 444, in handleMessage
status = lmsg.msgdict[msgName]['LLRPStatus']['StatusCode']
exceptions.TypeError: 'NoneType' object has no attribute 'getitem'

2016-12-07 14:40:04,506 sllurp.llrp: INFO: lost connection: 'NoneType' object has no attribute 'getitem'
2016-12-07 14:40:04,507 sllurp: INFO: total # of tags seen: 0 (0 tags/second)

Targeted Antenna Tag Readings

Hello!

I am using Impinj R420 Reader. Everything is working fine until I tried to the scenario below:

My setup, I place:

  • EPC: 3039606343b916c000154213 on antenna#1
  • EPC: 30396062c3b02440000002ee on antenna#2

Below is the command i used and result given:

sllurp inventory <reader ip> --antennas 2

sllurp.verb.inventory: INFO: saw tag(s):
[{u'AntennaID': (2,),
u'EPC-96': '3039606343b916c000154213',
u'LastSeenTimestampUTC': (1508917299346036,),
u'PeakRSSI': (-34,),
u'TagSeenCount': (38,)},
{u'AntennaID': (2,),
u'EPC-96': '30396062c3b02440000002ee',
u'LastSeenTimestampUTC': (1508917299345483,),
u'PeakRSSI': (-53,),
u'TagSeenCount': (38,)}]

Instead of getting one RFID's EPC, i'm getting both.
Is there a configuration for me to disable antenna#1 while antenna#2 is scanning?

Thank you!

Support for ThingMagic Astra-EX reader

Hi Folks. I'd like to get sslurp working with the ThingMagic Astra EX reader (http://www.thingmagic.com/index.php/integrated-readers/445-astra-ex). The reader specs state that it supports "LLRP v1.0.1 with multi-protocol extensions". Here's what I get when trying to use inventory "out-of-the-box":

$ ./inventory 10.0.80.63
2015-07-19 00:41:01,892 sllurp: INFO: log level: INFO
2015-07-19 00:41:01,893 sllurp.llrp: INFO: connecting...
2015-07-19 00:41:01,896 sllurp.llrp: INFO: will reset reader state on connect
2015-07-19 00:41:01,896 sllurp.llrp: INFO: will start inventory on connect
2015-07-19 00:41:01,896 sllurp.llrp: INFO: using antennas: [1]
2015-07-19 00:41:01,897 sllurp.llrp: INFO: connected to ('10.0.80.63', 5084)
2015-07-19 00:41:02,104 sllurp.llrp: INFO: requested modulation: M4
2015-07-19 00:41:02,104 sllurp.llrp: INFO: using reader mode: {'C': 0, 'MaxTari': 25000, 'M': 3, 'PIE': 1700, 'StepTari': 12500, 'R': 1, 'FLM': 0, 'MinTari': 12500, 'ModeIdentifier': 1, 'BDR': 250000, 'Mod': 2}
2015-07-19 00:41:02,105 sllurp.llrp: INFO: stopping politely
2015-07-19 00:41:02,118 sllurp.llrp: INFO: reader finished inventory
2015-07-19 00:41:02,118 sllurp.llrp: INFO: starting inventory
2015-07-19 00:41:02,128 sllurp.llrp: CRITICAL: Error FieldError adding ROSpec: ADD_ROSPEC: Error: Transmit Power index 107 is out of range for Ant 1 in NA region, valid range is 1 to 101

Any help is much appreciated. The "Mercury" API that ThingMagic supplies only supports Java, C and C#. I could probably generate python wrappers for the C interface but if I can get sslurp working, that will save me a lot of time.

Trouble with rswr-400 reader

Hi,

I'm currently having problem when running sllurp inventory ip.add.re.ss. I'm using the rswr-400 reader from Radiant Sensors. From what I can see, there is a problem with ADD_ROSPEC_RESPONSE but I have no clue how to resolve this.

Here is the --debug result: https://pastebin.com/B6Cn7K5x

Help would be greatly appreciated.

Thanks!

Errors while running `bin/access`

When running the access script I encounter two errors:

The first is right at the start of the script (using the -r 1 argument):

2015-01-12 16:11:46,668 sllurp.llrp: ERROR: panic(): ('ENABLE_ROSPEC failed',)
2015-01-12 16:11:46,669 sllurp.llrp: ERROR: 'int' object has no attribute '__getitem__'
2015-01-12 16:11:46,669 sllurp.llrp: ERROR: Traceback (most recent call last):
  File "sllurp/llrp.py", line 440, in handleMessage
    self.processDeferreds(msgName, lmsg.isSuccess())
  File "sllurp/llrp.py", line 301, in processDeferreds
    d.callback(self.state)
  File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 382, in callback
    self._startRunCallbacks(result)
  File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 490, in _startRunCallbacks
    self._runCallbacks()
--- <exception caught here> ---
  File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 577, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "sllurp/llrp.py", line 232, in _setState_wrapper
    self.setState(args[0], **kwargs)
  File "sllurp/llrp.py", line 227, in setState
    fn(self)
  File "/home/ivar/Code/sllurp/sllurp/access.py", line 21, in access
    writeWords=args.write_words)
  File "sllurp/llrp.py", line 611, in startAccess
    opSpecParam['MB'] = readWords['MB']
exceptions.TypeError: 'int' object has no attribute '__getitem__'

The second error is right before the end of the program:

Unhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1085, in connectionLost
    self.factory.clientConnectionLost(self, reason)
  File "sllurp/llrp.py", line 842, in clientConnectionLost
    self.onFinish.callback(None)
  File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 382, in callback
    self._startRunCallbacks(result)
  File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 490, in _startRunCallbacks
    self._runCallbacks()
--- <exception caught here> ---
  File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 577, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "/home/ivar/Code/sllurp/sllurp/access.py", line 17, in finish
    reactor.stop()
  File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 580, in stop
    "Can't stop reactor that isn't running.")
twisted.internet.error.ReactorNotRunning: Can't stop reactor that isn't running.

I'll create a PR fixing these.

Error unexpected response DELETE_ROSPEC_RESPONSE

This is the error we chatted about - I'm immediately disconnecting (to delete any existing ROSpecs) like so:

def clear_rospec(proto):
    if not self.initial_rospec_clear:
        logger.info('rfid clearing rospec')
        self.initial_rospec_clear = True
        return proto.stopPolitely()

fac = LLRPClientFactory(**config)
fac.addTagReportCallback(tag_seen_callback)
fac.addStateCallback(LLRPClient.STATE_CONNECTED, clear_rospec)

And here is the output, from starting to the error, to inventory starting. I've replaced the content of , its NUL values were causing problems.

INFO: sllurp: llrp.py 585  connecting...
INFO: sllurp: llrp.py 170  will start inventory on connect
INFO: sllurp: llrp.py 199  connected to ('10.140.249.187', 5084)
DEBUG: sllurp: llrp.py 421  got 32 bytes from reader: 043f000000201974f2b300f600160080000c0004fa79159854d1010000060000
DEBUG: sllurp: llrp.py 439  expect 32 bytes (have 32)
DEBUG: sllurp: llrp.py 76  deserializing READER_EVENT_NOTIFICATION command
DEBUG: sllurp: llrp_proto.py 650  decode_ReaderEventNotification
DEBUG: sllurp: llrp_proto.py 1993  decode_ReaderEventNotificationData (type=246 len=22)
DEBUG: sllurp: llrp_proto.py 718  decode_UTCTimestamp
DEBUG: sllurp: llrp_proto.py 730  decode_UTCTimestamp (type=128 len=12)
DEBUG: sllurp: llrp_proto.py 2066  decode_ConnectionAttemptEvent
DEBUG: sllurp: llrp_proto.py 2078  decode_ConnectionAttemptEvent (type=256 len=6)
DEBUG: sllurp: llrp_proto.py 2033  decode_AntennaEvent
DEBUG: sllurp: llrp.py 89  done deserializing READER_EVENT_NOTIFICATION command
DEBUG: sllurp: llrp.py 270  LLRPMessage received in state 1: <READER_EVENT_NOTIFICATION>
    <Ver>1</Ver>
    <Type>63</Type>
    <ID>427094707</ID>
    <ReaderEventNotificationData>
        <ConnectionAttemptEvent>
            <Status>Success</Status>
        </ConnectionAttemptEvent>
    </ReaderEventNotificationData>
</READER_EVENT_NOTIFICATION>
DEBUG: sllurp: llrp.py 275  starting message callbacks for READER_EVENT_NOTIFICATION
DEBUG: sllurp: llrp.py 278  done with message callbacks for READER_EVENT_NOTIFICATION
DEBUG: sllurp: llrp.py 285  in handleMessage(READER_EVENT_NOTIFICATION), there are 0 Deferreds
DEBUG: sllurp: llrp.py 48  serializing GET_READER_CAPABILITIES command
DEBUG: sllurp: llrp.py 62  serialized bytes: 04010000000b0000000000
DEBUG: sllurp: llrp.py 63  done serializing GET_READER_CAPABILITIES command
DEBUG: sllurp: llrp.py 206  state change: STATE_DISCONNECTED -> STATE_SENT_GET_CAPABILITIES
DEBUG: sllurp: llrp.py 421  got 1513 bytes from reader: 040b000005e900000000011f00080000000000890197000440000000651a001e886b0009342e382e332e323430008b000800010000008b00080002000a008b00080003000b008b00080004000c008b00080005000d008b00080006000e008b00080007000f008b000800080010008b000800090011008b0008000a0012008b0008000b0013008b0008000c0014008b0008000d0015008b0008000e0016008b0008000f0017008b000800100018008b000800110019008b00080012001a008b00080013001b008b00080014001c008b00080015001d008b00080016001e008b00080017001f008b000800180020008b000800190021008b0008001a0022008b0008001b0023008b0008001c0024008b0008001d0025008b0008001e0026008b0008001f0027008b000800200028008b000800210029008b00080022002a008b00080023002b008b00080024002c008b00080025002d008b00080026002e008b00080027002f008b000800280030008b000800290031008b0008002a0032008d000800040004008c00090001000101008c00090002000101008c00090003000101008c00090004000101008e001c48010000000000010000001000000001000005e400000010008f041d034800010090041500910008000103e80091000800020401009100080003041a0091000800040433009100080005044c0091000800060465009100080007047e009100080008049700910008000904b000910008000a04c900910008000b04e200910008000c04fb00910008000d051400910008000e052d00910008000f0546009100080010055f0091000800110578009100080012059100910008001305aa00910008001405c300910008001505dc00910008001605f5009100080017060e0091000800180627009100080019064000910008001a065900910008001b067200910008001c068b00910008001d06a400910008001e06bd00910008001f06d600910008002006ef00910008002107080091000800220721009100080023073a0091000800240753009100080025076c0091000800260785009100080027079e00910008002807b700910008002907d000910008002a07e900910008002b080200910008002c081b00910008002d083400910008002e084d00910008002f0866009100080030087f009100080031089800910008003208b100910008003308ca00910008003408e300910008003508fc0091000800360915009100080037092e0091000800380947009100080039096000910008003a097900910008003b099200910008003c09ab00910008003d09c400910008003e09dd00910008003f09f60091000800400a0f0091000800410a280091000800420a410091000800430a5a0091000800440a730091000800450a8c0091000800460aa50091000800470abe0091000800480ad70091000800490af000910008004a0b0900910008004b0b22009200d580009300d001000032000e128a000e1672000df53e000de59e000e2612000dd40a000dcc3a000e241e000dfb1a000dd216000ddfc2000ddbda000e1e42000dd9e6000dc65e000e1866000e1a5a000e2036000df34a000dd022000e08c6000dd5fe000df926000e04de000dff02000de3aa000dfd0e000de1b6000e0ea2000e1096000dc852000df732000ded6e000e0cae000def62000e0aba000de792000deb7a000de986000e02ea000e147e000dddce000e06d2000e1c4e000e00f6000df156000e222a000dce2e000dca46000dd7f2014800e40149002000000000800002020009c400000005dc0000186a0000186a000000000149002000000001800102020009c400000005dc0000186a0000186a0000000001490020000000028002000300042e50000007d000004e2000004e200000000001490020000000038003000300029a68000007d000004e2000004e20000000000149002000000004800200020009c400000005dc00001be400001be40000000001490020000003e80000000000009c40000005dc0000186a0000186a0000000001490020000003e90000000000009c40000005dc0000186a0000186a0000000001470007400002
DEBUG: sllurp: llrp.py 439  expect 1513 bytes (have 1513)
DEBUG: sllurp: llrp.py 76  deserializing GET_READER_CAPABILITIES_RESPONSE command
DEBUG: sllurp: llrp_proto.py 325  decode_GetReaderCapabilitiesResponse
DEBUG: sllurp: llrp_proto.py 2097  decode_LLRPStatus
DEBUG: sllurp: llrp_proto.py 2099  decode_LLRPStatus: 011f00080000000000890197000440000000651a001e886b0009342e382e332e323430008b000800010000008b00080002000a008b00080003000b008b00080004000c008b00080005000d008b00080006000e008b00080007000f008b000800080010008b000800090011008b0008000a0012008b0008000b0013008b0008000c0014008b0008000d0015008b0008000e0016008b0008000f0017008b000800100018008b000800110019008b00080012001a008b00080013001b008b00080014001c008b00080015001d008b00080016001e008b00080017001f008b000800180020008b000800190021008b0008001a0022008b0008001b0023008b0008001c0024008b0008001d0025008b0008001e0026008b0008001f0027008b000800200028008b000800210029008b00080022002a008b00080023002b008b00080024002c008b00080025002d008b00080026002e008b00080027002f008b000800280030008b000800290031008b0008002a0032008d000800040004008c00090001000101008c00090002000101008c00090003000101008c00090004000101008e001c48010000000000010000001000000001000005e400000010008f041d034800010090041500910008000103e80091000800020401009100080003041a0091000800040433009100080005044c0091000800060465009100080007047e009100080008049700910008000904b000910008000a04c900910008000b04e200910008000c04fb00910008000d051400910008000e052d00910008000f0546009100080010055f0091000800110578009100080012059100910008001305aa00910008001405c300910008001505dc00910008001605f5009100080017060e0091000800180627009100080019064000910008001a065900910008001b067200910008001c068b00910008001d06a400910008001e06bd00910008001f06d600910008002006ef00910008002107080091000800220721009100080023073a0091000800240753009100080025076c0091000800260785009100080027079e00910008002807b700910008002907d000910008002a07e900910008002b080200910008002c081b00910008002d083400910008002e084d00910008002f0866009100080030087f009100080031089800910008003208b100910008003308ca00910008003408e300910008003508fc0091000800360915009100080037092e0091000800380947009100080039096000910008003a097900910008003b099200910008003c09ab00910008003d09c400910008003e09dd00910008003f09f60091000800400a0f0091000800410a280091000800420a410091000800430a5a0091000800440a730091000800450a8c0091000800460aa50091000800470abe0091000800480ad70091000800490af000910008004a0b0900910008004b0b22009200d580009300d001000032000e128a000e1672000df53e000de59e000e2612000dd40a000dcc3a000e241e000dfb1a000dd216000ddfc2000ddbda000e1e42000dd9e6000dc65e000e1866000e1a5a000e2036000df34a000dd022000e08c6000dd5fe000df926000e04de000dff02000de3aa000dfd0e000de1b6000e0ea2000e1096000dc852000df732000ded6e000e0cae000def62000e0aba000de792000deb7a000de986000e02ea000e147e000dddce000e06d2000e1c4e000e00f6000df156000e222a000dce2e000dca46000dd7f2014800e40149002000000000800002020009c400000005dc0000186a0000186a000000000149002000000001800102020009c400000005dc0000186a0000186a0000000001490020000000028002000300042e50000007d000004e2000004e200000000001490020000000038003000300029a68000007d000004e2000004e20000000000149002000000004800200020009c400000005dc00001be400001be40000000001490020000003e80000000000009c40000005dc0000186a0000186a0000000001490020000003e90000000000009c40000005dc0000186a0000186a0000000001470007400002
DEBUG: sllurp: llrp_proto.py 2113  decode_LLRPStatus (type=287 len=8)
DEBUG: sllurp: llrp_proto.py 2157  decode_FieldError
DEBUG: sllurp: llrp_proto.py 2190  decode_ParameterError
DEBUG: sllurp: llrp_proto.py 1166  decode_GeneralDeviceCapabilities
DEBUG: sllurp: llrp_proto.py 1178  decode_GeneralDeviceCapabilities (type=137 len=407)
DEBUG: sllurp: llrp_proto.py 1266  decode_ReceiveSensitivityTableEntry
DEBUG: sllurp: llrp_proto.py 1276  decode_ReceiveSensitivityTableEntry (type=139 len=8)
DEBUG: sllurp: llrp_proto.py 1295  decode_PerAntennaReceiveSensitivityRange
DEBUG: sllurp: llrp_proto.py 1364  decode_GPIOCapabilities
DEBUG: sllurp: llrp_proto.py 1326  decode_PerAntennaAirProtocol
DEBUG: sllurp: llrp_proto.py 1239  decode_MaximumReceiveSensitivity
DEBUG: sllurp: llrp_proto.py 1111  decode_LLRPCapabilities
DEBUG: sllurp: llrp_proto.py 1123  decode_LLRPCapabilities (type=142 len=28)
DEBUG: sllurp: llrp_proto.py 757  decode_RegulatoryCapabilities
DEBUG: sllurp: llrp_proto.py 769  decode_RegulatoryCapabilities (type=143 len=1053)
DEBUG: sllurp: llrp_proto.py 797  decode_UHFBandCapabilities
DEBUG: sllurp: llrp_proto.py 807  decode_UHFBandCapabilities (type=144 len=1045)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 853  decode_TransmitPowerLevelTableEntry (type=145 len=8)
DEBUG: sllurp: llrp_proto.py 843  decode_TransmitPowerLevelTableEntry
DEBUG: sllurp: llrp_proto.py 872  decode_FrequencyInformation
DEBUG: sllurp: llrp_proto.py 882  decode_FrequencyInformation (type=146 len=213)
DEBUG: sllurp: llrp_proto.py 915  decode_FrequencyHopTable
DEBUG: sllurp: llrp_proto.py 925  decode_FrequencyHopTable (type=147 len=208)
DEBUG: sllurp: llrp_proto.py 915  decode_FrequencyHopTable
DEBUG: sllurp: llrp_proto.py 872  decode_FrequencyInformation
DEBUG: sllurp: llrp_proto.py 994  decode_UHFRFModeTable
DEBUG: sllurp: llrp_proto.py 1001  decode_UHFRFModeTable (type=328 len=228)
DEBUG: sllurp: llrp_proto.py 1007  decode_UHFRFModeTable (type=328 len=228)
DEBUG: sllurp: llrp_proto.py 1029  decode_UHFC1G2RFModeTableEntry
DEBUG: sllurp: llrp_proto.py 1036  decode_UHFC1G2RFModeTableEntry (type=329 len=32)
DEBUG: sllurp: llrp_proto.py 1029  decode_UHFC1G2RFModeTableEntry
DEBUG: sllurp: llrp_proto.py 1036  decode_UHFC1G2RFModeTableEntry (type=329 len=32)
DEBUG: sllurp: llrp_proto.py 1029  decode_UHFC1G2RFModeTableEntry
DEBUG: sllurp: llrp_proto.py 1036  decode_UHFC1G2RFModeTableEntry (type=329 len=32)
DEBUG: sllurp: llrp_proto.py 1029  decode_UHFC1G2RFModeTableEntry
DEBUG: sllurp: llrp_proto.py 1036  decode_UHFC1G2RFModeTableEntry (type=329 len=32)
DEBUG: sllurp: llrp_proto.py 1029  decode_UHFC1G2RFModeTableEntry
DEBUG: sllurp: llrp_proto.py 1036  decode_UHFC1G2RFModeTableEntry (type=329 len=32)
DEBUG: sllurp: llrp_proto.py 1029  decode_UHFC1G2RFModeTableEntry
DEBUG: sllurp: llrp_proto.py 1036  decode_UHFC1G2RFModeTableEntry (type=329 len=32)
DEBUG: sllurp: llrp_proto.py 1029  decode_UHFC1G2RFModeTableEntry
DEBUG: sllurp: llrp_proto.py 1036  decode_UHFC1G2RFModeTableEntry (type=329 len=32)
DEBUG: sllurp: llrp_proto.py 1029  decode_UHFC1G2RFModeTableEntry
DEBUG: sllurp: llrp_proto.py 1079  decode_RFSurveyFrequencyCapabilities
DEBUG: sllurp: llrp.py 89  done deserializing GET_READER_CAPABILITIES_RESPONSE command
DEBUG: sllurp: llrp.py 270  LLRPMessage received in state 8: <GET_READER_CAPABILITIES_RESPONSE>
    <Ver>1</Ver>
    <Type>11</Type>
    <ID>0</ID>
    <LLRPStatus>
        <StatusCode>Success</StatusCode>
        <ErrorDescription></ErrorDescription>
    </LLRPStatus>
    <GeneralDeviceCapabilities>
        <MaxNumberOfAntennaSupported>4</MaxNumberOfAntennaSupported>
        <CanSetAntennaProperties>False</CanSetAntennaProperties>
        <HasUTCClockCapability>True</HasUTCClockCapability>
        <DeviceManufacturerName>25882</DeviceManufacturerName>
        <ModelName>2001003</ModelName>
        <FirmwareVersionByteCount>9</FirmwareVersionByteCount>
        <ReaderFirmwareVersion>4.8.3.240</ReaderFirmwareVersion>
        <ReceiveSensitivityTableEntry>
            <Index>1</Index>
            <ReceiveSensitivityValue>0</ReceiveSensitivityValue>
        </ReceiveSensitivityTableEntry>
    </GeneralDeviceCapabilities>
    <LLRPCapabilities>
        <CanDoRFSurvey>False</CanDoRFSurvey>
        <CanReportBufferFillWarning>True</CanReportBufferFillWarning>
        <SupportsClientRequestOpSpec>False</SupportsClientRequestOpSpec>
        <CanDoTagInventoryStateAwareSingulation>False</CanDoTagInventoryStateAwareSingulation>
        <SupportsEventAndReportHolding>True</SupportsEventAndReportHolding>
        <MaxPriorityLevelSupported>1</MaxPriorityLevelSupported>
        <ClientRequestOpSpecTimeout>0</ClientRequestOpSpecTimeout>
        <MaxNumROSpec>1</MaxNumROSpec>
        <MaxNumSpecsPerROSpec>16</MaxNumSpecsPerROSpec>
        <MaxNumInventoryParametersSpecsPerAISpec>1</MaxNumInventoryParametersSpecsPerAISpec>
        <MaxNumAccessSpec>1508</MaxNumAccessSpec>
        <MaxNumOpSpecsPerAccessSpec>16</MaxNumOpSpecsPerAccessSpec>
    </LLRPCapabilities>
    <RegulatoryCapabilities>
        <CountryCode>840</CountryCode>
        <CommunicationsStandard>1</CommunicationsStandard>
        <UHFBandCapabilities>
            <FrequencyInformation>
                <Hopping>True</Hopping>
            </FrequencyInformation>
            <UHFRFModeTable>
            </UHFRFModeTable>
        </UHFBandCapabilities>
    </RegulatoryCapabilities>
    <AirProtocolLLRPCapabilities>๏ฟฝG๏ฟฝ@</AirProtocolLLRPCapabilities>
</GET_READER_CAPABILITIES_RESPONSE>
DEBUG: sllurp: llrp.py 275  starting message callbacks for GET_READER_CAPABILITIES_RESPONSE
DEBUG: sllurp: llrp.py 278  done with message callbacks for GET_READER_CAPABILITIES_RESPONSE
DEBUG: sllurp: llrp.py 285  in handleMessage(GET_READER_CAPABILITIES_RESPONSE), there are 1 Deferreds
DEBUG: sllurp: llrp.py 336  Capabilities: {'AirProtocolLLRPCapabilities': '\x01G\x00\x07@\x00\x02',
 'GeneralDeviceCapabilities': {'CanSetAntennaProperties': False,
                               'DeviceManufacturerName': 25882,
                               'FirmwareVersionByteCount': 9,
                               'HasUTCClockCapability': True,
                               'MaxNumberOfAntennaSupported': 4,
                               'ModelName': 2001003,
                               'ReaderFirmwareVersion': '4.8.3.240',
                               'ReceiveSensitivityTableEntry': {'Index': 1,
                                                                'ReceiveSensitivityValue': 0}},
 'ID': 0,
 'LLRPCapabilities': {'CanDoRFSurvey': False,
                      'CanDoTagInventoryStateAwareSingulation': False,
                      'CanReportBufferFillWarning': True,
                      'ClientRequestOpSpecTimeout': 0,
                      'MaxNumAccessSpec': 1508,
                      'MaxNumInventoryParametersSpecsPerAISpec': 1,
                      'MaxNumOpSpecsPerAccessSpec': 16,
                      'MaxNumROSpec': 1,
                      'MaxNumSpecsPerROSpec': 16,
                      'MaxPriorityLevelSupported': 1,
                      'SupportsClientRequestOpSpec': False,
                      'SupportsEventAndReportHolding': True},
 'LLRPStatus': {'ErrorDescription': '', 'StatusCode': 'Success'},
 'RegulatoryCapabilities': {'CommunicationsStandard': 1,
                            'CountryCode': 840,
                            'UHFBandCapabilities': {'FrequencyInformation': {'FrequencyHopTable0': {'Frequency1': (922250,),
                                                                                                    'Frequency10': (905750,),
                                                                                                    'Frequency11': (909250,),
                                                                                                    'Frequency12': (908250,),
                                                                                                    'Frequency13': (925250,),
                                                                                                    'Frequency14': (907750,),
                                                                                                    'Frequency15': (902750,),
                                                                                                    'Frequency16': (923750,),
                                                                                                    'Frequency17': (924250,),
                                                                                                    'Frequency18': (925750,),
                                                                                                    'Frequency19': (914250,),
                                                                                                    'Frequency2': (923250,),
                                                                                                    'Frequency20': (905250,),
                                                                                                    'Frequency21': (919750,),
                                                                                                    'Frequency22': (906750,),
                                                                                                    'Frequency23': (915750,),
                                                                                                    'Frequency24': (918750,),
                                                                                                    'Frequency25': (917250,),
                                                                                                    'Frequency26': (910250,),
                                                                                                    'Frequency27': (916750,),
                                                                                                    'Frequency28': (909750,),
                                                                                                    'Frequency29': (921250,),
                                                                                                    'Frequency3': (914750,),
                                                                                                    'Frequency30': (921750,),
                                                                                                    'Frequency31': (903250,),
                                                                                                    'Frequency32': (915250,),
                                                                                                    'Frequency33': (912750,),
                                                                                                    'Frequency34': (920750,),
                                                                                                    'Frequency35': (913250,),
                                                                                                    'Frequency36': (920250,),
                                                                                                    'Frequency37': (911250,),
                                                                                                    'Frequency38': (912250,),
                                                                                                    'Frequency39': (911750,),
                                                                                                    'Frequency4': (910750,),
                                                                                                    'Frequency40': (918250,),
                                                                                                    'Frequency41': (922750,),
                                                                                                    'Frequency42': (908750,),
                                                                                                    'Frequency43': (919250,),
                                                                                                    'Frequency44': (924750,),
                                                                                                    'Frequency45': (917750,),
                                                                                                    'Frequency46': (913750,),
                                                                                                    'Frequency47': (926250,),
                                                                                                    'Frequency48': (904750,),
                                                                                                    'Frequency49': (903750,),
                                                                                                    'Frequency5': (927250,),
                                                                                                    'Frequency50': (907250,),
                                                                                                    'Frequency6': (906250,),
                                                                                                    'Frequency7': (904250,),
                                                                                                    'Frequency8': (926750,),
                                                                                                    'Frequency9': (916250,),
                                                                                                    'HopTableId': 1,
                                                                                                    'NumHops': 50},
                                                                             'Hopping': True},
                                                    'TransmitPowerLevelTableEntry0': {'Index': 1,
                                                                                      'TransmitPowerValue': 1000},
                                                    'TransmitPowerLevelTableEntry1': {'Index': 2,
                                                                                      'TransmitPowerValue': 1025},
                                                    'TransmitPowerLevelTableEntry10': {'Index': 11,
                                                                                       'TransmitPowerValue': 1250},
                                                    'TransmitPowerLevelTableEntry11': {'Index': 12,
                                                                                       'TransmitPowerValue': 1275},
                                                    'TransmitPowerLevelTableEntry12': {'Index': 13,
                                                                                       'TransmitPowerValue': 1300},
                                                    'TransmitPowerLevelTableEntry13': {'Index': 14,
                                                                                       'TransmitPowerValue': 1325},
                                                    'TransmitPowerLevelTableEntry14': {'Index': 15,
                                                                                       'TransmitPowerValue': 1350},
                                                    'TransmitPowerLevelTableEntry15': {'Index': 16,
                                                                                       'TransmitPowerValue': 1375},
                                                    'TransmitPowerLevelTableEntry16': {'Index': 17,
                                                                                       'TransmitPowerValue': 1400},
                                                    'TransmitPowerLevelTableEntry17': {'Index': 18,
                                                                                       'TransmitPowerValue': 1425},
                                                    'TransmitPowerLevelTableEntry18': {'Index': 19,
                                                                                       'TransmitPowerValue': 1450},
                                                    'TransmitPowerLevelTableEntry19': {'Index': 20,
                                                                                       'TransmitPowerValue': 1475},
                                                    'TransmitPowerLevelTableEntry2': {'Index': 3,
                                                                                      'TransmitPowerValue': 1050},
                                                    'TransmitPowerLevelTableEntry20': {'Index': 21,
                                                                                       'TransmitPowerValue': 1500},
                                                    'TransmitPowerLevelTableEntry21': {'Index': 22,
                                                                                       'TransmitPowerValue': 1525},
                                                    'TransmitPowerLevelTableEntry22': {'Index': 23,
                                                                                       'TransmitPowerValue': 1550},
                                                    'TransmitPowerLevelTableEntry23': {'Index': 24,
                                                                                       'TransmitPowerValue': 1575},
                                                    'TransmitPowerLevelTableEntry24': {'Index': 25,
                                                                                       'TransmitPowerValue': 1600},
                                                    'TransmitPowerLevelTableEntry25': {'Index': 26,
                                                                                       'TransmitPowerValue': 1625},
                                                    'TransmitPowerLevelTableEntry26': {'Index': 27,
                                                                                       'TransmitPowerValue': 1650},
                                                    'TransmitPowerLevelTableEntry27': {'Index': 28,
                                                                                       'TransmitPowerValue': 1675},
                                                    'TransmitPowerLevelTableEntry28': {'Index': 29,
                                                                                       'TransmitPowerValue': 1700},
                                                    'TransmitPowerLevelTableEntry29': {'Index': 30,
                                                                                       'TransmitPowerValue': 1725},
                                                    'TransmitPowerLevelTableEntry3': {'Index': 4,
                                                                                      'TransmitPowerValue': 1075},
                                                    'TransmitPowerLevelTableEntry30': {'Index': 31,
                                                                                       'TransmitPowerValue': 1750},
                                                    'TransmitPowerLevelTableEntry31': {'Index': 32,
                                                                                       'TransmitPowerValue': 1775},
                                                    'TransmitPowerLevelTableEntry32': {'Index': 33,
                                                                                       'TransmitPowerValue': 1800},
                                                    'TransmitPowerLevelTableEntry33': {'Index': 34,
                                                                                       'TransmitPowerValue': 1825},
                                                    'TransmitPowerLevelTableEntry34': {'Index': 35,
                                                                                       'TransmitPowerValue': 1850},
                                                    'TransmitPowerLevelTableEntry35': {'Index': 36,
                                                                                       'TransmitPowerValue': 1875},
                                                    'TransmitPowerLevelTableEntry36': {'Index': 37,
                                                                                       'TransmitPowerValue': 1900},
                                                    'TransmitPowerLevelTableEntry37': {'Index': 38,
                                                                                       'TransmitPowerValue': 1925},
                                                    'TransmitPowerLevelTableEntry38': {'Index': 39,
                                                                                       'TransmitPowerValue': 1950},
                                                    'TransmitPowerLevelTableEntry39': {'Index': 40,
                                                                                       'TransmitPowerValue': 1975},
                                                    'TransmitPowerLevelTableEntry4': {'Index': 5,
                                                                                      'TransmitPowerValue': 1100},
                                                    'TransmitPowerLevelTableEntry40': {'Index': 41,
                                                                                       'TransmitPowerValue': 2000},
                                                    'TransmitPowerLevelTableEntry41': {'Index': 42,
                                                                                       'TransmitPowerValue': 2025},
                                                    'TransmitPowerLevelTableEntry42': {'Index': 43,
                                                                                       'TransmitPowerValue': 2050},
                                                    'TransmitPowerLevelTableEntry43': {'Index': 44,
                                                                                       'TransmitPowerValue': 2075},
                                                    'TransmitPowerLevelTableEntry44': {'Index': 45,
                                                                                       'TransmitPowerValue': 2100},
                                                    'TransmitPowerLevelTableEntry45': {'Index': 46,
                                                                                       'TransmitPowerValue': 2125},
                                                    'TransmitPowerLevelTableEntry46': {'Index': 47,
                                                                                       'TransmitPowerValue': 2150},
                                                    'TransmitPowerLevelTableEntry47': {'Index': 48,
                                                                                       'TransmitPowerValue': 2175},
                                                    'TransmitPowerLevelTableEntry48': {'Index': 49,
                                                                                       'TransmitPowerValue': 2200},
                                                    'TransmitPowerLevelTableEntry49': {'Index': 50,
                                                                                       'TransmitPowerValue': 2225},
                                                    'TransmitPowerLevelTableEntry5': {'Index': 6,
                                                                                      'TransmitPowerValue': 1125},
                                                    'TransmitPowerLevelTableEntry50': {'Index': 51,
                                                                                       'TransmitPowerValue': 2250},
                                                    'TransmitPowerLevelTableEntry51': {'Index': 52,
                                                                                       'TransmitPowerValue': 2275},
                                                    'TransmitPowerLevelTableEntry52': {'Index': 53,
                                                                                       'TransmitPowerValue': 2300},
                                                    'TransmitPowerLevelTableEntry53': {'Index': 54,
                                                                                       'TransmitPowerValue': 2325},
                                                    'TransmitPowerLevelTableEntry54': {'Index': 55,
                                                                                       'TransmitPowerValue': 2350},
                                                    'TransmitPowerLevelTableEntry55': {'Index': 56,
                                                                                       'TransmitPowerValue': 2375},
                                                    'TransmitPowerLevelTableEntry56': {'Index': 57,
                                                                                       'TransmitPowerValue': 2400},
                                                    'TransmitPowerLevelTableEntry57': {'Index': 58,
                                                                                       'TransmitPowerValue': 2425},
                                                    'TransmitPowerLevelTableEntry58': {'Index': 59,
                                                                                       'TransmitPowerValue': 2450},
                                                    'TransmitPowerLevelTableEntry59': {'Index': 60,
                                                                                       'TransmitPowerValue': 2475},
                                                    'TransmitPowerLevelTableEntry6': {'Index': 7,
                                                                                      'TransmitPowerValue': 1150},
                                                    'TransmitPowerLevelTableEntry60': {'Index': 61,
                                                                                       'TransmitPowerValue': 2500},
                                                    'TransmitPowerLevelTableEntry61': {'Index': 62,
                                                                                       'TransmitPowerValue': 2525},
                                                    'TransmitPowerLevelTableEntry62': {'Index': 63,
                                                                                       'TransmitPowerValue': 2550},
                                                    'TransmitPowerLevelTableEntry63': {'Index': 64,
                                                                                       'TransmitPowerValue': 2575},
                                                    'TransmitPowerLevelTableEntry64': {'Index': 65,
                                                                                       'TransmitPowerValue': 2600},
                                                    'TransmitPowerLevelTableEntry65': {'Index': 66,
                                                                                       'TransmitPowerValue': 2625},
                                                    'TransmitPowerLevelTableEntry66': {'Index': 67,
                                                                                       'TransmitPowerValue': 2650},
                                                    'TransmitPowerLevelTableEntry67': {'Index': 68,
                                                                                       'TransmitPowerValue': 2675},
                                                    'TransmitPowerLevelTableEntry68': {'Index': 69,
                                                                                       'TransmitPowerValue': 2700},
                                                    'TransmitPowerLevelTableEntry69': {'Index': 70,
                                                                                       'TransmitPowerValue': 2725},
                                                    'TransmitPowerLevelTableEntry7': {'Index': 8,
                                                                                      'TransmitPowerValue': 1175},
                                                    'TransmitPowerLevelTableEntry70': {'Index': 71,
                                                                                       'TransmitPowerValue': 2750},
                                                    'TransmitPowerLevelTableEntry71': {'Index': 72,
                                                                                       'TransmitPowerValue': 2775},
                                                    'TransmitPowerLevelTableEntry72': {'Index': 73,
                                                                                       'TransmitPowerValue': 2800},
                                                    'TransmitPowerLevelTableEntry73': {'Index': 74,
                                                                                       'TransmitPowerValue': 2825},
                                                    'TransmitPowerLevelTableEntry74': {'Index': 75,
                                                                                       'TransmitPowerValue': 2850},
                                                    'TransmitPowerLevelTableEntry8': {'Index': 9,
                                                                                      'TransmitPowerValue': 1200},
                                                    'TransmitPowerLevelTableEntry9': {'Index': 10,
                                                                                      'TransmitPowerValue': 1225},
                                                    'UHFRFModeTable': {'UHFC1G2RFModeTableEntry0': {'BDR': 640000,
                                                                                                    'C': 0,
                                                                                                    'FLM': 2,
                                                                                                    'M': 2,
                                                                                                    'MaxTari': 6250,
                                                                                                    'MinTari': 6250,
                                                                                                    'Mod': 0,
                                                                                                    'ModeIdentifier': 0,
                                                                                                    'PIE': 1500,
                                                                                                    'R': 1,
                                                                                                    'StepTari': 0},
                                                                       'UHFC1G2RFModeTableEntry1': {'BDR': 640000,
                                                                                                    'C': 0,
                                                                                                    'FLM': 2,
                                                                                                    'M': 2,
                                                                                                    'MaxTari': 6250,
                                                                                                    'MinTari': 6250,
                                                                                                    'Mod': 1,
                                                                                                    'ModeIdentifier': 1,
                                                                                                    'PIE': 1500,
                                                                                                    'R': 1,
                                                                                                    'StepTari': 0},
                                                                       'UHFC1G2RFModeTableEntry2': {'BDR': 274000,
                                                                                                    'C': 0,
                                                                                                    'FLM': 0,
                                                                                                    'M': 3,
                                                                                                    'MaxTari': 20000,
                                                                                                    'MinTari': 20000,
                                                                                                    'Mod': 2,
                                                                                                    'ModeIdentifier': 2,
                                                                                                    'PIE': 2000,
                                                                                                    'R': 1,
                                                                                                    'StepTari': 0},
                                                                       'UHFC1G2RFModeTableEntry3': {'BDR': 170600,
                                                                                                    'C': 0,
                                                                                                    'FLM': 0,
                                                                                                    'M': 3,
                                                                                                    'MaxTari': 20000,
                                                                                                    'MinTari': 20000,
                                                                                                    'Mod': 3,
                                                                                                    'ModeIdentifier': 3,
                                                                                                    'PIE': 2000,
                                                                                                    'R': 1,
                                                                                                    'StepTari': 0},
                                                                       'UHFC1G2RFModeTableEntry4': {'BDR': 640000,
                                                                                                    'C': 0,
                                                                                                    'FLM': 0,
                                                                                                    'M': 2,
                                                                                                    'MaxTari': 7140,
                                                                                                    'MinTari': 7140,
                                                                                                    'Mod': 2,
                                                                                                    'ModeIdentifier': 4,
                                                                                                    'PIE': 1500,
                                                                                                    'R': 1,
                                                                                                    'StepTari': 0},
                                                                       'UHFC1G2RFModeTableEntry5': {'BDR': 40000,
                                                                                                    'C': 0,
                                                                                                    'FLM': 0,
                                                                                                    'M': 0,
                                                                                                    'MaxTari': 6250,
                                                                                                    'MinTari': 6250,
                                                                                                    'Mod': 0,
                                                                                                    'ModeIdentifier': 1000,
                                                                                                    'PIE': 1500,
                                                                                                    'R': 0,
                                                                                                    'StepTari': 0},
                                                                       'UHFC1G2RFModeTableEntry6': {'BDR': 40000,
                                                                                                    'C': 0,
                                                                                                    'FLM': 0,
                                                                                                    'M': 0,
                                                                                                    'MaxTari': 6250,
                                                                                                    'MinTari': 6250,
                                                                                                    'Mod': 0,
                                                                                                    'ModeIdentifier': 1001,
                                                                                                    'PIE': 1500,
                                                                                                    'R': 0,
                                                                                                    'StepTari': 0}}}},
 'Type': 11,
 'Ver': 1}
DEBUG: sllurp: llrp.py 237  requested tx_power: 0
DEBUG: sllurp: llrp.py 253  set tx_power: 75 (28.5 dBm)
DEBUG: sllurp: llrp.py 260  running 1 Deferreds for GET_READER_CAPABILITIES_RESPONSE; isSuccess=True
DEBUG: sllurp: llrp.py 206  state change: STATE_SENT_GET_CAPABILITIES -> STATE_CONNECTED
INFO: sllurp: llrp.py 535  stopping politely
DEBUG: sllurp: llrp.py 48  serializing DELETE_ROSPEC command
DEBUG: sllurp: llrp.py 62  serialized bytes: 04150000000e0000000000000000
DEBUG: sllurp: llrp.py 63  done serializing DELETE_ROSPEC command
DEBUG: sllurp: llrp.py 206  state change: STATE_CONNECTED -> STATE_SENT_DELETE_ROSPEC
DEBUG: sllurp: llrp_proto.py 2647  will report every ~N=100 tags
DEBUG: sllurp: llrp.py 529  ROSpec: <ROSpec>
    <ROSpecID>1</ROSpecID>
    <Priority>0</Priority>
    <CurrentState>Disabled</CurrentState>
    <ROBoundarySpec>
        <ROSpecStartTrigger>
            <ROSpecStartTriggerType>Immediate</ROSpecStartTriggerType>
        </ROSpecStartTrigger>
        <ROSpecStopTrigger>
            <ROSpecStopTriggerType>Null</ROSpecStopTriggerType>
            <DurationTriggerValue>0</DurationTriggerValue>
        </ROSpecStopTrigger>
    </ROBoundarySpec>
    <AISpec>
        <AntennaIDs>1 2 3 4</AntennaIDs>
        <AISpecStopTrigger>
            <AISpecStopTriggerType>Duration</AISpecStopTriggerType>
            <DurationTriggerValue>500</DurationTriggerValue>
        </AISpecStopTrigger>
        <InventoryParameterSpec>
            <InventoryParameterSpecID>1</InventoryParameterSpecID>
            <ProtocolID>1</ProtocolID>
            <AntennaConfiguration>
                <AntennaID>1</AntennaID>
                <RFTransmitter>
                    <HopTableId>1</HopTableId>
                    <ChannelIndex>0</ChannelIndex>
                    <TransmitPower>75</TransmitPower>
                </RFTransmitter>
                <C1G2InventoryCommand>
                    <TagInventoryStateAware>False</TagInventoryStateAware>
                    <C1G2RFControl>
                        <ModeIndex>2</ModeIndex>
                        <Tari>0</Tari>
                    </C1G2RFControl>
                    <C1G2SingulationControl>
                        <Session>0</Session>
                        <TagPopulation>4</TagPopulation>
                        <TagTransitTime>0</TagTransitTime>
                    </C1G2SingulationControl>
                </C1G2InventoryCommand>
            </AntennaConfiguration>
            <AntennaConfiguration>
                <AntennaID>2</AntennaID>
                <RFTransmitter>
                    <HopTableId>1</HopTableId>
                    <ChannelIndex>0</ChannelIndex>
                    <TransmitPower>75</TransmitPower>
                </RFTransmitter>
                <C1G2InventoryCommand>
                    <TagInventoryStateAware>False</TagInventoryStateAware>
                    <C1G2RFControl>
                        <ModeIndex>2</ModeIndex>
                        <Tari>0</Tari>
                    </C1G2RFControl>
                    <C1G2SingulationControl>
                        <Session>0</Session>
                        <TagPopulation>4</TagPopulation>
                        <TagTransitTime>0</TagTransitTime>
                    </C1G2SingulationControl>
                </C1G2InventoryCommand>
            </AntennaConfiguration>
            <AntennaConfiguration>
                <AntennaID>3</AntennaID>
                <RFTransmitter>
                    <HopTableId>1</HopTableId>
                    <ChannelIndex>0</ChannelIndex>
                    <TransmitPower>75</TransmitPower>
                </RFTransmitter>
                <C1G2InventoryCommand>
                    <TagInventoryStateAware>False</TagInventoryStateAware>
                    <C1G2RFControl>
                        <ModeIndex>2</ModeIndex>
                        <Tari>0</Tari>
                    </C1G2RFControl>
                    <C1G2SingulationControl>
                        <Session>0</Session>
                        <TagPopulation>4</TagPopulation>
                        <TagTransitTime>0</TagTransitTime>
                    </C1G2SingulationControl>
                </C1G2InventoryCommand>
            </AntennaConfiguration>
            <AntennaConfiguration>
                <AntennaID>4</AntennaID>
                <RFTransmitter>
                    <HopTableId>1</HopTableId>
                    <ChannelIndex>0</ChannelIndex>
                    <TransmitPower>75</TransmitPower>
                </RFTransmitter>
                <C1G2InventoryCommand>
                    <TagInventoryStateAware>False</TagInventoryStateAware>
                    <C1G2RFControl>
                        <ModeIndex>2</ModeIndex>
                        <Tari>0</Tari>
                    </C1G2RFControl>
                    <C1G2SingulationControl>
                        <Session>0</Session>
                        <TagPopulation>4</TagPopulation>
                        <TagTransitTime>0</TagTransitTime>
                    </C1G2SingulationControl>
                </C1G2InventoryCommand>
            </AntennaConfiguration>
        </InventoryParameterSpec>
    </AISpec>
    <ROReportSpec>
        <N>100</N>
        <ROReportTrigger>Upon_N_Tags_Or_End_Of_AISpec</ROReportTrigger>
        <TagReportContentSelector>
            <EnableROSpecID>False</EnableROSpecID>
            <EnableSpecIndex>False</EnableSpecIndex>
            <EnableInventoryParameterSpecID>False</EnableInventoryParameterSpecID>
            <EnableAntennaID>True</EnableAntennaID>
            <EnableChannelIndex>False</EnableChannelIndex>
            <EnablePeakRRSI>True</EnablePeakRRSI>
            <EnableFirstSeenTimestamp>False</EnableFirstSeenTimestamp>
            <EnableLastSeenTimestamp>True</EnableLastSeenTimestamp>
            <EnableTagSeenCount>True</EnableTagSeenCount>
            <EnableAccessSpecID>False</EnableAccessSpecID>
        </TagReportContentSelector>
    </ROReportSpec>
</ROSpec>
DEBUG: sllurp: llrp.py 48  serializing ADD_ROSPEC command
DEBUG: sllurp: llrp_proto.py 1603  encoding AntennaConfiguration: {'C1G2InventoryCommand': {'TagInventoryStateAware': False, 'C1G2RFControl': {'ModeIndex': 2, 'Tari': 0}, 'C1G2SingulationControl': {'TagPopulation': 4, 'Session': 0, 'TagTransitTime': 0}}, 'AntennaID': 1, 'RFTransmitter': {'TransmitPower': 75, 'HopTableId': 1, 'ChannelIndex': 0}}
DEBUG: sllurp: llrp_proto.py 1603  encoding AntennaConfiguration: {'C1G2InventoryCommand': {'TagInventoryStateAware': False, 'C1G2RFControl': {'ModeIndex': 2, 'Tari': 0}, 'C1G2SingulationControl': {'TagPopulation': 4, 'Session': 0, 'TagTransitTime': 0}}, 'AntennaID': 2, 'RFTransmitter': {'TransmitPower': 75, 'HopTableId': 1, 'ChannelIndex': 0}}
DEBUG: sllurp: llrp_proto.py 1603  encoding AntennaConfiguration: {'C1G2InventoryCommand': {'TagInventoryStateAware': False, 'C1G2RFControl': {'ModeIndex': 2, 'Tari': 0}, 'C1G2SingulationControl': {'TagPopulation': 4, 'Session': 0, 'TagTransitTime': 0}}, 'AntennaID': 3, 'RFTransmitter': {'TransmitPower': 75, 'HopTableId': 1, 'ChannelIndex': 0}}
DEBUG: sllurp: llrp_proto.py 1603  encoding AntennaConfiguration: {'C1G2InventoryCommand': {'TagInventoryStateAware': False, 'C1G2RFControl': {'ModeIndex': 2, 'Tari': 0}, 'C1G2SingulationControl': {'TagPopulation': 4, 'Session': 0, 'TagTransitTime': 0}}, 'AntennaID': 4, 'RFTransmitter': {'TransmitPower': 75, 'HopTableId': 1, 'ChannelIndex': 0}}
DEBUG: sllurp: llrp.py 62  serialized bytes: 0414000000f10000000000b100e700000001000000b2001200b300050100b60009000000000000b700be0004000100020003000400b8000901000001f400ba00a700010100de0028000100e0000a00010000004b014a001800014f0008000200000150000b0000040000000000de0028000200e0000a00010000004b014a001800014f0008000200000150000b0000040000000000de0028000300e0000a00010000004b014a001800014f0008000200000150000b0000040000000000de0028000400e0000a00010000004b014a001800014f0008000200000150000b0000040000000000ed000d01006400ee00061580
DEBUG: sllurp: llrp.py 63  done serializing ADD_ROSPEC command
DEBUG: sllurp: llrp.py 206  state change: STATE_SENT_DELETE_ROSPEC -> STATE_SENT_ADD_ROSPEC
DEBUG: sllurp: llrp.py 421  got 18 bytes from reader: 041f0000001200000000011f000800000000
DEBUG: sllurp: llrp.py 439  expect 18 bytes (have 18)
DEBUG: sllurp: llrp.py 76  deserializing DELETE_ROSPEC_RESPONSE command
DEBUG: sllurp: llrp_proto.py 422  decode_DeleteROSpecResponse
DEBUG: sllurp: llrp_proto.py 2097  decode_LLRPStatus
DEBUG: sllurp: llrp_proto.py 2099  decode_LLRPStatus: 011f000800000000
DEBUG: sllurp: llrp_proto.py 2113  decode_LLRPStatus (type=287 len=8)
DEBUG: sllurp: llrp_proto.py 2157  decode_FieldError
DEBUG: sllurp: llrp_proto.py 2190  decode_ParameterError
DEBUG: sllurp: llrp.py 89  done deserializing DELETE_ROSPEC_RESPONSE command
DEBUG: sllurp: llrp.py 270  LLRPMessage received in state 4: <DELETE_ROSPEC_RESPONSE>
    <Ver>1</Ver>
    <Type>31</Type>
    <ID>0</ID>
    <LLRPStatus>
        <StatusCode>Success</StatusCode>
        <ErrorDescription></ErrorDescription>
    </LLRPStatus>
</DELETE_ROSPEC_RESPONSE>
DEBUG: sllurp: llrp.py 275  starting message callbacks for DELETE_ROSPEC_RESPONSE
DEBUG: sllurp: llrp.py 278  done with message callbacks for DELETE_ROSPEC_RESPONSE
DEBUG: sllurp: llrp.py 285  in handleMessage(DELETE_ROSPEC_RESPONSE), there are 1 Deferreds
ERROR: sllurp: llrp.py 355  unexpected response DELETE_ROSPEC_RESPONSE  when adding ROSpec
DEBUG: sllurp: llrp.py 421  got 18 bytes from reader: 041e0000001200000000011f000800000000
DEBUG: sllurp: llrp.py 439  expect 18 bytes (have 18)
DEBUG: sllurp: llrp.py 76  deserializing ADD_ROSPEC_RESPONSE command
DEBUG: sllurp: llrp_proto.py 380  decode_AddROSpecResponse
DEBUG: sllurp: llrp_proto.py 2097  decode_LLRPStatus
DEBUG: sllurp: llrp_proto.py 2099  decode_LLRPStatus: 011f000800000000
DEBUG: sllurp: llrp_proto.py 2113  decode_LLRPStatus (type=287 len=8)
DEBUG: sllurp: llrp_proto.py 2157  decode_FieldError
DEBUG: sllurp: llrp_proto.py 2190  decode_ParameterError
DEBUG: sllurp: llrp.py 89  done deserializing ADD_ROSPEC_RESPONSE command
DEBUG: sllurp: llrp.py 270  LLRPMessage received in state 4: <ADD_ROSPEC_RESPONSE>
    <Ver>1</Ver>
    <Type>30</Type>
    <ID>0</ID>
    <LLRPStatus>
        <StatusCode>Success</StatusCode>
        <ErrorDescription></ErrorDescription>
    </LLRPStatus>
</ADD_ROSPEC_RESPONSE>
DEBUG: sllurp: llrp.py 275  starting message callbacks for ADD_ROSPEC_RESPONSE
DEBUG: sllurp: llrp.py 278  done with message callbacks for ADD_ROSPEC_RESPONSE
DEBUG: sllurp: llrp.py 285  in handleMessage(ADD_ROSPEC_RESPONSE), there are 1 Deferreds
DEBUG: sllurp: llrp.py 260  running 1 Deferreds for ADD_ROSPEC_RESPONSE; isSuccess=True
DEBUG: sllurp: llrp.py 48  serializing ENABLE_ROSPEC command
DEBUG: sllurp: llrp.py 62  serialized bytes: 04180000000e0000000000000001
DEBUG: sllurp: llrp.py 63  done serializing ENABLE_ROSPEC command
DEBUG: sllurp: llrp.py 206  state change: STATE_SENT_ADD_ROSPEC -> STATE_SENT_ENABLE_ROSPEC
DEBUG: sllurp: llrp.py 421  got 18 bytes from reader: 04220000001200000000011f000800000000
DEBUG: sllurp: llrp.py 439  expect 18 bytes (have 18)
DEBUG: sllurp: llrp.py 76  deserializing ENABLE_ROSPEC_RESPONSE command
DEBUG: sllurp: llrp_proto.py 548  decode_EnableROSpecResponse
DEBUG: sllurp: llrp_proto.py 2097  decode_LLRPStatus
DEBUG: sllurp: llrp_proto.py 2099  decode_LLRPStatus: 011f000800000000
DEBUG: sllurp: llrp_proto.py 2113  decode_LLRPStatus (type=287 len=8)
DEBUG: sllurp: llrp_proto.py 2157  decode_FieldError
DEBUG: sllurp: llrp_proto.py 2190  decode_ParameterError
DEBUG: sllurp: llrp.py 89  done deserializing ENABLE_ROSPEC_RESPONSE command
DEBUG: sllurp: llrp.py 270  LLRPMessage received in state 5: <ENABLE_ROSPEC_RESPONSE>
    <Ver>1</Ver>
    <Type>34</Type>
    <ID>0</ID>
    <LLRPStatus>
        <StatusCode>Success</StatusCode>
        <ErrorDescription></ErrorDescription>
    </LLRPStatus>
</ENABLE_ROSPEC_RESPONSE>
DEBUG: sllurp: llrp.py 275  starting message callbacks for ENABLE_ROSPEC_RESPONSE
DEBUG: sllurp: llrp.py 278  done with message callbacks for ENABLE_ROSPEC_RESPONSE
DEBUG: sllurp: llrp.py 285  in handleMessage(ENABLE_ROSPEC_RESPONSE), there are 1 Deferreds
DEBUG: sllurp: llrp.py 260  running 1 Deferreds for ENABLE_ROSPEC_RESPONSE; isSuccess=True
DEBUG: sllurp: llrp.py 206  state change: STATE_SENT_ENABLE_ROSPEC -> STATE_INVENTORYING
DEBUG: sllurp: llrp.py 421  got 146 bytes from reader: 043d000000921974f2b400f000228de280681000000039052d575d81000186be840004fa7915a43e4688000500f000228de280681000000039052d575d81000286bd840004fa7915a493e288000600f000228de280681000000039052d575d81000386be840004fa7915a4e3d288000200f000228de280681000000039052d575d81000486bc840004fa7915a3c360880004
DEBUG: sllurp: llrp.py 439  expect 146 bytes (have 146)
DEBUG: sllurp: llrp.py 76  deserializing RO_ACCESS_REPORT command
DEBUG: sllurp: llrp_proto.py 617  decode_ROAccessReport
DEBUG: sllurp: llrp_proto.py 619  RO_ACCESS_REPORT bytes: 00f000228de280681000000039052d575d81000186be840004fa7915a43e4688000500f000228de280681000000039052d575d81000286bd840004fa7915a493e288000600f000228de280681000000039052d575d81000386be840004fa7915a4e3d288000200f000228de280681000000039052d575d81000486bc840004fa7915a3c360880004
DEBUG: sllurp: llrp_proto.py 1838  decode_TagReportData
DEBUG: sllurp: llrp_proto.py 1839  TagReportData bytes: 00f000228de280681000000039052d575d81000186be840004fa7915a43e4688000500f000228de280681000000039052d575d81000286bd840004fa7915a493e288000600f000228de280681000000039052d575d81000386be840004fa7915a4e3d288000200f000228de280681000000039052d575d81000486bc840004fa7915a3c360880004
DEBUG: sllurp: llrp_proto.py 1857  failed to decode EPCData; trying EPC-96
DEBUG: sllurp: llrp_proto.py 1937  decode_EPC96 (type=13 len=13)
DEBUG: sllurp: llrp_proto.py 1838  decode_TagReportData
DEBUG: sllurp: llrp_proto.py 1839  TagReportData bytes: 00f000228de280681000000039052d575d81000286bd840004fa7915a493e288000600f000228de280681000000039052d575d81000386be840004fa7915a4e3d288000200f000228de280681000000039052d575d81000486bc840004fa7915a3c360880004
DEBUG: sllurp: llrp_proto.py 1857  failed to decode EPCData; trying EPC-96
DEBUG: sllurp: llrp_proto.py 1937  decode_EPC96 (type=13 len=13)
DEBUG: sllurp: llrp_proto.py 1838  decode_TagReportData
DEBUG: sllurp: llrp_proto.py 1839  TagReportData bytes: 00f000228de280681000000039052d575d81000386be840004fa7915a4e3d288000200f000228de280681000000039052d575d81000486bc840004fa7915a3c360880004
DEBUG: sllurp: llrp_proto.py 1857  failed to decode EPCData; trying EPC-96
DEBUG: sllurp: llrp_proto.py 1937  decode_EPC96 (type=13 len=13)
DEBUG: sllurp: llrp_proto.py 1838  decode_TagReportData
DEBUG: sllurp: llrp_proto.py 1839  TagReportData bytes: 00f000228de280681000000039052d575d81000486bc840004fa7915a3c360880004
DEBUG: sllurp: llrp_proto.py 1857  failed to decode EPCData; trying EPC-96
DEBUG: sllurp: llrp_proto.py 1937  decode_EPC96 (type=13 len=13)
DEBUG: sllurp: llrp_proto.py 1838  decode_TagReportData
DEBUG: sllurp: llrp_proto.py 1839  TagReportData bytes: 
DEBUG: sllurp: llrp.py 89  done deserializing RO_ACCESS_REPORT command
DEBUG: sllurp: llrp.py 270  LLRPMessage received in state 6: <RO_ACCESS_REPORT>
    <Ver>1</Ver>
    <Type>61</Type>
    <ID>427094708</ID>
    <TagReportData>
        <EPC-96>e280681000000039052d575d</EPC-96>
        <AntennaID>(1,)</AntennaID>
        <PeakRSSI>(-66,)</PeakRSSI>
        <LastSeenTimestampUTC>(1401297867914822,)</LastSeenTimestampUTC>
        <TagSeenCount>(5,)</TagSeenCount>
    </TagReportData>
    <TagReportData>
        <EPC-96>e280681000000039052d575d</EPC-96>
        <AntennaID>(2,)</AntennaID>
        <PeakRSSI>(-67,)</PeakRSSI>
        <LastSeenTimestampUTC>(1401297867936738,)</LastSeenTimestampUTC>
        <TagSeenCount>(6,)</TagSeenCount>
    </TagReportData>
    <TagReportData>
        <EPC-96>e280681000000039052d575d</EPC-96>
        <AntennaID>(3,)</AntennaID>
        <PeakRSSI>(-66,)</PeakRSSI>
        <LastSeenTimestampUTC>(1401297867957202,)</LastSeenTimestampUTC>
        <TagSeenCount>(2,)</TagSeenCount>
    </TagReportData>
    <TagReportData>
        <EPC-96>e280681000000039052d575d</EPC-96>
        <AntennaID>(4,)</AntennaID>
        <PeakRSSI>(-68,)</PeakRSSI>
        <LastSeenTimestampUTC>(1401297867883360,)</LastSeenTimestampUTC>
        <TagSeenCount>(4,)</TagSeenCount>
    </TagReportData>
</RO_ACCESS_REPORT>

remove LLRPReaderThread

The thread<->reactor relationship is too hard to get right. Base everything on the reactor's async event model instead.

Unbreak duration arg

Specifying LLRPClient.duration used to make LLRPClient call stopPolitely() after duration seconds, but since 7fd2559 we repurposed this duration member variable to control reporting period instead. This is a mess.

Lost Connection: Unpack requires a string argument of length 10

A frequent error has been occurring while running sllurp and causes a connection timeout. It seems that there is an issue with unpacking data and results in the error 'unpack requires a string argument of length 10'. I'm not sure what steps to take to resolve the issue. Below is copy of the error received,

Unhandled Error
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/twisted/python/log.py", line 88, in callWithLogger
    return callWithContext({"system": lp}, func, *args, **kw)
  File "/usr/local/lib/python2.7/site-packages/twisted/python/log.py", line 73, in callWithContext
    return context.call({ILogContext: newCtx}, func, *args, **kw)
  File "/usr/local/lib/python2.7/site-packages/twisted/python/context.py", line 118, in callWithContext
    return self.currentContext().callWithContext(ctx, func, *args, **kw)
  File "/usr/local/lib/python2.7/site-packages/twisted/python/context.py", line 81, in callWithContext
    return func(*args,**kw)
--- <exception caught here> ---
  File "/usr/local/lib/python2.7/site-packages/twisted/internet/selectreactor.py", line 149, in _doReadOrWrite
    why = getattr(selectable, method)()
  File "/usr/local/lib/python2.7/site-packages/twisted/internet/tcp.py", line 214, in doRead
    return self._dataReceived(data)
  File "/usr/local/lib/python2.7/site-packages/twisted/internet/tcp.py", line 220, in _dataReceived
    rval = self.protocol.dataReceived(data)
  File "/usr/local/lib/python2.7/site-packages/twisted/protocols/basic.py", line 578, in dataReceived
    why = self.rawDataReceived(data)
  File "/Users/zerina/sllurp/sllurp/llrp.py", line 508, in rawDataReceived
    data[:LLRPMessage.full_hdr_len])
struct.error: unpack requires a string argument of length 10
INFO:sllurp.llrp:lost connection: unpack requires a string argument of length 10

Declarative parsing of protocol messages

There's a huge amount of redundancy in the message encoding and decoding routines. Each message type currently has its own functions that pack & unpack binary representations -- including headers and other redundant stuff.

The right solution is to do most of the encoding and decoding work in a generic function that obeys a separate specification of message formats. This work is already started in the messages branch.

Upload to PyPi

Hello!

It would be great to see the package up on PyPi. The procedure is as follows:

pip install --upgrade pip
pip install wheel
pip install twine
python setup.py sdist bdist_wheel

#dist/ should now contain 2 files (.whl, .tar.gz)
twine upload -u USERNAME -p PASSWORD dist/*

It would make sense for the author of this package, @ransford, to upload this to https://pypi.python.org/pypi

Thanks!

Support callback arguments

LLRPClientFactory.addTagReportCallback(<callable>) should support args and keyword args to be provided to the callable.

Getting TID from RFID tags through LLRP readers (although not Impinj).

Hi! I would like to get the TID from the RFID tags through any LLRP reader (although not Impinj).

First of all, I don't know if it is possible, because I've seen that this data is requested in a Custom Parameter by the Octane SDK (Impinj) in LLRP frames. Any idea? Example:

image

Secondly, if I can request this data from any reader through a Custom Parameter in the ROSpec, how could I do it? I started the implementation of this field but I have some problems.

First, I defined the Custom Parameter struct:

Message_struct['CustomParameter'] = {
    'type': 1023,
    'fields': [
        'VendorID',
    #    'Subtype',
    #    'CustomParameter'
    ],
    'encode': encode_CustomParameter
}

Second, I've implemented the encoding function like yours:

def encode_CustomParameter(par):

    msgtype = Message_struct['CustomParameter']['type']

    msg_header = '!HH'

    flags = 0
    i = 15
    for field in Message_struct['CustomParameter']['fields']:
        if field in par and par[field]:
            print(field)
            flags = flags | (1 << i)
        i = i - 1

    data = struct.pack('!H', flags)
    data = struct.pack(msg_header, msgtype,
                       len(data) + struct.calcsize(msg_header)) + data

    return data

And then, I added the new field to the 'ROSpec':

# 16.2.7.1 ROReportSpec Parameter
def encode_ROReportSpec(par):
    msgtype = Message_struct['ROReportSpec']['type']
    n = int(par['N'])
    roReportTrigger = ROReportTrigger_Name2Type[par['ROReportTrigger']]

    msg_header = '!HHBH'
    msg_header_len = struct.calcsize(msg_header)

    data = encode('TagReportContentSelector')(par['TagReportContentSelector'])

    custom = encode('CustomParameter')(par['CustomParameter'])


    data = struct.pack(msg_header, msgtype,
                       len(data) + len(custom) + msg_header_len,
                       roReportTrigger, n) + data + custom

    return data

Message_struct['ROReportSpec'] = {
    'type': 237,
    'fields': [
        'N',
        'ROReportTrigger',
        'TagReportContentSelector',
        'CustomParameter'
    ],
    'encode': encode_ROReportSpec
}
[...]

'ROReportSpec': {
                # XXX this does *not* cause the reader to produce
                # RO_ACCESS_REPORT messages every 1s, as it looks like it
                # should; instead they appear much more frequently.
                'ROReportTrigger': 'Upon_N_Seconds',
                'N': 1,
                'TagReportContentSelector': tagReportContentSelector,
                'CustomParameter': {
                     'VendorID': 25882,
                    # 'Subtype': 50,
                    # 'CustomParameter': {
                    #     'VendorID': 'Impinj',
                    #     'Subtype': 51,
                    #     'SerializedTIDMode': 1
                    # }
                },
            },

Finally, the reader replies that there is an error with any of the fields:

image

Could you help me a little bit? :)
Thank you!

NoneType object is not iterable when decoding tve params

I began seeing this today. I'm not familiar with this library, is there anything I can do to help troubleshoot?

Unhandled Error
Traceback (most recent call last):
  File "/Users/jsheeley/.virtualenvs/InStore/lib/python2.7/site-packages/twisted/python/log.py", line 88, in callWithLogger
    return callWithContext({"system": lp}, func, *args, **kw)
  File "/Users/jsheeley/.virtualenvs/InStore/lib/python2.7/site-packages/twisted/python/log.py", line 73, in callWithContext
    return context.call({ILogContext: newCtx}, func, *args, **kw)
  File "/Users/jsheeley/.virtualenvs/InStore/lib/python2.7/site-packages/twisted/python/context.py", line 118, in callWithContext
    return self.currentContext().callWithContext(ctx, func, *args, **kw)
  File "/Users/jsheeley/.virtualenvs/InStore/lib/python2.7/site-packages/twisted/python/context.py", line 81, in callWithContext
    return func(*args,**kw)
--- <exception caught here> ---
  File "/Users/jsheeley/.virtualenvs/InStore/lib/python2.7/site-packages/twisted/internet/selectreactor.py", line 151, in _doReadOrWrite
    why = getattr(selectable, method)()
  File "/Users/jsheeley/.virtualenvs/InStore/lib/python2.7/site-packages/twisted/internet/tcp.py", line 215, in doRead
    return self._dataReceived(data)
  File "/Users/jsheeley/.virtualenvs/InStore/lib/python2.7/site-packages/twisted/internet/tcp.py", line 221, in _dataReceived
    rval = self.protocol.dataReceived(data)
  File "/Users/jsheeley/git/InStore/lib/sllurp/sllurp/llrp.py", line 317, in dataReceived
    lmsg = LLRPMessage(msgbytes=data)
  File "/Users/jsheeley/git/InStore/lib/sllurp/sllurp/llrp.py", line 41, in __init__
    self.remainder = self.deserialize()
  File "/Users/jsheeley/git/InStore/lib/sllurp/sllurp/llrp.py", line 86, in deserialize
    name: dict(decoder(body))
  File "/Users/jsheeley/git/InStore/lib/sllurp/sllurp/llrp_proto.py", line 617, in decode_ROAccessReport
    ret, data = decode('TagReportData')(data)
  File "/Users/jsheeley/git/InStore/lib/sllurp/sllurp/llrp_proto.py", line 1276, in decode_TagReportData
    par.update(llrp_decoder.decode_tve_parameters(body))
  File "/Users/jsheeley/git/InStore/lib/sllurp/sllurp/llrp_decoder.py", line 60, in decode_tve_parameters
    params.update(par)
exceptions.TypeError: 'NoneType' object is not iterable

Continuously reading TID from RFID tags

Hi Ben,
I am using Impinj Speedway Revolution R220, when reading TID instead of EPC from RFID tags, it only reads 5 times and then start reading EPC instead of TID, how to continuously reading TID from RFID tags, Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.