digidotcom / xbee-micropython

MIT License
73 stars 30 forks source link

read(-1) blocking? #65

Open GHamblin opened 3 years ago

GHamblin commented 3 years ago

It appears that sometimes stdin.buffer.read(-1) is blocking. Is there any way to determine if something is in the buffer before attempting to read from it?

mikewadsten commented 3 years ago

Hi,

Would you be able to provide a simplified piece of example code which demonstrates this issue? Also, can you tell us which XBee product and firmware version you are seeing this on?

GHamblin commented 3 years ago

Here is the function that's causing me issues. It will hang until I send it a newline. The data it receives from the device is already terminated with a new line, But it blocks until I manually send it a newline.

Thanks for looking into this. I am a Python noob, so I may have also done something wrong without realizing it.

def subscribe_test(client_id=CLIENT_ID, hostname=SERVER, topic=SUB_TOPIC, blocking=False): """ Connects to the MQTT server subscribes to a topic and waits for messages coming from that topic. :param client_id: Unique identifier for the device connected. :param hostname: Host name to connect to. :param topic: Name of the topic to subscribe. :param blocking: True to block the client waiting for messages, False to poll for messages. """

Connect to the MQTT server.

client = MQTTClient(client_id, hostname)
client.KEEP_QOS0 = False
client.NO_QUEUE_DUPS = True
client.MSG_QUEUE_MAX = 2
client.set_callback(sub_cb)
print("- Connecting to '%s'... " % hostname, end="")
if not client.connect(clean_session=False):
    print("New session being set up")
    client.subscribe(b"/Machines/100002/cmd", qos=1, resubscribe=True)
print("[OK]")
# Subscribe to topic.
# print("- Subscribing to topic '%s'... " % "/Machines/100002/cmd",

end="")

client.subscribe("/Machines/100002/cmd")

print("[OK]")
# Wait for messages.
print("Waiting for input lines")
loops = 0
while True:
    client.check_msg()

    if (begin = stdin.buffer.read(-1)):
        data = stdin.buffer.readline()
        data = begin + data

    if len(data) > 20:
        publish_message(client, topic, data)

        # Need to sleep to avoid 100% CPU usage.
    utime.sleep_ms(200)
    loops += 1
    if loops > 7500:
        client.ping()
        loops = 0
        while client.is_conn_issue():
            # If the connection is successful, the is_conn_issue
            # method will not return a connection error.
            client.reconnect()
    else:
        client.resubscribe()
        client.check_msg()
        client.send_queue()

On Mon, Feb 22, 2021 at 9:42 AM Mike Wadsten notifications@github.com wrote:

Hi,

Would you be able to provide a simplified piece of example code which demonstrates this issue? Also, can you tell us which XBee product and firmware version you are seeing this on?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/digidotcom/xbee-micropython/issues/65#issuecomment-783507879, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA45DCWC4DGLYWKNUVVEAUDTAKCPBANCNFSM4X7QPUJQ .

mikewadsten commented 3 years ago
if (begin = stdin.buffer.read(-1)):

That is not (or should not be) valid Python/MicroPython. I take it you're coming from C or C++ (or similar language). Variable assignments in Python are not expressions, and you cannot do this. https://www.quora.com/Why-does-the-Python-assignment-not-return-a-value

If you send Ctrl-C while the program is hung, what line does the resulting traceback point to? That will tell you (and us) where it is hanging.

GHamblin commented 3 years ago

Thanks. I'll try ^C and get back to you.

So begin = stdin.buffer.read(-1) should be a line by itself, followed by an if begin: ?

On Tue, Feb 23, 2021 at 2:35 PM Mike Wadsten notifications@github.com wrote:

if (begin = stdin.buffer.read(-1)):

That is not (or should not be) valid Python/MicroPython. I take it you're coming from C or C++ (or similar language). Variable assignments in Python are not expressions, and you cannot do this. https://www.quora.com/Why-does-the-Python-assignment-not-return-a-value

If you send Ctrl-C while the program is hung, what line does the resulting traceback point to? That will tell you (and us) where it is hanging.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/digidotcom/xbee-micropython/issues/65#issuecomment-784528793, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA45DCXRABRFGE23UB4FG43TAQNSNANCNFSM4X7QPUJQ .

mikewadsten commented 3 years ago

So begin = stdin.buffer.read(-1) should be a line by itself, followed by an if begin: ?

Yes, exactly.

GHamblin commented 3 years ago

Here's the result of the ^C. And yes I have had a long relationship with C in the embedded world.

Traceback (most recent call last): File "main", line 139, in =subscribe_test(blocking=False ) File "main", line 96, in subscribe_test = utime.sleep_ms(200) KeyboardInterrupt:

On Tue, Feb 23, 2021 at 2:35 PM Mike Wadsten notifications@github.com wrote:

if (begin = stdin.buffer.read(-1)):

That is not (or should not be) valid Python/MicroPython. I take it you're coming from C or C++ (or similar language). Variable assignments in Python are not expressions, and you cannot do this. https://www.quora.com/Why-does-the-Python-assignment-not-return-a-value

If you send Ctrl-C while the program is hung, what line does the resulting traceback point to? That will tell you (and us) where it is hanging.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/digidotcom/xbee-micropython/issues/65#issuecomment-784528793, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA45DCXRABRFGE23UB4FG43TAQNSNANCNFSM4X7QPUJQ .