Setting additional WiFi credentials

I am setting up some Photons to do some power monitoring at some remote locations that have generators. The design is simple, if the generator comes on, so does the Photon and it will publish an event to the Particle cloud. That way we know that there was a main power outage causing a generator to kick in.

Each site has WiFi and I need to program the credentials in in advance so that they will simply be plug and play. My local WiFi credentials are already functional of course so I can program and test here at work. I will NOT be able to be on site for installation, nor will anyone else be there that would understand how to perform any task other than plugging it in to power.

All I want to do is add a second set of credentials.

I have scoured the forum for a definitive way to do this, but all I can find are pretty lengthy discussions and none of them seem to have a simple answer. I would think this would be something that a lot of people would encounter. Maybe I just haven’t found the definitive post :wink:

So, basically, all I want to do is pre-program a second set of credentials on a Photon so I can flash these, test them here, then send them on their way and they will “just work” on site.

Does anyone have a “tried and true” code snippet example for doing this?

Thanks!

So, this?
https://docs.particle.io/reference/firmware/photon/#setcredentials-

Alternatively, this, which should be doable for anybody that can operate a smartphone:
https://docs.particle.io/reference/firmware/photon/#complete-example

If that's all that is necessary, a simple call to WiFi.setCredentials, that's great! I saw so many references to WiFi.on, WiFi.Connect, testing to see if it hasCredentials, etc. that it was confusing as to what the proper, recommended mechanism is. Asking the "installer" to do anything is simply not an option. They may not even know the proper operation of a light switch. I just have no control over that and I don't want to have someone stuck in a remote location needing to talk to me immediately.

I am just a casual Particle user. I mostly use Linux based boards. But I try to choose the best device for the job. I like Particle stuff (except the 2G Electrons I bought) but I am very careful. I deployed about 10 Photons running 24/7 about 18 months ago just doing dumb things so I could feel confident about reliability. Only one failed and was easily swapped out. So I feel good about deploying these now and just want to make sure I follow recommended procedures.

I wish the forum had voting with "Accepted Answer" so it would be easier to find the solutions here.

Thanks!

@bigdog, it would be a good idea to not call WiFi.setCredentials() every time you boot. You can first test if you have the credentials set with getCrendentials() and comparing the stored ssid against what you expected it to be. If it isn’t in the list of set credentials THEN you set the new credentials. To keep things clean before shipping, you may want to clear all the wifi credentials holding the setup button for 10+ seconds and then only setting your local credentials. Then, when the setCredentials() runs, it will be the only other set of credentials to compare against.

1 Like

this worked to prevent the constant re-flashing of credentials:

  WiFiAccessPoint ap[5];
  int found = WiFi.getCredentials(ap, 5);
  bool gotMyMacCreds = false;
  for (int i = 0; i < found; i++) {
    if(strstr(ap[i].ssid, "SomeSSID"))
    {
      gotMyMacCreds = true;
      Serial.println("had creds");
    }
  }
  if(!gotMyMacCreds)
  {
    WiFi.setCredentials("SomeSSID", "SomePassword");
    Serial.println("set creds");
  }
  waitUntil(Particle.connected);

setCredentials() only called if it wasn’t already stored…

2 Likes

Opened an issue to hopefully have it taken care of in firmware: https://github.com/spark/firmware/issues/1287

1 Like

I thought it was discovered that you also need to pass the WiFi encryption method to WiFi.setCredentials(ssid,passwd,etype) if the network in question is not currently visible.

1 Like

@kennethlimcp, the issue will persist if people clear and then set credentials in their code, which I have seen quite often.

1 Like

@peekay123 will having the checks in firmware solve the issue?

@kennethlimcp, only partially. The issue is more about awareness.

2 Likes

And if it is a WPA/WPA2 network it needs the WLAN_CIPHER too.

1 Like

I just ran across this thread because I too have a simple product that I need to ship with the WiFi credentials already loaded. I ended up with the following which I thought was the “best” way before reading this thread. Note, I start in SEMI-AUTOMATIC mode.

    WiFi.on();                                                  // Turn WiFi on
    WiFi.clearCredentials();                                    // Clear WIFI credentials
    WiFi.setCredentials("SSID", "password", WPA2, WLAN_CIPHER_AES);    // hidden SSID
    WiFi.connect();                                             // Connect to WiFi
    Particle.connect();                                         // Connect to Particle cloud
    waitUntil(Particle.connected);                              // Wait until the cloud connection is established
    waitUntil(Time.isValid);     

I wasn’t aware of any potential long-term issues with erasing and writing the credentials on boot. Theoretically this would only happen several times a year once in production. I’m guessing I don’t need the WiFi.on() or WiFi.connect() either?

I’m going with the solution provided by @BulldogLowell and just because I hate embedding numbers into code, I added the following:

#define PHOTON_SSIDS     5      // disable for Photon
#define CORE_SSIDS       7      // disable for Core

and changed the following:

WiFiAccessPoint ap[PHOTON_SSIDS];
int found = WiFi.getCredentials(ap, PHOTON_SSIDS);

And I threw in a break() if I match an SSID so I can bail out of the for() loop early.

Additional thanks to @peekay123 for the reminder about not writing to flash too often. This definitely sounds like something that should be a NOTE: in the documentation.

1 Like

You can actually define your SSID_COUNT that way

#if ( PLATFORM_ID == PLATFORM_SPARK_CORE )
 #define SSID_COUNT 7
#elif (PLATFORM_ID == PLATFORM_PHOTON_PRODUCTION ) 
   || (PLATFORM_ID == PLATFORM_P1 )  
 #define SSID_COUNT 5
#endif
...
WiFiAccessPoint ap[SSIDS_COUNT];
int found = WiFi.getCredentials(ap, SSIDS_COUNT);

This will auto-adjust the value just by target seletion without the need to (un)comment anything.

@ScruffR,

I couldn’t get your code to compile on my Photon. Had to change to:

#if ( PLATFORM_ID == PLATFORM_SPARK_CORE )
 #define SSID_COUNT             7
#elif ((PLATFORM_ID == PLATFORM_PHOTON_PRODUCTION) || (PLATFORM_ID == PLATFORM_P1))
 #define SSID_COUNT             5
#endif

Yup, that was a typo, but in essence it did work, didn’t it?

Yes, the concept was much more flexible.

I wasn’t aware those defines existed. Hey Particle documenters, how about a page of all of these type of shortcuts we can utilize?

1 Like