Coder Social home page Coder Social logo

python-mercuryapi's Introduction

Python wrapper for the ThingMagic Mercury API

The ThingMagic Mercury API is used to discover, provision and control ThingMagic RFID readers.

Reading RFID tags is as simple as this:

import mercury
reader = mercury.Reader("tmr:///dev/ttyUSB0")

reader.set_region("EU3")
reader.set_read_plan([1], "GEN2")
print(reader.read())

Installation

On Windows, use the pre-compiled binary installer.

On Linux:

  • Check prerequisites using apt-get install unzip patch xsltproc gcc libreadline-dev,
  • Then build and install using pip install python-mercuryapi.

Note: The build process will (temporarily) require upto 500MB of free space in /tmp. If your /tmp is smaller, use e.g. pip install python-mercuryapi -b $HOME/tmp to redirect.

Alternatively, you can follow the Build Instructions below and install the software manually.

Usage

Import the module mercury and create an mercury.Reader object.

import mercury

Reader Object

Represents a connection to the reader.

mercury.Reader(uri, baudrate=115200, antenna, protocol)

Object constructor. Connects to the reader:

  • uri identifies the device communication channel:
    • "tmr:///com2" is a typical format to connect to a serial based module on Windows COM2
    • "tmr:///dev/ttyUSB0" is a typical format to connect to a USB device named ttyUSB0 on a Unix system
    • "llrp://192.198.1.100" is a typical format to connect to an Ethernet device (works on Linux only)
  • baudrate defines the desired communication speed of the serial port. Supported values include 110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600 and 115200 (default). This parameter is not allowed for network-connected readers.
  • antenna number and protocol for operations not using the read-plan (see bellow)

For example:

reader = mercury.Reader("tmr:///dev/ttyUSB0", baudrate=9600)

or

reader = mercury.Reader("tmr://192.168.1.101")

reader.set_read_plan(antennas, protocol, epc_target=None, bank=[], read_power=default)

Specifies the antennas and protocol to use for a search:

  • antennas list define which antennas (or virtual antenna numbers) to use in the search
  • protocol defines the protocol to search on. Supported values are:
    • "GEN2", UPC GEN2
    • "ISO180006B", ISO 180006B
    • "UCODE", ISO 180006B UCODE
    • "IPX64", IPX (64kbps link rate)
    • "IPX256", IPX (256kbps link rate)
    • "ATA"
  • epc_target defines tags to be addressed (see Filtering)
  • bank defines the memory banks to read. Supported values are:
    • "reserved"
    • "epc"
    • "tid"
    • "user"
  • read_power defines the transmit power, in centidBm, for read operations. If not given, a reader specific default value is used.

For example:

reader.set_read_plan([1], "GEN2")

or

reader.set_read_plan([1], "GEN2", bank=["user"], read_power=1900)

Target filtering

The epc_target may be:

  • None to address all tags
  • Single hexa-string, e.g. b'E2002047381502180820C296' to address a tag with specific data (non-protocol-specific)
  • List of hexa-strings to address multiple Gen2 tags with given EPC
  • List of Gen2 Select filters (or even a single Gen2 filter) to address a given tag population (see below).

The Gen2 Select filter is a Dict with arguments:

  • reserved, epc, tid, or user that defines the mask as a hexa-string. This also determines the memory bank in which to compare the mask.
  • invert flag to match tags not matching the mask (by default false)
  • bit indicating the location (in bits) at which to begin comparing the mask (by default 32 for the epc bank and 0 otherwise)
  • len indicating length (in bits) of the mask (by default, the entire hexa-string given will be matched)
  • action defines the filter action on the matching and not-matching tags (by default, on&off for the first filter in the list and on&nop otherwise)
Action Tag Matching Tag Not-Matching
on&off Assert SL Deassert SL
on&nop Assert SL Do nothing
nop&off Do nothing Deassert SL
neg&nop Negate SL Do nothing
off&on Deassert SL Assert SL
off&nop Deassert SL Do nothing
nop&on Do nothing Assert SL
nop&neg Do nothing Negate SL

The tuples are processed sequentially and depending on the action the selection (SL) of matching and not-matching tags is either asserted, deasserted or negated. The read/write operation is applied to the tags that remain asserted after processing the entire filter.

To select one tag or another, use on&off, followed by a sequence of on&nop. For example:

[b'E2002047381502180820C296', b'0000000000000000C0002403']

is equivalent to

[{'epc':b'E2002047381502180820C296', 'action':'on&off'}, {'epc':b'0000000000000000C0002403', 'action':'on&nop'}]

Please note that the assertion is a state of the (physical) tag that disappears after some time. Therefore, the result of one operation may affect another!

reader.read(timeout=500)

Performs a synchronous read, and then returns a list of TagReadData objects resulting from the search. If no tags were found then the list will be empty.

  • timeout sets the reading time

For example:

print(reader.read())
[EPC(b'E2002047381502180820C296'), EPC(b'0000000000000000C0002403')]

To get a list (or a set) of EPC codes you can use the map function:

epcs = map(lambda t: t.epc, reader.read())
print(list(epcs))
[b'E2002047381502180820C296', b'0000000000000000C0002403']
print(set(epcs))
{b'E2002047381502180820C296', b'0000000000000000C0002403'}

reader.write(epc_code, epc_target=None)

Performs a synchronous write. Returns True upon success, or False if no tag was found. Upon failure an exception is raised.

For example:

old_epc = b'E2002047381502180820C296'
new_epc = b'E20020470000000000000012'

reader = Reader('llrp://192.168.0.2')
reader.set_read_plan([1], "GEN2")

if reader.write(epc_code=new_epc, epc_target=old_epc):
    print('Rewrited "{}" with "{}"'.format(old_epc, new_epc))
else:
    print('No tag found')

reader.enable_stats(callback)

Provide reader stats during asynchronous tag reads.

The function must be called before reader.start_reading().

For example:

def stats_received(stats):
    print({"temp" : stats.temperature})
    print({"antenna" : stats.antenna})
    print({"protocol" : stats.protocol})
    print({"frequency" : stats.frequency})

reader.enable_stats(stats_received)

reader.enable_exception_handler(callback)

Provide reader exception handling The function must be called before reader.start_reading().

For example:

def exeception_handle(e):
    print(e)

reader.enable_exception_handler(exeception_handle)

reader.start_reading(callback, on_time=250, off_time=0)

Starts asynchronous reading. It returns immediately and begins a sequence of reads or a continuous read. The results are passed to the callback. The reads are repeated until the reader.stop_reading() method is called

  • callback(TagReadData) will be invoked for every tag detected
  • on_time sets the duration, in milliseconds, for the reader to be actively querying
  • off_time duration, in milliseconds, for the reader to be quiet while querying

For example:

reader.start_reading(lambda tag: print(tag.epc))
b'E2002047381502180820C296'
b'0000000000000000C0002403'

reader.stop_reading()

Stops the asynchronous reading started by reader.start_reading().

For example:

reader.stop_reading()

reader.read_tag_mem(bank, address, count, epc_target=None)

Reads bytes from the memory bank of a tag. Returns a bytearray or None if no tag was found. Upon failure an exception is raised.

The read-plan is not used. Use the antenna and protocol parameters in the Reader constuctor.

For example:

reader = mercury.Reader("tmr:///dev/ttyUSB0", baudrate=9600, protocol="GEN2")
print(reader.read_tag_mem(1, 0x08, 8))
bytearray(b'\x00\x00\x00\x16\x12\x00\x00\x61')

reader.write_tag_mem(bank, address, data, epc_target=None)

Writes bytes to the memory bank of a tag. Returns True upon success, or False if no tag was found. Upon failure an exception is raised.

The read-plan is not used. Use the antenna and protocol parameters in the Reader constuctor.

For example:

reader.write_tag_mem(1, 0x08, bytearray(b'\x00\x00\x00\x16\x12\x00\x00\x61'))

reader.gpi_get(pin)

Returns value of a GPIO pin, or None is the pin is not configured as input (see get_gpio_inputs).

For example:

print(reader.get_gpio_inputs())
[1]
print(reader.gpi_get(1))
True

reader.gpo_set(pin, value)

Sets value of a GPIO pin configured as output (see get_gpio_outputs).

For example:

print(reader.get_gpio_outputs())
[1]
reader.gpo_set(1, False)

reader.get_model()

Returns a model identifier for the connected reader hardware.

For example:

print(reader.get_model())
M6e Nano

reader.get_software_version()

Returns the software version of the reader hardware For example:

print(reader.get_sofware_version())
01.0B.03.11-20.19.07.12-BL12.12.13.00

01.0B.03 is the current firmware version

reader.get_serial()

Returns a serial number of the reader, the same number printed on the barcode label.

reader.set_region(region)

Controls the Region of Operation for the connected device:

  • region represents the regulatory region that the device will operate in. Supported values are:
    • "NA", North America/FCC
    • "NA2", Reduced FCC region
    • "NA3", 5MHZ FCC band
    • "EU", European Union/ETSI EN 302 208
    • "EU2", European Union/ETSI EN 300 220
    • "EU3", European Union/ETSI Revised EN 302 208
    • "EU4", 4 channels (916.3MHz, 917.5MHz, 918.7MHz)
    • "IS", Israel
    • "IN", India
    • "JP", Japan
    • "JP2", Japan 24dBm with 13 channels
    • "JP3", Japan 24dBm with 6 channels
    • "KR", Korea MIC
    • "KR2", Korea KCC
    • "PRC", China
    • `"PRC2", China 840MHZ
    • "AU", Australia/AIDA LIPD Variation 2011
    • "NZ", New Zealand

For example:

reader.set_region("EU3")

reader.get_supported_regions()

Lists supported regions for the connected device.

For example:

print(reader.get_supported_regions())
['NA2', 'IN', 'JP', 'PRC', 'EU3', 'KR2', 'AU', 'NZ']

reader.get_hop_table()

Gets the frequencies for the reader to use, in kHz.

reader.set_hop_table(list)

Sets the frequencies for the reader to use, in kHz.

reader.get_hop_time()

Gets the frequency hop time, in milliseconds.

reader.set_hop_time(num)

Sets the frequency hop time, in milliseconds.

reader.get_antennas()

Lists available antennas.

For example:

print(reader.get_antennas())
[1, 2]

reader.get_connected_ports()

Returns numbers of the antenna ports where the reader has detected antennas.

For example:

print(reader.get_connected_ports())
[1]

reader.get_power_range()

Lists supported radio power range, in centidBm.

For example:

print(reader.get_power_range())
(0, 3000)

reader.get_read_powers()

Lists configured read powers for each antenna. [(antenna, power)]. The list does not include antennas with default power setting, so the list may be empty.

For example:

print(reader.get_read_powers())
[(1, 1800), (2, 3000)]

reader.get_write_powers()

Lists configured write powers for each antenna. [(antenna, power)].

reader.set_read_powers(powers)

Set the read power for each listed antenna and return the real setted values. Setted values may differ from those passed due to reader rounding.

  • powers list of 2-tuples that include:
    • which antenna (or virtual antenna numbers) is going to be setted
    • required power, in centidBm, for the antenna, overriding the value from set_read_plan or reader specific default. The value must be within the allowed power range.

For example:

setted_powers = reader.set_read_powers([(1, 1533), (2, 1912)])
print(setted_powers)
[(1, 1525), (2, 1900)]

reader.set_write_powers(powers)

Set the write power for each listed antenna and return the real setted values.

reader.get_gpio_inputs()

Get numbers of the GPIO pins available as input pins on the device.

For example:

print(reader.get_gpio_inputs())
[1, 2]

reader.set_gpio_inputs(list)

Set numbers of the GPIO pins available as input pins on the device.

For example:

reader.set_gpio_inputs([1, 2])

reader.get_gpio_outputs()

Get numbers of the GPIO pins available as output pins on the device.

reader.set_gpio_outputs(list)

Set numbers of the GPIO pins available as output pins on the device.

On some devices this parameter is not writeable. Thus, instead of calling set_gpio_outputs with the a set you may need to call set_gpio_inputs with the pin omitted.

reader.get_gen2_blf()

Returns the current Gen2 BLF setting.

For example:

print(reader.get_gen2_blf())
250

reader.set_gen2_blf(blf)

Sets the Gen2 BLF. Supported values include:

  • 250 (250KHz)
  • 320 (320KHz)
  • 640 (640KHz)

Not all values may be supported by a particular reader. If successful the input value will be returned. For example:

print(reader.set_gen2_blf(640))
640

reader.get_gen2_tari()

Returns the current Gen2 Tari setting.

For example:

print(reader.get_gen2_tari())
0

reader.set_gen2_tari(tari)

Sets the Gen2 Tari. Supported values include:

  • 0 (25 us)
  • 1 (12.5 us)
  • 2 (6.25 us)

If successful the input value will be returned. For example:

print(reader.set_gen2_tari(1))
1

reader.get_gen2_tagencoding()

Returns the current Gen2 TagEncoding setting.

For example:

print(reader.get_gen2_tagencoding())
0

reader.set_gen2_tagencoding(tagencoding)

Sets the Gen2 TagEncoding. Supported values include:

  • 0 (FM0)
  • 1 (M = 2)
  • 2 (M = 4)
  • 3 (M = 8)

If successful the input value will be returned. For example:

print(reader.set_gen2_tagencoding(2))
2

reader.get_gen2_session()

Returns the current Gen2 Session setting.

For example:

print(reader.get_gen2_session())
0

reader.set_gen2_session(session)

Sets the Gen2 Session. Supported values include:

  • 0 (S0)
  • 1 (S1)
  • 2 (S2)
  • 3 (S3)

If successful the input value will be returned. For example:

print(reader.set_gen2_session(2))
2

reader.get_gen2_target()

Returns the current Gen2 Target setting.

For example:

print(reader.get_gen2_target())
0

reader.set_gen2_target(target)

Sets the Gen2 Target. Supported values include:

  • 0 (A)
  • 1 (B)
  • 2 (AB)
  • 3 (BA)

If successful the input value will be returned. For example:

print(reader.set_gen2_target(2))
2

reader.get_gen2_q()

Returns the current Gen2 Q setting as a tuple containing the current Q type, and initial Q value.

For example:

print(reader.get_gen2_q())
(0, 16)

reader.set_gen2_q(qtype, initialq)

Sets the Gen2 Q.

  • qtype defines Dynamic vs Static Q value where:
    • 0 (Dynamic)
    • 1 (Static)
  • initialq defines 2^initialq time slots to be used initially for tag communication.

If Dynamic Q is used then the input initialq value is ignored as the reader will choose this on its own. It is then likely for initialq on a get to be different than the value used on a set.

If successful the input value will be returned. For example:

print(reader.set_gen2_q(0, 4))
(0, 4)
print(reader.get_gen2_q())
(0, 64)

or

print(reader.set_gen2_q(1, 4))
(1, 4)
print(reader.get_gen2_q())
(1, 4)

reader.get_temperature()

Returns the chip temperature in degrees of Celsius.

TagReadData Object

Represents a read of an RFID tag:

  • epc corresponds to the Electronic Product Code
  • phase of the tag response
  • antenna indicates where the tag was read
  • read_count indicates how many times was the tag read during interrogation
  • rssi is the strength of the signal recieved from the tag
  • frequency the tag was read with
  • timestamp of the read, in floating-point seconds for datetime.fromtimestamp
  • epc_mem_data contains the EPC bank data bytes
  • tid_mem_data contains the TID bank data bytes
  • user_mem_data contains the User bank data bytes
  • reserved_mem_data contains the Reserved bank data bytes
print(tag.epc)
b'E2000087071401930700D206'
print(tag.antenna)
2
print(tag.read_count)
2
print(tag.rssi)
-65
print(datetime.fromtimestamp(tag.timestamp))
2018-07-29 09:17:13.812189
print(tag.user_mem_data)
bytearray(b'\x00\x00\x00...')

Please note that the bank data bytes need to be requested via the bank parameter of the reader.set_read_plan function. Data not requested will not be read.

The friendly string representation (str) of the tag data is its EPC.

print(tag)
b'E2000087071401930700D206'

However, to avoid ambiguity, the string representation (repr) includes a prefix.

print(repr(tag))
EPC(b'E2000087071401930700D206')

Build Instructions

Windows

Use the Windows installer for the latest release and Python 3.6.

If you get the "ImportError: DLL load failed", make sure you have the Microsoft Visual C++ 2010 Redistributable Package installed.

To build an installer for other Python releases you need to:

  • Download the latest Mercury API, e.g. mercuryapi-YEATS-1.31.4.35-1.zip.
  • Go to mercuryapi-1.31.4.35\c\src\api\ltkc_win32 and run gencode.bat
  • Open mercuryapi-1.31.4.35\c\src\api\ltkc_win32\inc\stdint_win32.h and comment (or delete) the block of typedef for int_fast8_t through uint_fast64_t (8 lines)
  • Download the latest pthreads-win32 binaries (both .dll and .lib) for your architecture and put them into mercuryapi-1.31.4.35\c\src\pthreads-win32\x86 or \x64
  • Obtain Microsoft Visual Studio 2017, including the Python extensions
  • Open the Solution and review the setup-win.py
    • Verify the mercuryapi directory
    • Set library_dirs and data_files to the pthreads-win32 you downloaded
    • Set Script Arguments to bdist_wininst -p win32 (default) or bdist_wininst -p amd64
  • Start setup-win.py (without debugging)

Linux

First, make sure you have the required packages

yum install unzip patch libxslt gcc readline-devel python-devel python-setuptools

or

apt-get install unzip patch xsltproc gcc libreadline-dev python-dev python-setuptools

Both Python 2.x and Python 3.x are supported. To use the Python 3.x you may need to install the python3-dev[evel] instead of the python-dev[evel] packages.

Build the module simply by running

git clone https://github.com/gotthardp/python-mercuryapi.git
cd python-mercuryapi
make

This will download and build the Mercury API SDK and then it will build the Python module itself.

The make command will automatically determine which Python version is installed. If both 2.x and 3.x are installed, the 3.x takes precedence. To build and install 2.x you need to explicitly specify the Python interpreter to use:

sudo make PYTHON=python

Then, install the module by running

sudo make install

which is a shortcut to running

sudo python setup.py build install

If you are getting a "Module not found" error, please double check that you built and installed the module using the same Python version (2 or 3) you now use to run your script. (Or simply build and install it twice: once with python2 and once with python3.)

To access ports like /dev/ttyUSB0 as a non-root user you may need to add this user to the dialout group:

sudo usermod -a -G dialout $USER

MacOS X (Darwin)

To build on Mac

  • Copy mercuryapi_osx.patch to mercuryapi.patch (and overwrite the target)
  • Run make

Or simply do python setup.py build install

Copyright and Licensing

The python-mercuryapi is distributed under the terms of the MIT License. See the LICENSE.

Copyright (c) 2016-2020 Petr Gotthard

python-mercuryapi's People

Contributors

airlomba avatar bathroomepiphanies avatar carbaz avatar charlescochran avatar edgabaldi avatar gotthardp avatar hanyangzhao avatar josheb avatar mmigliavacca 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  avatar  avatar  avatar

python-mercuryapi's Issues

Read data banks fails on networked reader

I'm currently attempting to read tag data banks with a networked Sargas reader, and the current implementation is failing to read the data banks. For example simply running:

reader = mercury.Reader("tmr://192.168.1.101")
reader.set_read_plan([1], "GEN2", bank=["epc"], read_power=3000)
tags = reader.read(timeout=1000)
for tag in tags:
    print(tag.epc, tag.antenna, tag.read_count, tag.rssi, tag.epc_mem_data)

All of the tag parameters are correct, except for epc_mem_data which is None for every tag returned. The same None result applies for any other data bank, or if I'm attempting to get multiple instead of one.

After a little digging the source of the problem may be because the current bank read is implemented using embedded tag ops set in the read plan, combined with me using a networked reader accessed through an IP, not a serial connected reader. This is touched on in the MercuryAPI ProgrammerGuide:

Embedded TagOps are only supported with Gen2 (ISO18000-6C) protocol tags and when connected to readers of type SerialReader and RQLReader type M6.

This makes me think that for a networked reader I need to use direct invocation through Reader.ExecuteTagOp() that is mentioned in the programmer guide. I may take a stab at adding a method for this myself if I'm correct here.

To add an additional layer of confusion, the official Universal Reader Assistant program (which I presume still uses the Mercury API in the background) has an "Embedded ReadData" option that does work with my networked reader and the tags I'm testing with, which is in conflict with the above quote and leaves me wondering if I'm missing something else.

Has anyone else run into this kind of issue with the Mercury API before?

Key not found trying to connect a reader thought network

Hello Gotthardp,
thank for this project!

I've tried to use this project on a BeagleBone (ARM) with Debian.
I'm working with Sargas hardware, with 2 antennas.

Despite I had not some packets , I could making well the project and install.

Right now, I'm trying to connect the reader thought the network, so the uri is:

tmr://localhost
baudrate = 115200.

But, this instruction return me the message: "Key not found".

Have you any idea to how to resolv this?

Thanks a lot

pip install fails on Raspberry Pi

I'm not sure how pip works in terms of installing dependencies before installing the target library, but some necessary dependencies are apparently not present in Raspbian. Simply running

pip2 install python-mercuryapi

will fail unless first running

sudo apt-get install patch xsltproc gcc libreadline-dev python-dev python-setuptools

Like I wrote, I don't know how pip works but I thought it was possible to build in the installation of dependencies first, so maybe that could be added in.

Key error when try to connect a reader throught network

Hi, when I try to connect the reader I get a message saying: "Key Error". In the previous version I could connect without problems. How do I connect a reader that is on a network, not connected to the computer? In the old version, i use the command: mercury.Reader("tmr://m6-2128e5"), but doesn't work anymore.

Referencing multiple USB readers

First, a big thank you for providing this library - it's really awesome! Unfortunately I've become stuck on a curious issue: I've got two Mercury M6e readers connected via USB, with a UDEV rule* assigning fixed references for each one - yet in a simple Python test the readers (or rather, their callback functions) keep swapping around, which makes it impossible to identify which antenna read which tag! This is my test program:

import mercury
from time import sleep

readerA = mercury.Reader("tmr:///dev/MercuryA", baudrate=9600)
readerB = mercury.Reader("tmr:///dev/MercuryB", baudrate=9600)

def detectA(tag):
  print tag.epc + " A" + str(tag.antenna)

def detectB(tag):
  print tag.epc + " B" + str(tag.antenna)

readerA.set_region("EU3")
readerA.set_read_plan([1,2,3,4], "GEN2", read_power=800)

readerB.set_region("EU3")
readerB.set_read_plan([1,2,3,4], "GEN2", read_power=800)

try:
  readerA.start_reading(detectA)
  readerB.start_reading(detectB)
  while True:
        sleep(0.1)

except(KeyboardInterrupt, SystemExit):
  readerA.stop_reading()
  readerB.stop_reading()

And here is some sample output, with a single tag resting directly on top of one of the antennas:

300ED89F335000400182120B A2
300ED89F335000400182120B A2
300ED89F335000400182120B B2
300ED89F335000400182120B A2
300ED89F335000400182120B A2
300ED89F335000400182120B B2
300ED89F335000400182120B A2
300ED89F335000400182120B B2
300ED89F335000400182120B A2
300ED89F335000400182120B A2
300ED89F335000400182120B A2
300ED89F335000400182120B A2
300ED89F335000400182120B A2
300ED89F335000400182120B B2
300ED89F335000400182120B B2
300ED89F335000400182120B A2
300ED89F335000400182120B A2
300ED89F335000400182120B A2
300ED89F335000400182120B B2

As you can see, readerA (or is it B!? how can I tell!?) randomly switches between calling the detectA() and detectB() callbacks! How can this be, when I've separately defined each reader, and its callback function!? I'm hoping this is just due to some silly mistake on my part :)

*) My UDEV rule (/etc/udev/rules.d/99-usb-serial.rules), for those playing along at home:

SUBSYSTEM=="tty", KERNELS=="1-1.1.2:1.0", SYMLINK+="MercuryA"
SUBSYSTEM=="tty", KERNELS=="1-1.1.3:1.0", SYMLINK+="MercuryB"

python2

Is that possible to use python2 for this python wrapper?
I am using this code in ROS Indigo, but rospy supports only python2.

Error importing mercury

I've ben using your code for a while, and always been able to make it work.
Today I went again to install the code in a new computer, and follow your instructions for linux.
However, when trying to import mercury from my python code i get this error:

>>> import mercury
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "build/bdist.linux-x86_64/egg/mercury.py", line 7, in <module>
  File "build/bdist.linux-x86_64/egg/mercury.py", line 6, in __bootstrap__
ImportError: /home/username/.python-eggs/mercuryapi-0.4-py2.7-linux-x86_64.egg-tmp/mercury.so: undefined symbol: PyUnicode_AsUTF8

Any idea what is happening?

'out_ltkc.h' is missing when compiling

Hi,

I used the mercuryapi-1.31.0.33 and visual studio 2017 to compile the code. It came with the error that out_ltkc.h is missing, may I ask how to solve this? thanks.

C:/Apps/mercuryapi-1.31.0.33/c/src/api/ltkc_win32/inc\ltkc.h(32): fatal error C1
083: Cannot open include file: 'out_ltkc.h': No such file or directory

Hardware Device ?

Hi,
What device did you use with your Raspberry Pi ?

  • ThingMagic USB Pro RFID Reader ?
  • SparkFun Simultaneous RFID Reader ?

Thanks !

Problem installing

When I run "sudo python3 setup.py install" I end up with the following error:

error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

How can I resolve the problem? (Tnx)

Error when using with USB

I tried a test using the ThingMagic astra through IP and it worked, switched to USB and I get this error when running.
Traceback (most recent call last):
File "test.py", line 5, in
reader = mercury.Reader("tmr:///dev/ttyUSB0", baudrate=115200)
TypeError: Timeout

User Bank

Hey Guys,

I have achieved in reading epc asynchrouns.
In the How To i read that with the bank="user" parameter, I can read userdata that I have written to the tags.
But the following code just does nothing:
`import mercury
reader = mercury.Reader("tmr:///dev/ttyUSB0")

reader.set_region("EU3")
reader.set_read_plan([1], "GEN2", bank=["user"],read_power=500)
reader.start_reading(lambda tag: print(tag.user_mem_data))
`

Any ideas?

Bug start_reading

Hello,

I encouter an issu with the function start_reading with the folling code:

import time as tm
import mercury
reader = mercury.Reader("tmr:///COM12")

    
''' paramètres'''
reader.set_read_powers([1, 2, 3, 4], [2100,2300,2200,2100])
reader.set_region("EU3")
reader.set_read_plan([1,2,3],"GEN2")
reader.set_gen2_session(0)
reader.set_gen2_q(0,2)


print("start")
reader.start_reading(lambda tag: print(tag.epc))
tm.sleep(2)
reader.stop_reading()
print("end")

I do not receive any error message however it forces us to restart the shell as shown in this image:
pb lecture asynchrone

Do you have any idea how to fix it?

thank's

Setup Problems

I downloaded the API from ThingMagic, and have it in the same folder as the github package you posted. I'm in Python 3.63 via Pycharm and when I try to run the setup folders: usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
or: setup.py --help [cmd1 cmd2 ...]
or: setup.py --help-commands
or: setup.py cmd --help

error: no commands supplied

then when I try to run the test.py: import mercury
ImportError: No module named 'mercury'

I'm on a 64 bit OS with Windows 10 and I'm new to coding..

Thanks for the help.

tm_reader.h not found

Hey! I'm using windows and i got that installer in the latest release link to install but i'm still getting the error when i try "setup.py install"

running build
running build_ext
building 'mercury' extension
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -Ibuild/mercuryapi/include -IC:\Users\HP\AppData\Local\Programs\Python\Python36\include -IC:\Users\HP\AppData\Local\Programs\Python\Python36\include "-IC:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\8.1\include\shared" "-IC:\Program Files (x86)\Windows Kits\8.1\include\um" "-IC:\Program Files (x86)\Windows Kits\8.1\include\winrt" /Tcmercury.c /Fobuild\temp.win-amd64-3.6\Release\mercury.obj
mercury.c
mercury.c(23): fatal error C1083: Cannot open include file: 'tm_reader.h': No such file or directory
error: command 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\cl.exe' failed with exit status 2"

could please help me with this?
Thanks.

Support for Gen2 Settings

Nice work on the code. I've been able to use it to get some initial reads with a ThingMagic Sargas UHF reader. I was wondering if you had any plans on adding support for gen2 settings (e.g. tari, BLF, session).

Thanks!

installation

for the installation instruction, i tried and it showed:


better to run:
```python3 setup.py install
as well

Configuring 6E Nano multiple antenna

Great work writing well documented python wrapper !
I was trying to configure to read tag from multiple antenna, steps i followed are as follows
1). Since sparkfun have given access to GPIO1 of thingmagic 6E nano RFID , i have set it high to enable logical antenna 1 and 3 via antenna multiplexer.

2)and also set read plan as follows, which is also mentioned in the readme.md of this repo
reader.set_read_plan(antennas=[1,3],protocol="GEN2")
But this throws following error
TypeError : Invalid antenna configuration

What is the problem with the above steps ?

Best Regards
mundkur

Getting data off RFID Tags

Hey! I got everything running, but I'm just not sure how to get the actual data off of the tags. How would you suggest about doing so?

Thanks!

Multiplexer GPIO setup

When a multiplexer is connected the reader.read command outputs no reads even though it would without the multiplexer. How do I set the GPIO pins high with the python wrapper? Is there anyway of this? If not, is there a way to change the built code?

support for phase measurement

It would be good to be able to get the phase measurement from tags also

Any chance that this is a minor implementation to the current code?

Cannot build on Mac OS

When running make from on Mac OS, I get a lot of the following errors:

./ltkc_base.h:142:5: error: unknown type name 'llrp_u16_t'; did you mean 'llrp_u16v_t'?

Is building/installing from MacOS supported? And if not, what is required to allow for this?

TagReadData Object RSSI average?

Hello,

Just wondering whether the rssi value returned in TagReadData objects from reader.read() when read_count > 1 is the average rssi value of all the readings or something else such as the last rssi value?

Run in Raspberry Pi 3 B running Windows 10 IoT

Hi!
I already have runing in a Python proyect in Windows 10 and it's works perfect!
But... i need to have the same running in a Windows 10 IOT, but when i deploy form Visual Studio 2015 (the same proyecto what it's ok over Windows 10) i have a Error "mercury module not found"... i guest what i need a Raspberry compiled version of the wrapper.... any help?

Regards!!
PD: Grate job done with the library...
PD2: Sorry my terrible english

reader.Read() invalid argument if bank is set

I've gotten to the point where I'm able to read the tags using the reader.Read method.

I create a reader using mercury.Reader("tmr:///COM6")
I set the region to "EU3"
I set the readplan:
rfid_reader.set_read_plan(rfid_reader.get_antennas(), "GEN2")
This works fine, I'm able to get some information from the API for example:

b'303A5E59000000000000DB96'

However, I'd like to get more of the information, so I tried adding the bank parameter to the set_read_plan function like so:
rfid_reader.set_read_plan(rfid_reader.get_antennas(), "GEN2", "tid")

I've also tried adding a list of 1 and a list of multiple bank parameters like so:
rfid_reader.set_read_plan(rfid_reader.get_antennas(), "GEN2", ["tid"])
and
rfid_reader.set_read_plan(rfid_reader.get_antennas(), "GEN2", ["tid", "reserved"])

However, as soon as I set a bank parameter, I get the following error:

Traceback (most recent call last):
  File "C:\ti-software\RFID\rfid\app.py", line 38, in start_action
    self.read_timer.timeout.connect(self.update_list())
  File "C:\ti-software\RFID\rfid\app.py", line 45, in update_list
    tags = utils.rfid_read(self)
  File "C:\ti-software\RFID\rfid\utils.py", line 42, in rfid_read
    temp = mainWindow.rfid_reader.read()
RuntimeError: Invalid argument

just in case it matters, the reader is kept as a property of mainWindow.

I'm using the latest 32 bit release for python 3.6.

Any idea what is going on? Or what I should change to get more data back ?

thanks!

Windows installer for Python 3.6

Hi, I tried the 3.5 installer and it works, but we need a 3.6 installer for our project.
Do you have this 3.6 installer or do you know how to make it works without create a parallel 3.5 service?

Thanks!

Build Process in Windows 10

Hi, I'm really interesting with how to build mercury api c library in windows. But the windows installer is not open source. I'm doing the research on how to write mercury api in C/C++. I'm not sure whether you can share the step how to build the library for windows? Thanks.

Installing in conda environment

Hey,

I am unfamiliar with wrapping C Librarys for python.
My plan was to use your wrap of the mercury api in a project.
So I would like to isolate all dependencies I will require.
I use a conda environment, python --version shows me that the correct python version is active. But if I follow your instructions on building the api wrapper for linux the api is installed on the python in the /usr/lib64/python2.7/ path instead of my home/anaconda3/.
Also I am unable to import mercury in my environment.
Is there any way to install your wrapper in a anaconda environment?

Hope you can help me and thanks in advance for your time!

ImportError: DLL load failed

I'm using Windows 10 and Python 3.6.6.

Installation from mercuryapi-0.3.win32-py3.6.exe completes with no errors, but when attempting to import the mercury package, I get the following error:

ImportError: DLL load failed: The specified module could not be found.

What (probably stupid) thing am I doing wrong here?

reader.stop() Timeout issue

Hey,

I am running a flask based web application. In this apllication when visiting a specific page, the readprocess starts as a background thread.
If the index page is visited, the read should be stopped.
If the reader is busy reading, I can't stop the reader with reader.stop(). I get the following error massage:
Traceback (most recent call last): File "manStop.py", line 7, in <module> reader = mercury.Reader("tmr:///dev/ttyUSB0", baudrate=115200) TypeError: Timeout
Any ideas?

ImportError : No module name "setuptools'

Hello, I'm getting an error when calling the make command. The make process ends up with the following error:

Traceback (most recent call last) :
File "setup.py", line 3, in
from setuptools import setup Extension
ImportError: No module named 'setuptools'
Makefile:7: recipe for target 'all' failed
make: *** [all] Error 1

Setting Device Power and Read Mode

Hi,

Thanks for making this library available. I'm trying to integrate it into a project I'm working on, and I was wondering if there was any way to set a device's power and read mode in Python.

Thanks again.

pip install fails on Ubuntu 16.04

Attempting to install with

pip install python-mercury api

From here:
https://pypi.org/project/python-mercuryapi/

This is the output

Collecting python-mercuryapi
Using cached https://files.pythonhosted.org/packages/5f/b3/0ed60331a77de7fcc5f8dc55bd48a901a327a93052e2756868cd9ead2ac2/python-mercuryapi-0.4.1.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "", line 1, in
File "/tmp/pip-build-s0UN60/python-mercuryapi/setup.py", line 8, in
long_description=open('README.md').read(),
IOError: [Errno 2] No such file or directory: 'README.md'

----------------------------------------

Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-s0UN60/python-mercuryapi/

When I build from source using python2, then try to import, it says it's already been imported and it just doesn't work at all.

BUG? Multiple Tags - User Data Read only on first Tag

Hey @gotthardp
I tried the following:

#!/usr/bin/env python3
from __future__ import print_function
import mercury
reader = mercury.Reader("tmr://dev/ttyUSB0", baudrate=115200)

reader.set_region("EU3")
reader.set_read_plan(reader.get_antennas(), "GEN2", "user")
for tag in reader.read(timeout=450):
    print("EPC", tag.epc)
    print("Antenna", tag.antenna)
    print("Count", tag.read_count)
    print("RSSI", tag.rssi)
    print("user", tag.user_mem_data)

Unfortunately I get the following results:

EPC b'E200001963020091231027DE'
Antenna 1
Count 7
RSSI -37
user bytearray(b'L18100117\r\n\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
EPC b'E2000017230C01961100AA8E'
Antenna 1
Count 7
RSSI -31
user None

As you can see, the second tag does not return user data. That is, if two tags are read at the same time. Both show the correct user data if read seperately.

Originally posted by @rasidmusic in #39 (comment)

Module not found error on a Raspberry Pi (This could be user error)

Hi,
I have followed the installation instructions on Linux and everything ran successfully without any errors. Here are list of instructions I executed.

  1. sudo apt-get install patch xsltproc gcc libreadline-dev python-dev python-setuptools
  2. git clone https://github.com/gotthardp/python-mercuryapi.git
  3. cd in to dir,
  4. make

pi@raspberrypi: make -C mercuryapi-1.31.0.33/c/src/api make[1]: Entering directory '/home/pi/TM/PY/python-mercuryapi/mercuryapi-1.31.0.33/c/src/api' SOURCE_DIR=lib PATCH_DIR=lib XML_DIR=lib sh lib/install_LTKC.sh NULL lib lib/LTK directory already exists cd lib/LTK/LTKC/Library; make CC="cc -Ilib/LTK/LTKC/Library -Ilib/LTK/LTKC/Library/LLRP.org -I. -g -Wall -fPIC" STRIP="strip" make[2]: Entering directory '/home/pi/TM/PY/python-mercuryapi/mercuryapi-1.31.0.33/c/src/api/lib/LTK/LTKC/Library' cd LLRP.org; make all make[3]: Entering directory '/home/pi/TM/PY/python-mercuryapi/mercuryapi-1.31.0.33/c/src/api/lib/LTK/LTKC/Library/LLRP.org' make[3]: Nothing to be done for 'all'. make[3]: Leaving directory '/home/pi/TM/PY/python-mercuryapi/mercuryapi-1.31.0.33/c/src/api/lib/LTK/LTKC/Library/LLRP.org' make[2]: Leaving directory '/home/pi/TM/PY/python-mercuryapi/mercuryapi-1.31.0.33/c/src/api/lib/LTK/LTKC/Library' make[1]: Leaving directory '/home/pi/TM/PY/python-mercuryapi/mercuryapi-1.31.0.33/c/src/api' mkdir -p build/mercuryapi/include find mercuryapi-*/c/src/api -type f -name '*.h' ! -name '*_imp.h' | grep -v 'ltkc_win32' | xargs cp -t build/mercuryapi/include mkdir -p build/mercuryapi/lib find mercuryapi-*/c/src/api -type f -name '*.a' -or -name '*.so.1' | xargs cp -t build/mercuryapi/lib /usr/bin/python3 setup.py build running build running build_ext

Once its done, When I run the /usr/bin/python3 test.py, I get the import error: No module named mercury error. I am trying to connect a ThingMagic rfid reader to a Raspberry Pi and read some tags.

Read chip temperature

Hi,
it would be useful if the python api has a feature to read the chip temperature.

I think the c++ library has this feature, so maybe it is possible to support this in python too.

Regards,
Jan

Read Timeout

I get this error when running my code. Things work fine until the call to read. I'm assuming this has to do with the Tag buffer filling up for some reason, but I don't know how to clear it properly. I've tried setting different baud rates but no luck.

M6e Nano
[u'NA2', u'NA3', u'IN', u'JP', u'PRC', u'EU3', u'KR2', u'AU', u'NZ', u'open']
Traceback (most recent call last):
  File "test.py", line 12, in <module>
    print(reader.read(timeout=1000))
RuntimeError: Timeout

here is the code that I am running

from __future__ import print_function
import time
import mercury
reader = mercury.Reader("tmr:///dev/ttyUSB0", baudrate=115200)

print(reader.get_model())
print(reader.get_supported_regions())

reader.set_region("EU3")
reader.set_read_plan([1], "GEN2", read_power=1900)
print(reader.read(timeout=1000))

reader.start_reading(lambda tag: print(tag.epc, tag.antenna, tag.read_count, tag.rssi))
time.sleep(1)
reader.stop_reading()

reader.start_reading

Im having issue running the reader.start_reading call function when setting the read plan to include for the bank arguments. For example when I set: reader.set_readplan([1], "GEN2", bank=["epc", "reserved"], read_power=1400), the reader.start_reading call returns nothing. When I get rid of the bank argument it starts to work however the bank arguments will print as "None" such as the reserved, tid etc.

Getting user memory data

Hey,
Is it possible to get the user memory data?
I tried to play with the code(of mercury.c) a little bit but with no luck.

Thank you.

How to convert the list with byte strings into something useable? What is the reader.read() output?

Hi, you're currently saving me a lot of work on my current project (thank you!), but I've got some issues with converting the list of byte strings.

I want to compare a list of known ID's with the tags that are being seen, and get the location of the seen tags in the known tags-list.

I keep running into the issue that the list with byte strings doesn't seem to be a real list, and it keeps referring to mercury.TagReadData (TypeError: 'mercury.TagReadData' object is not subscriptable). Also, doing it like this (below) also does not work, the output is always false. So I think the output from reader.read() might not be a normal list but something else?

# importing libraries
import threading
import time 
import mercury
import collections

# set-up for the connected reader
reader = mercury.Reader("tmr:///dev/ttyS0", baudrate=115200)
print(reader.get_model()) # print the model to see if it's working
reader.set_region("EU3") # set a region to work with
reader.set_read_plan([1], "GEN2", read_power=1900)

# Below should be the IDs of the RFID tags!
knownIDs = [b'E2000015860E01451120AB56',
        b'48656C6C6F2101591120AB75',
        b'E2000015860E01601120AB6E',
        b'E2000015860E01611120AB76']

def readTags():
	threading.Timer(0.15, readTags).start()
	# this reads all of them in one go within the given time limit, and puts them in the CurIDs list
	incomingIDs = reader.read(timeout=100)
	print (list(incomingIDs))
	print ("length of list is", len(incomingIDs))

	# comparing lists, output the location of the found IDs within knownIDs
	print (b'E2000015860E01451120AB56' in incomingIDs)


readTags()

Thanks in advance!

Read_count staying at 1

Hello, When I run continous read mode the read_count for the tag remains at one, any chance this can be fixed? I'm using the test.py code.

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.