-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Workspace issue to improve Zebra support #9
Comments
A few tips for you:
There is 2 versions of the spec and of the api: v1 (1.0.1) and v2 (1.1). From one of your comments, I think that the Zebra reader supports v2, but Impinj ones just v1. A little bit like for the v2, each vendor can have it's own custom "messages" et "parameters" that are available and usable you ask the reader to enable its "custom" extensions. For the Zebra, you can find the details of their custom parameters inside the following document: |
@pBogey : |
I'm not so sure about Zebra. I tried to implement a
Don't really remember what the code was and if it was correctly implemented, but the v1.1 Standard mentions:
So I assumed that FX9500 only supports v 1.0.1.
I ran
There are some From what I understood from the LLRP standard, these are custom parameters (type 1023). The RFID Reader Software Interface Control Guide has details about these parameters.
MotoGeneralCapabilities
This parameter extends reader capabilities to report custom capabilities supported by Zebra readers. The reader sends this to the client as a custom parameter to the GET_READER_CAPABILITIES_RESPONSE message when the client issues a GET_READER_CAPABILITIES_REQUEST with custom reporting of general capabilities enabled. See MotoGeneralRequestCapabilities. The general capabilities indicate if the reader can report the radio version, part number, and whether the reader supports MotoGeneralGetParams on page 133.
MotoAutonomousCapabilities
This parameter reports the reader’s ability to operate in autonomous mode. The reader sends this to the client as a custom parameter to the GET_READER_CAPABILITIES_RESPONSE message when the client issues a
GET_READER_CAPABILITIES_REQUEST with custom reporting of autonomous mode capabilities enabled.
In autonomous mode, the reader continuously operates without requiring intervention from the client to re-initiate an operation. Autonomous mode and associated tag reporting is useful for continuous inventory, but can also be used for access operations. For efficiency, configure this mode for tag reporting when tag visibility changes during repeated inventory, rather than reporting the same tag data continuously. See MotoTagEventsGenerationCapabilities on page 129 for the reader's support of event reporting, MotoTagEventSelector on page 139 and MotoTagReportMode on page 140 for configuring reporting criteria, and MotoDefaultSpec on page 142 and MotoAutonomousState on page 138 for configuring and controlling autonomous mode.
MotoTagEventsGenerationCapabilities
This parameter reports the reader’s ability to report tag visibility state changes. The reader sends this to the client as a custom parameter to the GET_READER_CAPABILITIES_RESPONSE message when the client issues a
GET_READER_CAPABILITIES_REQUEST with custom reporting of tag events generation capabilities enabled.
This capability makes the autonomous mode of operation more efficient by reporting only event state changes rather than reporting tags continuously.
MotoFilterCapabilities
This parameter reports the reader’s ability to filter tags based on the tags’ RSSI, the time of day the tags were read, or the UTC Timestamp when the tags were read. The reader sends this to the client as a custom parameter to the
GET_READER_CAPABILITIES_RESPONSE message when the client issues a
GET_READER_CAPABILITIES_REQUEST with custom reporting of filtering capabilities enabled.
MotoPersistenceCapabilities
This parameter reports the reader’s ability to save the configuration, save the tag, and save the associated event information. Saved information is retained across reader reboots. The reader sends this to the client as a custom parameter to the GET_READER_CAPABILITIES_RESPONSE message when the client issues a GET_READER_CAPABILITIES_REQUEST with custom reporting of persistence capabilities enabled.
MotoC1G2LLRPCapabilities
MotoAutonomousState
This parameter enables or disables autonomous mode of operation and is sent as a custom parameter to the SET_READER_CONFIG message. The client can retrieve the current autonomous mode state from GET_READER_CONFIG_RESPONSE by requesting reporting of the corresponding custom parameter in the GET_READER_CONFIG message.
MotoFilterList
Use this parameter to configure filter settings on the reader to filter tags based on the received signal strength of the tag, the time the tag was read, or both. The filter list is composed of one or more filter rules. Configure multiple filter rules as a chain of rules using the Continue flag for RuleType. See MotoFilterRule on page 135. This allows continuing rule matching for subsequent rules if the current rule passes.
MotoPersistenceSaveParams
This parameter configures the reader to save and restore reader configurations performed over LLRP, save tag data and non-reported events in internal flash, and restore these if the reader power cycles. SaveTagData and SaveTagEventData enable saving tag and event data persistently on the reader across graceful reader shutdowns and reboots. Saving tag events also saves tag data and events associated with it. This saves only tags stored in the reader’s internal tag database generated by ROSpec (either autonomous mode or regular
ROSpecs) that are set to use custom reporting preference. The following conditions must be met to save a tag data report:
MotoDefaultSpec
This parameter defines a pre-configured ROSpec that the reader uses
MotoCustomCommandOptions
This parameter enables or disables specific custom command options. It is sent as a custom parameter to the SET_READER_CONFIG message. The client can retrieve the current custom options state from GET_READER_CONFIG_RESPONSE by requesting the reporting of the corresponding custom parameter in GET_READER_CONFIG message.
|
Yes, you got it right. In the config and capabilities list response by the reader that was expected. Good thing also, it looks like that just "vendor" parameters are unknown, but no standard field. That being said, it looks like that the reader is not really respecting the specification, because normally we should have sent an 2 notes:
So, that is a very good and easy starting point for you. Yes, 1023 is the type for custom parameter or message, 161 is the vendor code, and then the subtype that you see. So, what I suggest you to begin with:
|
Yeah, I think so. They are like the headers in the TCP/IP standard, but I don't know how to extract information from them. I have made the following modifications in llrp_proto.py:
I don't fully understand the struct package and the formats, but I think I got it right. For example, the table below represents the `MotoAutonomousCapabilities` message header.
The data send by the reader is: XML message now contains:
The log output now prints
Do you think this redundancy is useful? |
Yes, you got it right!
It is a little bit nicer to extract the tuple directly here instead of getting the fields tuple and then using it with fields[0], fields[1].
If you have 2 lines, that means that the reader has sent this argument 2 times.
The only originality in sllurp, is that if you look at the top of llrp_proto, the struct instances are "precreated"/"precompiled" once, and in a variable like
One line is The two first line, are just a reminder of the bit index per column. From 0 to 31. What you see is the complete parameter. A message contains X parameters, and each parameter can contain more parameters or fields. That is how we can decode dynamically, by starting the read the header of a parameter, determine it's type, and then send the remaining data to the appropriate decoder. One last important information, everything is rounded to "bytes", as with binary and network protocols it is not really possible to read less than that or that is not a multiple of bytes. So, in the table that you give as example, the bit stream is like this:
As it is a custom type field, it continues:
All of that, previously, was the parameter header. So, the automatic code figures out what kind of parameter it is, and then it calls your decoder with the data, starting next, just before version:
And in flags, the first bit is a boolean named "A" with the meaning that you know. |
You're right, will do like in your example.
I see that the majority of the parameters have the Moto prefix (legacy from the Motorola days), while the new parameters started to use the Zebra prefix. Do you think it would be a good idea to separate everything specific to a certain vendor into it's own module? This way, it will have their own namespace, like
The second debug message comes from
It's funny, because I started the comment having a lot of trouble getting the decode function to work, but as I was writing, asking for info, comparing the Impinj specifications with Zebra's and the decode for Impinj with my version, I began to understand. |
For the namespace using a separate module, you are right, that is the correct solution, but this will probably done later, as it is a little bit trickier in this context to do it nicely at the same time of keeping the micro optimizations. So for the moment, I think that you can continue to add other parameters with their official name. For the "double" debug message, you are right. So, don't hesitate to continue with other functions. |
hey, Florent, I have a little issue: I don't know how to contribute :) I've searched the net and found out that I need to fork your project, clone it to my pc, work on it and do a pull request. That's great, sounds simple, but I don't know how to make sllurp work, after I clone it. What I mean is, I will create a PyCharm project, for example, with a Python virtualenvironment and clone sllurp into that project. But sllurp is not installed, neither are it's dependencies. How can I make it work, then, so I can test my modifications? |
If you are already inside a virtualenv, you just have to do: That is the simplest. That being said, there is also an alternative, when you are inside the main sllurp top folder (not the "sllurp" sub-folder), you can also call the following without install: Please use one method or the other, but don't mix or you have the risk to have some file confusion at execution that could lead to strange non-explainable errors. |
I am having a little trouble understanding how to decode MotoDefaultSpec (102), MotoFilterList (255). For example, let's take MotoDefaultSpect:
This code will obviously fail. I need some tips/guidance on how to handle ROSpec and subsequent AccessSpec fields. I have tried using the generic decoder functions, but had no success. I suppose the first thing to do is to implement an ROSpec decoder, but encountered the same issue: nested messages that I don't know how to handle. EDIT: created a pull request with current progress. |
You were almost good.
Fields are for real fields. Then, decode_all_parameters will automatically read the headers that are in the remaining of the data to find the right parameter (here "ROSpec" or "AccessSpec") and to find the the right decoder for this block and use it on the relevant part of data. |
For |
Btw, the PR you created looks good for all the rest. |
I have made progress ragarding MotoDefaultSpec parameter:
Now ROSpec is being decoded. Continued to add decode functions for all fields and parameters within ROSpec and everyhting seems good, so far. I have another issue, though, with AISpec:
This will generate an error in
The data input for decode_AISpec is:
while the input for decode_all_parameters is:
which is the first sequence without the first 4 bytes (one AntennaCount field and one AntennaID field). Note: In the log file, I will find this output:
Shouldn't MotoDefaultSpec also show the ROSpec in the xml output? Or it will after AISpec will be decode? |
I just understand your issue. |
Nevermind, I chose a wrong format for "AISpecStopTrigger" and this was generating the error. I will continue with the decoding. WIll push as I make progress. EDIT: I have something that's kind of working, but I encounter some wierd stuff.
ID 24831 (which is the same as the DeviceManufacturerName) belongs to Sirit Technologies Inc.. Later Edit: I tried to log the output of llrp_data2xml for MotoDefaultSpec and this is what I got:
Don't know why it's not printed in the log file, though. |
Had typo in the code, I have managed to decode most parameters (all, except the unusual ones with vendor id = 24831):
You were right, I think I understand how to decode most of the messages now. Should probably learn how to implement tests for all this stuff. |
You have completed all that you wanted with your PR? |
Also, I looked everywhere on internet, but it looks like that Sirit disappeared a long time ago merged in other companies. So no spec, nowhere, but it probably means that these fields are insignificant, even if it is frustrating to have fields remaining non-decoded. (I also noticed that in the GeneralDeviceCapabilities, the DeviceManufacturerName is 24831, so probably this device inherit from a Sirit ancestor) You can probably ask Zebra support about these fields, maybe they will share the documentation about them. |
@pBogey following the discussion in #8.
Here is the new issue/thread, to provide directions for more Zebra support improvements.
The text was updated successfully, but these errors were encountered: