Is there a way to check WiFi.isOn() or WiFi.isOff() as there is for Cellular

I'm porting some code from Cellular to WiFi and noticed there do not appear to be any WiFi.isOn() or WiFi.isOff() functions to match Cellular.isOn() or Cellular.isOff().

Is there any other way to do this check, or is it unnecessary - ie. no factors to consider before switching WiFi.on() or WiFi.off() ?

The functions WiFi.isOn() and WiFi.isOff() exist despite not being documented. They're in the base class Network and that fallback will work for WiFi.

Many thanks! However, this give me compilation errors, perhaps because I need to #include something? I tried #include "Network.h" but no joy. Any suggestions?

You don't need to include anything. What device and Device OS version are you targeting?

I tested with P2 5.6.0 and Argon 4.2.0 and this compiled successfully:

Log.info("WiFi on: %d", WiFi.isOn());

If you need code that compiles for both cellular and WiFi devices, you'll either need to surround the code with #if Wiring_WiFi or use Network.isOn() instead. The networks call will work for both cellular and Wi-Fi devices.

Ah! My bad: Had not specified the right compiler/Device OS indeed!
...and thanks for the tip re Network.isOn() etc. Much more elegant than the #if Wiring_WiFi that I had been using! However, my guess is I would still need this for sleep configuration(?)

			Log.info("sleeping with Network on for [sec] " + String(sleepTime));
			config.mode(SystemSleepMode::STOP)
#if Wiring_WiFi
				.network(NETWORK_INTERFACE_WIFI_STA) 	// this takes a lot of power!
#endif
#if Wiring_Cellular
				.network(NETWORK_INTERFACE_CELLULAR) 	// this takes a lot of power!
#endif
				.duration(sleepTime * 1000);		 	// in ms (unlike classic sleep fn)

Yes, that is how you'd have to do it. However, the P2 and Photon 2 cannot wake on Wi-Fi network; there is no network standby mode for Wi-Fi on these devices. Also, the M-SoM only supports it for the cellular interface, not the Wi-Fi interface.

So using Network.xxx() functions is an elegant way to handle multi-platform connectivity-related code, but I've encountered one mystifying problem. Consider this code snippet:

SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);

// Do things while not connected, then when we need to connect...

			if (Network.isOff()) {							// Turn wifi/cellular on + connect to cloud (call only once!)
				Network.on();								// Lower level connect() and ready()
				Particle.connect(); 						// will be handled automatically
			}

// Do things while connected, then when we want to disconnect...

			if (Particle.connected()) { 
				Log.info("disconnecting " + Time.timeStr());	// need to do this manually if we want the modem off
				Particle.disconnect();				  			// and to remain off on wakeup
				waitUntilNot(Particle.connected);	  			// Blocking
			}
			if (Network.isOn()) {
				Log.info("turning wifi/cell network off" + Time.timeStr());
	//			Network.off();
	//			waitUntil(Network.isOff);						// ***Blocking****
				WiFi.off();
				waitUntil(WiFi.isOff);					    	// ***Blocking****
				Log.info("wifi/cell network successfully turned off" + Time.timeStr());
			}

// Then do other non-connected things including going to sleep

This code works fine, but if I replace the platform-specific calls to WiFi.off(), WiFi.isOff with their (currently commented out) Network equivalents, then the program hangs while waiting for the WiFi to be turned off and the last Log.info message never appears. Any thoughts on what is going wrong? [Argon, DeviceOS 4.2.0]

As an aside, I am not experienced in writing threaded programs, but wondered if it was possible to write this in a way that avoided blocking other things while waiting to connect / disconnect?

Thanks as always!

What version of Device OS and which device are you using?

Network.on() should work on Device OS 5.6.0 and later which support connection management. It probably does not work properly in earlier versions.

Thanks. I am using Argon with DeviceOS 4.2.0 which I believe is the latest LTS version and the version installed if I do particle update within CLI. I see I could do particle update --target 5.6.0 myDevice. Would you recommend this? Are there any downsides to doing so?

I finally got around to testing this with Device OS 6.1.0 on an Argon.

  • Network.isOn(), and Network.isOff() and Network.on() all work fine,
  • ...but strangely Network.off() still does not work in my case.
    [My original code snippet still hangs if I replace the WiFi.off() with its Network equivalent - so for now I'm using #if Wiring_WiFi etc]

I tried inserting a WiFi.prefer() in setup in case that helped, but it made no difference. Is this a bug, or am I missing something?...

It appears that Network.off() will not work in your case. While it might make sense for it to turn off the current network interface, or all interfaces, it does neither. I'm not sure why.

It appears that you need to explicitly turn off all interface you want to turn off using a #if surrounding the appropriate call for WiFi, Cellular, or Ethernet.