ARTICLE AD BOX
I would like to access a Python package in Ruby using PyCall.
The non-blocking function in the Python code below activates a callback.
Could you help me implement the callback?
#!/usr/bin/env python # start_reading.py import time import mercury def found(tag): print(tag.epc.decode()) # Check check # print(tags[1].epc.decode()) reader = mercury.Reader("tmr:///dev/ttyUSB0") reader.start_reading(found, on_time=250, off_time=0) time.sleep(0.5) reader.stop_reading()Output start_reading.py:
b'001853000000000000000012' b'34155CACB400000000000125' b'34155CACB400000000000125' b'34155CACB400000000000125' b'001853000000000000000012' b'34155CACB400000000000125' b'001853000000000000000012' b'34155CACB400000000000125' b'34155CACB400000000000125'This pertains an api for ThingMagic RFID readers, which is a Python wrapper for the original api written in C.
From the docs:
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 queryingAs follows the parts I got working using a single read function. First the Python code, then Ruby.
#!/usr/bin/env python # read.py import mercury reader = mercury.Reader("tmr:///dev/ttyUSB0") data = reader.read() print(data) print(f"type: {type(data)}")Output read.py:
[EPC(b'34155CACB400000000000125'), EPC(b'001853000000000000000012')] type: <class 'list'> #!/usr/bin/env ruby # read.rb require 'pycall/import' include PyCall::Import pyimport :mercury reader = mercury.Reader.new("tmr:///dev/ttyUSB0") python_data = reader.read() puts "python_data: #{python_data}" puts "python class: #{python_data.class}" puts "" ruby_data = python_data.to_ary puts "ruby_data: #{ruby_data}" puts "ruby class: #{ruby_data.class}"Output read.rb:
python_data: [EPC(b'34155CACB400000000000125'), EPC(b'001853000000000000000012')] python class: <class 'list'> ruby_data: [EPC(b'34155CACB400000000000125'), EPC(b'001853000000000000000012')] ruby class: ArrayThe above works, as you can see.
The solution for the callback should be an improvement upon the following code.
#!/usr/bin/env ruby # start_reading.rb require 'pycall/import' include PyCall::Import pyimport :mercury def found(tag) puts tag.epc end reader = mercury.Reader.new("tmr:///dev/ttyUSB0") reader.start_reading(found, on_time=250, off_time=0) # What should I do here? sleep(0.5) reader.stop_reading()Current output start_reading.rb
start_reading.rb:7:in `found': wrong number of arguments (given 0, expected 1) (ArgumentError) from start_reading.rb:14:in `<main>'