-1

in example read from xbee devices is:

device = XBeeDevice(PORT, BAUD_RATE)

try:
    device.open()

    def data_receive_callback(xbee_message):
        print("From %s >> %s" % (xbee_message.remote_device.get_64bit_addr(),
                                 xbee_message.data.decode()))

    device.add_data_received_callback(data_receive_callback)

    print("Waiting for data...\n")
    input()

finally:
    if device is not None and device.is_open():
        device.close()

finally:

    if device is not None and device.is_open():

        device.close()

I need to run this in a separate thread, what to use instead of input ()?

prem111
  • 63
  • 1
  • 7
  • Why do you use ``input`` at all? You are not storing the result. – MisterMiyagi Jan 27 '20 at 16:31
  • 1
    The OP wants the thread to block until it receives some sort of signal from elsewhere to proceed. – chepner Jan 27 '20 at 16:32
  • I'm using input () to force data to wait ... What to use instead? I need to wait all the time for the arrival of new data ... – prem111 Jan 27 '20 at 16:34
  • 1
    The `XBeeDevice` class probably has a method that receives data, waiting until some has arrived. The `.add_data_received_callback()` method you're using is inappropriate when you *want* to wait for data. – jasonharper Jan 27 '20 at 16:38
  • I think you probably want to read the documentation here: https://xbplib.readthedocs.io/en/latest/user_doc/communicating_with_xbee_devices.html#polling-for-data It seems like you want to poll for the data (i.e. read it synchronously), rather than setup a call back and wait for the data to arrive (i.e. receive it asynchronously). – Doddie Jan 27 '20 at 16:42
  • Yes, it has read_data () but I need to run in a loop. And I wanted to avoid it. I need something to run the function when new data arrives ... – prem111 Jan 27 '20 at 16:43
  • @prem111 Blocking IO does that: it waits till data arrives, then you can process it and try to read again. It doesn't invalidate your question, though; you still want something external to signal your thread to end the loop in which you make the blocking reads. – chepner Jan 27 '20 at 16:47
  • So I have to use a loop for read_data ()? do I have other solutions? – prem111 Jan 27 '20 at 16:52

1 Answers1

2

This is just a rough sketch based on a cursory glance at the XBeeDevice documentation, but roughly speaking, you'll just perform a series of blocking reads until a certain condition is true, then exit.

def process_data(event):
    device = XBeeDevice(PORT, BAUD_RATE)
    device.open()
    while(event.is_set()):
        try:
            # 10 seconds is just a suggestion, as is what to do
            # if no data arrives in 10 seconds.
            data = device.read_data(10)
            print(..)
        except TimeoutException:
            pass  # Just try again
    device.close()

To start the thread, create a new Thread object and new Event object.

import threading

e = threading.Event()
e.set()

t = threading.Thread(target=process_data, args=(e,))
t.start()

# do some other stuff; eventually it's time to kill the loop in
# the thread.

e.clear()  # after this, e.is_set() will return False, and the loop
           # in your thread will exit.
chepner
  • 497,756
  • 71
  • 530
  • 681
  • Thank you for the example! I have another question. In this case, if two response are received at the same time? How to identify which request is answered? – prem111 Jan 27 '20 at 17:11
  • I'm not sure what you mean. I am assuming `read_data` returns one response at a time, and multiple incoming responses are simply queued up to be returned in the order they arrive, one per call to `read_data`. – chepner Jan 27 '20 at 17:14
  • that's exactly how it is. I mean how to identify which query is the answer. – prem111 Jan 27 '20 at 17:21
  • I don't know enough about `XBeeDevice` to understand or answer the question. – chepner Jan 27 '20 at 17:29
  • Can use some special markings in sending messages I want to know which question came to the answer – prem111 Jan 27 '20 at 17:31
  • Example: Client (says hello) -> server -> client (server: reply on says hello) Client (says hello2) -> server -> client (server: reply on says hello2) – prem111 Jan 27 '20 at 18:04