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
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?
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.
@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.
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.
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.