I build an app that sends a text message to an LCD with a PICO W. SENDING:
I can send the message with no problem.
I have created a scheduled background task (every 1 minute ), that checks my database and sends the last message that not has been sent when the planned time of sending has expired compared with the actual time. Works fine. USER SEND BACK:
anvil.pico.call(“msgback”, nr, resp)
The user acknowledges that the message is read by pushing on a button and this sends the “message number” back together with the response True. If he didn’t respond, I created a timer in the Pico that sends the “message number” back as unread with the response = False. Works fine as long as the response time does not exceed 30 seconds after receiving the message. THE PROBLEM:
After 30 seconds of receiving the incoming message, the server goes into a timeout. When the anvil.pico.call(“msgback”, nr, resp) is called, the connection has to be rebuild:
Connecting to Anvil…
Connected
Authenticated to app XXXXXXXXXX
This takes some seconds and at that time, the anvil.pico.call is not executed.
THE QUESTIONS:
how can I check in my Pico program if the server is disconnected?
how can I reconnect the server before executing the anvil.pico.call(“msgback”, nr, resp)?
can I change the scheduled background task time to less than 1 minute? Should this help?
I’d like to suggest an alternative that is not subject to timeout in the first place.
As I understand it, msgback doesn’t return until the user responds. Instead, let it return immediately. Then, when the user responds, the Pico should call the server back, with the response.
To uniquely identify which message they’re responding to, pass the database table row-id of the message.
Ok, thank you for the input.
The point is that I will get the same problem, if the user or the timer function is active it calls the function anvil.pico.call(“msgback”, nr, resp), and the server will then be not active anymore and will only turn on when I call this function. But maybe you give me an idea that I have to try:
run this part of the msgback call continuously in a while True loop (so keeping the server alive), send the result to the server of the app, and in the server code check if it has changed or not and update the database if necessary.
For the moment i call this anvil.pico.call only when the situation changes, this means when the user push the button when the message is read or if the timeout is passed (that I wrote in my pico program).
If the reply happens within 30 sec after sending the initial message, there is no problem. Once this time delay is passed so more than 30 sec, the anvil server goes in sleep mode (This is also confirmed in the docs). When the pico program arrives than at the point of calling anvil.pico.call, you see clearly in the IDE shell :
Connecting to Anvil…
Connected
Authenticated to app XXXXXXXXXX
So the connection is restarted, but this take different seconds to be re-established (just like on the initial start).
In that time, the action for the call is not happened, so no data is sent back to my database even when I increase the await delay.
What happens if you make another anvil server callable that returns some value, then have the pico wait until that ‘ping’ value is returned before sending your data.
I agree what you are describing probably shouldn’t be happening, but waiting for confirmation that the anvil server has spun up might be a workaround.
Yes, this is maybe also a possibility, I need to test it.
But these are all walk around.
I would like to be able to test in the Micropython code, if the server is a sleep or not.
So just an if statement something like this:
if server.connected :
anvil.server.call(…)
else:
anvil.server.connect
wait for connection
anvil.server.call(…)
But I cannot find the micropython code to check if the server is alive or not and how to connect again.
Well I think there is a difference between questions about the states of:
“do you have an anvil connection that is available to send or receive data” (calls in either direction)
and
“is the virtual instance of the anvil server module currently spun up and running on anvil for the particular app that your uplink key belongs to” (this is what times out after 30 seconds)
The micropython code is available on github, the author is @daviesian:
Unzip the
link to check it out for yourself.
I’ve been looking into it and I actually don’t understand how the .connect() or .connect_async() functions don’t end up repeatedly connecting to anvil over and over every one second in a loop. The regular anvil-uplink code avoids this through a global connection object that re-connects if it is disconnected, but the pico.py code looks as if it runs the internal _connect function every second, I can’t find something that stops it. (i.e. I think I must be missing something)