Managing wireless connections on your IoT device, headless

Managing wireless connections on your IoT device, headless

April 24, 2019 | 10 min read
raspberry-pi IoT WiFi nmcli

Managing wireless connections on your IoT device, headless

Background :

Here is quick overview of my setup. So incase if you too are going in for the similar one, you know your job is not that daunting. Having said that if you have a distinct setup - the central idea still remains the same (Im assuming you are using Linux on your device).
Raspberries

  1. Raspberry Pi 3B : Since the beginning of my journey I have been a huge fan of this single board machine
  2. Raspbian Jessi Lite 32 bit OS _Lightweight , easy to install. Has its downside being a 32 bit system on a 64 bit machine, but we are ok here.
  3. Runs on headless mode Ah ! the sluggish GUIs
  4. WiFi password changes or has to selectively connect to a new network incase the primary internet gateway (Home WiFi) is down

Without internet you have just a device that automates. Rest all is Internet of things.

Reading that with a bit of cynical mind reveals, IoT without internet is yet another device. It further raises a question as to what would you need to do incase the user (neither the developer, nor the creator) needs to re-align his/her device to a new WiFi or the same WiFi with a new password ?
When the device cannot connect to any WiFi networks around it, can do mission critical stuff on the local database, reconfiguring the WiFi then needs user intervention.

Here are a few of ways you can sort this out

  • Connect the device to the nearest WiFi using LAN and then SSH into it. While this is a possibility , it is reserved for the technical few.
  • Via a mobile app you can (bluetooth)pair your handheld to the device and then open up APIs that can configure the wifi inturn. While this is the most common one, you would need to build apps for android & iOS and even Windows maybe. The effort to build and push changes is not worth the small task that the app is expected to perform.
  • Device runs a WiFi access point (WAP) and lets the handheld to get into the network. A web service on the device then can accept commands. Here you stay on the browser (platform agnostic) and there is no question of pushing changes.

I for, my setup am using a WAP incase there are no WiFi(s) that the device can connect to. How nmcli helps us is something that we arrive at in the consecutive sections.

Headless Raspberry and the struggle with WiFi :

Raspberries
Running the Raspberry Pi on headed mode is quite common, but then running the entire system light has its own advantages. Particularly the WiFi settings are easier to handle from a headed mode than to having a terminal access to the WiFi coniguration. Working your way thru the WiFi config in could be initially daunting but with nmcli, network manager it could be much less painful.

What you need your device to do with WiFi choices :

When you have a device running, you need it to do the following things w.r.t to WiFi connections :

  • Browsing network connections nearby
  • Saving connections with credentials
  • Auto connecting , connection priority
  • Fallback Access point , WiFi hotspot

Wireless Access Points help to turn the device into a WiFi hotspot, over which handhelds (/even computers) can connect to access the web server (possibly HTTP) running on the device. Put it out simply when no networks are found that the device can connect to, it should then itself act as a host to a web server allowing other hand held devices to access API.

Raspberry Pi Documentation

Learn how to turn your Raspberry Pi into a Wireless Access Point (WAP) from scratch with this comprehensive official guide.

Read Documentation

The above reference has everything to do with making a WAP from scratch, but wait till the next section nmcli indeed makes it easy to setup.

NMCLI to the rescue

Nmcli is a command line tool for managing NetworkManager and reporting network status. It allows users to create, display, edit, delete, activate, and deactivate network connections, as well as control and display network device status.

Why nmcli makes life easier

Watch this video tutorial to understand how nmcli simplifies network management on Linux systems.

Getting nmcli on your raspberry pi

sudo apt-get update
sudo apt-get install network-manager
# this shall install a number of packages as well

NetworkManager does not manage any interface defined in /etc/network/interfaces by default. The easiest way to manage some interfaces using NetworkManager is to comment them out.

sudo nano /etc/network/interfaces

comment out the ineterfaces as so...

auto lo
iface lo inet loopback

# Managed by NetworkManager
#iface eth0 inet manual

# Managed by NetworkManager
#auto wlan0
#allow-hotplug wlan0
#iface wlan0 inet dhcp
#    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

Now go ahead to inspect this file and find the details as below

sudo nano /etc/NetworkManager/NetworkManager.conf
[main]
plugins=ifupdown,keyfile

[ifupdown]
managed=false

This informs the network manager to only manage the interfaces not enlisted in the /etc/network/interfaces file.

Give your device a quick restart

nmcli dev status
DEVICE           TYPE      STATE      CONNECTION         
enxb827eb9d3108  ethernet  connected  Wired connection 1 
wlan0            wifi      connected  <SSID of Wifi> / ---        
lo               loopback  unmanaged  --

nmcli dev wifi

SSID              MODE   CHAN  RATE       SIGNAL  BARS  SECURITY  
*  UdanKhatola       Infra  1     54 Mbit/s  84      ▂▄▆█  WPA1 WPA2 
   Tvesha            Infra  2     54 Mbit/s  65      ▂▄▆_  WPA2      
   Arnav             Infra  2     54 Mbit/s  45      ▂▄__  WPA1 WPA2 
   A18_703           Infra  10    54 Mbit/s  44      ▂▄__  WPA1      
   ZTE-853bac        Infra  11    54 Mbit/s  32      ▂▄__  WPA1 WPA2 
   A16_704_2.4Ghz    Infra  9     54 Mbit/s  29      ▂___  WPA1 WPA2 
   homewifi          Infra  11    54 Mbit/s  25      ▂___  WPA1 WPA2 
   Moonlight 2.4GHz  Infra  9     54 Mbit/s  24      ▂___  WPA2      
   Rajeev            Infra  11    54 Mbit/s  22      ▂___  WPA2      
   Google-WifFi      Infra  1     54 Mbit/s  17      ▂___  WPA2      
   A5-703            Infra  5     54 Mbit/s  17      ▂___  WPA1 WPA2

Above is the list of all the networks around me. It shows this list in the descending order of the strengths. The channel of the WiFi could be of some interest, since it helps to know that RPi was built in the UK and Europeans dont consider CHN 13 & 14 as valid ones. Out here in India though it is easy to find even contemporary ISPs configuring their routers for CHN 13⁄14.

I did struggle with the channel setting initially , then wisely put that to CHN1. All is working fine since then.

When you know the SSID around you can add that as a connection. This is like saving the connection detail for later quick use. Incase it uses WPA/WPA_2 security mode the below example could be useful.

sudo nmcli connection add con-name HOMEOFFICE ifname wlan0 type wifi ssid HOMEOFFICE
# creates the connection, but has not assigned a WPA /WPA2 key to it
sudo nmcli con modify HOMEOFFICE wifi-sec.key-mgmt wpa-psk
#that modifies the existing connection
sudo nmcli con modify HOMEOFFICE wifi-sec.psk PASSKEY
# this assigns a key to the network which is encrypted 

Once added as a connection, check out all the connections on your device using the following command.

nmcli con show 
NAME                UUID                                  TYPE             DEVICE          
HOMEOFFICE          d420d540-3696-4ad8-aeff-b1c7ee5e9054  802-11-wireless  wlan0           
_$_$_$_$_$_         48537b88-d5e1-3577-b523-ec4f5b051691  802-3-ethernet   enxb827eb9d3108 

Saved a connection can be turned on (Analogous to connecting to saved networks), disconnect (down) the network and also forget (delete) the network. Please note all the below commands need elevated access rights.

sudo nmcli con up HOMEOFFICE
sudo nmcli con down HOMEOFFICE 
sudo nmcli con delete HOMEOFFICE

Getting the details of an individual connection is just one command ahead.

nmcli con show HOMEOFFICE
connection.id:                          HOMEOFFICE
connection.uuid:                        d420d540-3696-4ad8-aeff-b1c7ee5e9054
connection.stable-id:                   --
connection.interface-name:              wlan0
connection.type:                        802-11-wireless
connection.autoconnect:                 yes
connection.autoconnect-priority:        0
connection.autoconnect-retries:         -1 (default)
connection.timestamp:                   1556523041
connection.read-only:                   no
connection.permissions:                 
connection.zone:                        --
connection.master:                      --
connection.slave-type:                  --
connection.autoconnect-slaves:          -1 (default)
connection.secondaries:                 
connection.gateway-ping-timeout:        0
....
....
# for brevity sake I have posted only a part of attribute list

Understanding connection priority :

Network manager can asses a connection’s priority and check to see if that can pulled up. If the connection is not available the manager then jumps onto the next priority connection. __Higher the connection priority number, higher in the sequence of priority it is. __ As an example : Since we want the Access point to be connected only when there are no available connections, its autoconnect priority number has to be the lowest. It is worth noting that when a connection is created the default priority is 0, hence pushing the access point priority to -1 achieves what we want.

sudo nmcli con modify SSIDOFAP connection.autoconnect-priority -1

This indicates to the network manager to attempt and pull up the AP only when all other connections (Infrastructure) fail or are unavailable.

Last word:

Having a GUI to operate on WiFi connections management is convenient, but when you need programmatic access to WiFi configs, nmcli is a adequate choice that I have come to like. I have gone ahead to program such a use case in python. Readers interested can drop me a mail and I would be happy to share my repo.
Please also see : If the WAP is up, scanning the WiFi list will not work. Assume the WAP is up then the below command would not yield any results

nmcli device wifi list

Native command as below can be then handy and useful.

sudo iwlist wlan0 scan

References :

Installing Network Manager on RPi

Complete guide for setting up Network Manager on Raspberry Pi

Read Guide