Multiple WiFi Settings

Sign me up also.

Pls sign me up too.

Willing to participate in the test as well.

Is there a way to try a default SSID+password or trying out open networks “walking by” without loosing the original blinkup wifi configuration?
This would enable a lost Imp to try to connect to the agent or a server and check for new credentials, when the blinked up wifi is gone / has changed password.
Today when deploying remotely with huge organisations that don’t care for blinkup, and later “someone” changes the password, maybe even routinely, service personnel have to go onsite and blink up new credentials.

Sign me up too, I already got multiple mine can connect to.

@Hugo Are there plans on multiple wifi configurations? An approach could be to always keep the blink-up configured credentials (backward compatibility), allow a second user defined pair of SSID/Password via setwificonfiguration, choose via the API which of the two is active (and ask for status). I guess an IMP with user defined credentials, should accept a new blink-up as the new active setting (keeping the user defined set stored), simply because blink-up was not disabled to prevent it. The user defined wifi configuration password is not kept secret, as it can only be set by the program. The exception is if the token is changed for a new account in which case the user defined set is deleted by the firmware. The programmer can keep a connection list as long as needed …

I think you can do this in code. When the device disconnects, you can use imp.scanwifinetworks() to look for open networs and then, when you find one, apply its SSID to the device by using imp.setwificonfiguration().

To manage the disconnected state, you need to use server.setsendtimeoutpolicy() to set the RETURN_ON_ERROR policy and then implement a disconnection handler function that must be registered with server.onunexpecteddisconnect().

Yes, I think so too. Not being able to go back to blink up credentials after trying out other options, seems to be the only thing missing. So basicly just need a imp.setwificonfiguration(blinkup). Then multiple SSID’s including the blink up credentials can be handled manually in code.

Is it possible to set WPS (no pin) via imp.setwificonfiguration()?

Not as yet, this is on the to-do list.

I’ve been working on wifi switching recently and have code that seems to work. I’ve just been testing it by turning on and off my phone-based hotspot. I have used versions of this code in most of my devices and for the most part it works but it was hard to follow everything in my relatively large device code.

This example is a short one that has one timer that sends a message to the agent. If it loses wifi connection it will run through the pre-programmed list of credentials and resume sending messages. Hope this can help someone and please do let me know if you find any problems with it or optimizations that could be done.

The _debug function is optional. If you don’t want that ability or are using the uart for something else then remove those parts of the code.

The code generally follows the example from the API documentation.

Agent

`device.on(“report”,function(iv){

server.log("device sent " + iv.ssid + " " + iv.millis);

});`

Device

`
//example code for changing wifi ssid and password

_wifi <- {
current = -1,
connections = [
{ ssid = “mainssid”, pw = “yourpassword” },
{ ssid = “anotherssid”, pw = “yourpassword” },
{ ssid = “yetanother”, pw = “yourpassword” }
]
};

//// BELOW HERE, THERE SHOULD NOT BE ANY PERSONAL INFORMATION ////////////////

debuguart <- hardware.uart57;
debuguart.configure(9600, 8, PARITY_NONE, 1, NO_CTSRTS);//no callback added

nextwakeup <- null; //will be a handle so that pending wakeups can be cancelled

function mylog(note){
if (server.isconnected()){
server.log(note);
}
}

function reporter (){
agent.send(“report”,{millis = hardware.millis(), ssid = imp.getssid()});
nextwakeup = imp.wakeup(20.0, reporter);
}

// ***********WIFI CODE **************** {

function _debug(note){
debuguart.write(note);
}

function ChangeWifi(ssid, pw, callback) {

// if we're connected
// disconnects from current network (if required)
// tries connecting with the supplied ssid / pw
// executes the callback 

if (server.isconnected()) {
    // flush wifi and disconnect
    _debug("disconnect, flush 30\

“);
server.flush(30);
server.disconnect();
}
_debug(“setwifi
”);
_debug(ssid);
_debug(pw);
debug("
”);
imp.setwificonfiguration(ssid, pw);
server.connect(callback, 30);
}

function ConnectOrFailToNextConnection(result = null) {

// if we're connected, do nothing
 
// This function doesn't use the result parameter,
// but it's required since it's the callback from 
// a server.connect()

if (!server.isconnected()) {
  
  _wifi.current++;
  
  if (_wifi.current >= _wifi.connections.len()) {
    _wifi.current = 0;
    // go to sleep for 5 minutes
    // if we've already tried all the connections
    _debug("end list, sleep 5 min\

");

    imp.deepsleepfor(5*60);
  }
  
    // if there are still connections to try
    // grab current ssid and pw, and increment _wifi.current
    // for the next attempt (if connection fails)
    
    local ssid = _wifi.connections[_wifi.current].ssid;
    local pw = _wifi.connections[_wifi.current].pw;
   
    // try connecting
    _debug("changing wifi\

");
ChangeWifi(ssid, pw, ConnectOrFailToNextConnection);

}
else
{   
    _debug("connected," +_wifi.current + "\

");
mylog("connected " + _wifi.current + " " + imp.getssid());
if (nextwakeup==null){

      mylog("start reporter from connection routine");
      nextwakeup = imp.wakeup(30,reporter);//kick off reporting again
    }
    else
    //if there is a wakeup - don't have to do anything
    {
    
    }
}

}

server.onunexpecteddisconnect(function(reason) {

// called after imp tries to reconnect to current
// server for 1 minute and fails
// Loop through connections until we connect

_wifi.current = -1;
ConnectOrFailToNextConnection();

});

server.setsendtimeoutpolicy(RETURN_ON_ERROR, WAIT_TIL_SENT, 30);

// On boot, make sure we’re connected
// or try connecting
ConnectOrFailToNextConnection();

// END WIFI CONFIGURATION
//}

//Line below is for testing: normally is commented out
//ChangeWifi( “wifissidtoforce”, “passwordtouse”,ConnectOrFailToNextConnection );
`

Looks solid. I think there is another example somewhere here doing a wifi scan beforehand, if connection time is an issue.

BTW. imp.setwificonfiguration("", “”) seems to keep the imp002 from ever starting the user code even in RETURN_ON_ERROR mode. Only recoverable by blinkup. So for applications setting credentials via the agent it seems best to block that option.

The imp should be starting the user code even with a blank config; this is how every production device gets shipped, essentially, so we’re pretty sure that works fine :slight_smile:

Got any minimal example code that shows this?

I am pretty sure you are wright :slight_smile: In the process of making example code, it turned out to be a runtime error before the unit got on a net, in combination with testing changing networks with a predefined list of AP’s (when the config is blank).

ThermIT, has mjkuwp94’s code worked for you then?

I instead scan for a match to a predefined list before connection attempts. But this remains an experiment, as my application requires ability to return to the blinked up credentials (e.g. if the connection attempt to another net fails). I understand this is not possible today.