======================================================================
sllurp is a pure-python client and library for LLRP-based RFID readers
======================================================================
.. image:: http://img.shields.io/pypi/v/sllurp.svg
:target: https://pypi.python.org/pypi/sllurp
.. image:: https://img.shields.io/pypi/pyversions/sllurp.svg
:target: https://pypi.python.org/pypi/sllurp
.. image:: https://github.com/sllurp/sllurp/actions/workflows/test.yml/badge.svg
:target: https://github.com/sllurp/sllurp/actions/workflows/test.yml
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.
.. _GitHub: https://github.com/ransford/sllurp/
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``.
.. _PyPI: https://pypi.python.org/pypi/sllurp
.. _GitHub: https://github.com/ransford/sllurp/
Reader API
----------
sllurp spawn his own "thread" to manage network interaction with the reader.
To make a connection, create a ``LLRPReaderClient`` and ``connect()`` it:
.. code:: python
# 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:
.. code:: python
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:
.. code:: python
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).
.. _Impinj: https://support.impinj.com/hc/en-us/articles/202756158-Understanding-EPC-Gen2-Search-Modes-and-Sessions
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:
.. code:: python
import logging
logging.getLogger('sllurp').setLevel(logging.DEBUG)
.. _GitHub: https://github.com/ransford/sllurp/
.. _guide: https://www.chiark.greenend.org.uk/~sgtatham/bugs.html
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.
.. _confusing: https://github.com/ransford/sllurp/issues/63#issuecomment-309233937
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.
.. _Ben Ransford: https://ben.ransford.org/
.. _LLRPyC: https://sourceforge.net/projects/llrpyc/
Raw data
{
"_id": null,
"home_page": "https://github.com/sllurp/sllurp",
"name": "sllurp",
"maintainer": "Florent Viard (github.com/fviard)",
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "llrp rfid reader",
"author": "Ben Ransford",
"author_email": "ben@ransford.org",
"download_url": "https://files.pythonhosted.org/packages/28/1e/4ff1dc6edde35703828a6442bd11a68009f6c310df22a9a02e8ee3264941/sllurp-2.0.1.tar.gz",
"platform": null,
"description": "======================================================================\nsllurp is a pure-python client and library for LLRP-based RFID readers\n======================================================================\n\n\n.. image:: http://img.shields.io/pypi/v/sllurp.svg\n :target: https://pypi.python.org/pypi/sllurp\n\n.. image:: https://img.shields.io/pypi/pyversions/sllurp.svg\n :target: https://pypi.python.org/pypi/sllurp\n\n.. image:: https://github.com/sllurp/sllurp/actions/workflows/test.yml/badge.svg\n :target: https://github.com/sllurp/sllurp/actions/workflows/test.yml\n\nsllurp is a Python library to interface with RFID readers. It is a pure-Python\nimplementation of the Low Level Reader Protocol (LLRP).\n\nThese readers are known to work well with sllurp, but it should be adaptable\nwith not much effort to other LLRP-compatible readers:\n\n- Impinj Speedway (R1000)\n- Impinj Speedway Revolution (R220, R420)\n- Impinj Speedway xPortal\n- Motorola MC9190-Z (handheld)\n\nFile an issue on GitHub_ if you would like help getting another kind of reader\nto work.\n\nsllurp is distributed under version 3 of the GNU General Public License. See\n``LICENSE.txt`` for details.\n\n.. _GitHub: https://github.com/ransford/sllurp/\n\nQuick Start\n-----------\n\nInstall from PyPI_::\n\n $ virtualenv .venv\n $ source .venv/bin/activate\n $ pip install sllurp\n $ sllurp inventory ip.add.re.ss\n\nRun ``sllurp --help`` and ``sllurp inventory --help`` to see options.\n\nOr install from GitHub_::\n\n $ git clone https://github.com/ransford/sllurp.git\n $ cd sllurp\n $ virtualenv .venv\n $ source .venv/bin/activate\n $ pip install .\n $ sllurp inventory ip.add.re.ss\n\nIf the reader gets into a funny state because you're debugging against it\n(e.g., if your program or sllurp has crashed), you can set it back to an idle\nstate by running ``sllurp reset ip.add.re.ss``.\n\n.. _PyPI: https://pypi.python.org/pypi/sllurp\n.. _GitHub: https://github.com/ransford/sllurp/\n\nReader API\n----------\n\nsllurp spawn his own \"thread\" to manage network interaction with the reader.\nTo make a connection, create a ``LLRPReaderClient`` and ``connect()`` it:\n\n.. code:: python\n\n # Minimal example; see sllurp/verb/inventory.py for more.\n from sllurp import llrp\n from sllurp.llrp import LLRPReaderConfig, LLRPReaderClient, LLRP_DEFAULT_PORT\n import logging\n logging.getLogger().setLevel(logging.INFO)\n\n def tag_report_cb (reader, tag_reports):\n for tag in tag_reports:\n print('tag: %r' % tag)\n\n config = LLRPReaderConfig()\n reader = LLRPReaderClient(host, LLRP_DEFAULT_PORT, config)\n reader.add_tag_report_callback(tag_report_cb)\n\n reader.connect()\n # We are now connected to the reader and inventory is running.\n\n try:\n # Block forever or until a disconnection of the reader\n reader.join(None)\n except (KeyboardInterrupt, SystemExit):\n # catch ctrl-C and stop inventory before disconnecting\n reader.disconnect()\n\n.. note::\n\n Sllurp used to depend on python twisted and was using its mainloop.\n This is not the case anymore.\n Once connected to a reader, Sllurp will spawn his own \"thread\" to process\n the received messages and to call user defined callbacks.\n ``is_alive()`` and ``join(timeout)`` thread api are exposed by the\n ``LLRPReaderClient`` instance.\n\n\nGetting More Information From Tag Reports\n-----------------------------------------\n\nWhen initializing ``LLRPReaderConfig``, set flags in the\n``tag_content_selector`` dictionary argument:\n\n.. code:: python\n\n llrp.LLRPReaderConfig({\n 'tag_content_selector': {\n 'EnableROSpecID': False,\n 'EnableSpecIndex': False,\n 'EnableInventoryParameterSpecID': False,\n 'EnableAntennaID': True,\n 'EnableChannelIndex': False,\n 'EnablePeakRSSI': True,\n 'EnableFirstSeenTimestamp': False,\n 'EnableLastSeenTimestamp': True,\n 'EnableTagSeenCount': True,\n 'EnableAccessSpecID': False,\n }\n })\n\n\nLogging\n-------\n\nsllurp logs under the name ``sllurp``, so if you wish to log its output, you\ncan do this the application that imports sllurp:\n\n.. code:: python\n\n sllurp_logger = logging.getLogger('sllurp')\n sllurp_logger.setLevel(logging.DEBUG)\n sllurp_logger.setHandler(logging.FileHandler('sllurp.log'))\n # or .setHandler(logging.StreamHandler()) to log to stderr...\n\n\nVendor Extensions\n-----------------\n\nsllurp has limited support for vendor extensions through LLRP's custom message\nfacilities. For example, `sllurp inventory --impinj-search-mode N` allows you\nto set the Impinj_ search mode to single target (1) or dual target (2).\n\n.. _Impinj: https://support.impinj.com/hc/en-us/articles/202756158-Understanding-EPC-Gen2-Search-Modes-and-Sessions\n\nHandy Reader Commands\n---------------------\n\nTo see what inventory settings an Impinj reader is currently using (i.e., to\nfetch the current ROSpec), ssh to the reader and\n\n::\n\n > show rfid llrp rospec 0\n\nThe \"nuclear option\" for resetting a reader is:\n\n::\n\n > reboot\n\nIf You Find a Bug\n-----------------\n\nStart an issue on GitHub_! Please follow Simon Tatham's guide_ on writing good\nbug reports.\n\nBug reports are most useful when they're accompanied by verbose error messages.\nTurn sllurp's log level up to DEBUG, which you can do by specifying the `-d`\ncommand-line option to ``sllurp``. You can log to a logfile with the ``-l\n[filename]`` option. Or simply put this at the beginning of your own code:\n\n.. code:: python\n\n import logging\n logging.getLogger('sllurp').setLevel(logging.DEBUG)\n\n.. _GitHub: https://github.com/ransford/sllurp/\n.. _guide: https://www.chiark.greenend.org.uk/~sgtatham/bugs.html\n\nKnown Issues\n------------\n\nReader mode selection is confusing_, not least because most readers seem to\nconflate ``ModeIndex`` and ``ModeIdentifier``. If you're using ``sllurp\ninventory``, use ``--mode-identifier N``. Check your reader's manual to see\nwhat mode identifiers it supports via the ``C1G2RFControl`` parameter, or run\n``sllurp --debug inventory`` against a reader to see a dump of the supported\nmodes in the capabilities description.\n\n.. _confusing: https://github.com/ransford/sllurp/issues/63#issuecomment-309233937\n\nContributing\n------------\n\nWant to contribute? Here are some areas that need improvement:\n\n- Encode more protocol messages in the ``construct`` branch.\n- Write tests for common encoding and decoding tasks.\n\nAuthors\n-------\n\nMuch of the code in sllurp is by `Ben Ransford`_, although it began its life in\nAugust 2013 as a fork of LLRPyC_. Many fine citizens of GitHub have\ncontributed code to sllurp since the fork.\n\n.. _Ben Ransford: https://ben.ransford.org/\n.. _LLRPyC: https://sourceforge.net/projects/llrpyc/\n\n\n",
"bugtrack_url": null,
"license": "GPLv3",
"summary": "RFID reader control library",
"version": "2.0.1",
"project_urls": {
"Homepage": "https://github.com/sllurp/sllurp"
},
"split_keywords": [
"llrp",
"rfid",
"reader"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "dd32597ff7341ce847bf2c91ff1cb038c274baa55f0aca593ba01e56d469d5d5",
"md5": "cfe31c0738e7ca1652c7ed7d56dd21be",
"sha256": "f493f1a4a21dd72419b50fdc027bd39261ae286de1edcc73e385833d566584ff"
},
"downloads": -1,
"filename": "sllurp-2.0.1-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "cfe31c0738e7ca1652c7ed7d56dd21be",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 75703,
"upload_time": "2024-09-09T13:04:34",
"upload_time_iso_8601": "2024-09-09T13:04:34.935766Z",
"url": "https://files.pythonhosted.org/packages/dd/32/597ff7341ce847bf2c91ff1cb038c274baa55f0aca593ba01e56d469d5d5/sllurp-2.0.1-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "281e4ff1dc6edde35703828a6442bd11a68009f6c310df22a9a02e8ee3264941",
"md5": "b2f81654be77491820db336b86ef287f",
"sha256": "e12ac7963914eccd5af16307b05ec3249a2f2c7adb1d0981d9f1271f64eb4bb4"
},
"downloads": -1,
"filename": "sllurp-2.0.1.tar.gz",
"has_sig": false,
"md5_digest": "b2f81654be77491820db336b86ef287f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 66506,
"upload_time": "2024-09-09T13:04:36",
"upload_time_iso_8601": "2024-09-09T13:04:36.549606Z",
"url": "https://files.pythonhosted.org/packages/28/1e/4ff1dc6edde35703828a6442bd11a68009f6c310df22a9a02e8ee3264941/sllurp-2.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-09 13:04:36",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "sllurp",
"github_project": "sllurp",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "sllurp"
}