Low power software recovery from wifi outage

I have recently found an unwanted state with my current code design.

To sum up whats going on: Imp sleeps all the time. An MSP430 wakes it up gives it data via the UART. The device does some processing of the data and then sends it to the agent, then goes back to server.sleepfor. i do this because on these proto devices the bucking converter does not have the guts to run this for very long without overheating.

The unwanted state occurs when the local wifi is down; The device goes into the ‘squirrell stay alive, retry for connection every 60 seconds’ loop. And this repeats until the wifi is restored. This is killing my power supply.

What I would like to do is detect that state and go back to sleep for 30 minutes. Then it can warm boot and try to connect again…

I have very quickly tried to add
`
server.setsendtimeoutpolicy(RETURN_ON_ERROR, WAIT_TIL_SEND, 30)

function disconnected(xx){imp.deepsleepfor(1800);}

server.onunexpecteddisconnect(disconnected);

`
I put it before all my other device code. And it is not working as I had expected.

What appears to be happening after is after any warmboot, it continually goes to sleep for 30 minutes.
I say this because it is no longer giving me any of the normal server.logs alerts even though the local wifi is currently running.

When it wakes on a warm boot, does it set the ‘RETURN_ON_ERROR’ flag?
Did I do anything stupid in here?

One more stupid question: Does it really need to have the setsendtimeoutpolicy if this is the default policy?

I also use server.onunexpecteddisconnect(_onDisconnect) to cover the unexpected events. Apparently failing to connect at startup is not “unexpected”. The handler for server.onunexpecteddisconnect() is not called in this scenario. This wasn’t obvious to me either, but became clear through testing.

When I initialise the device I use the following:

`  _onConnect(server.isconnected()?SERVER_CONNECTED:-1);
`

and when I want to attempt reconnection, I use:

` server.connect(_onConnect, yourTimeoutValue);
`

My routine _onConnect takes appropriate action depending on the value of ‘reason’:

`    function _onConnect(reason) {
            
        if (reason==SERVER_CONNECTED) {
            // connect has succeeded, take action
        }
        else {
            // connect has failed, take action
            // reconnect or go to sleep
        }
    }
`

Thanks for the insight!

How long do i need to wait before server.isconnected() check can be run?

It’s all hopefully made a bit clearer at https://electricimp.com/docs/resources/wifistatediagram/

In particular, on a warm boot there is no attempt to connect unless the Squirrel code initiates one. If RETURN_ON_ERROR is in effect, that’s an explicit call to server.connect(); if the default SUSPEND_ON_ERROR is in effect, that’s any call that uses the network (server.*, agent.send).

Peter

is the code listing for RETURN_ON_ERROR in here correct?
it seems like the functions and callback names are incorrect…

@peter the question I have with the wifi state diagram is on the ‘return on error’ policy

  1. The code calls server.connect
  2. Enter ACTIVE CONNECTING
  3. WIFI goes up
  4. Enter ACTIVE ONLINE

In my case where the WIFI is not available; the connection fails and the state returns to ACTIVE CONNECTING.

Then what happens? Does it return to ACTIVE ONLINE because of the ‘return on error’ policy? If that is the case, do I need to start back at 1)?

Do the error states/flags survive ASLEEP (it sort of seems like they do)?

If a call to server.connect() fails or times out, under RETURN_ON_ERROR, then the connect callback (if any) is called, and the state becomes ACTIVE_OFFLINE. No further attempt to connect is made until Squirrel calls server.connect() again.

It’s often useful for the connect callback, and the unexpected-disconnect callback, to be the same function: in both cases you might want to schedule a later connection attempt (or, you might not).

Peter

how does
[Exit Code] imp restarted, reason: wifi outage
fit into the state diagram

Wifi outage is the message if the imp has woken from a SNOOZE state and then successfully connected - ie it’s in SUSPEND_ON_ERROR, failed to connect for 60 seconds, and then slept for 9 minutes, connecting when it woke (or on a subsequent cycle if the internet wasn’t available after one sleep).

thanks Hugo!

@Hugo, what are the circumstances where the device is in SUSPEND_ON_ERROR? I still get “reason: wifi outage” occasionally and the first line of my device code is:

server.setsendtimeoutpolicy(RETURN_ON_ERROR, WAIT_TIL_SENT, 30);

It will go to SUSPEND_ON_ERROR mode if your squirrel hits a runtime error - it tries to connect to report the problem. However, right now, if it doesn’t manage to report it before sleeping, the error is lost and I believe you’d just see the wifi outage report.

Is that possible in your case?

This is certainly possible in my case. We now have 7 protos running and while 4 work as designed, 2 regularly throw wifi outage comments. I had thought it was rssi, so I added signal strength to the log, but the worst offender has 5 bars (-42dbm).

We are hunting through the hardware right now just to make sure the issue is software domain