131131# pylint: disable=too-many-lines
132132
133133
134+ class Network :
135+ """A wifi network provided by a nearby access point."""
136+
137+ def __init__ ( # pylint: disable=too-many-arguments
138+ self ,
139+ esp_spi_control = None ,
140+ raw_ssid = None ,
141+ raw_bssid = None ,
142+ raw_rssi = None ,
143+ raw_channel = None ,
144+ raw_country = None ,
145+ raw_authmode = None ,
146+ ):
147+ self ._esp_spi_control = esp_spi_control
148+ self ._raw_ssid = raw_ssid
149+ self ._raw_bssid = raw_bssid
150+ self ._raw_rssi = raw_rssi
151+ self ._raw_channel = raw_channel
152+ self ._raw_country = raw_country
153+ self ._raw_authmode = raw_authmode
154+
155+ def _get_response (self , cmd ):
156+ respose = self ._esp_spi_control ._send_command_get_response ( # pylint: disable=protected-access
157+ cmd , [b"\xFF " ]
158+ )
159+ return respose [0 ]
160+
161+ @property
162+ def ssid (self ):
163+ """String id of the network"""
164+ if self ._raw_ssid :
165+ response = self ._raw_ssid
166+ else :
167+ response = self ._get_response (_GET_CURR_SSID_CMD )
168+ return response .decode ("utf-8" )
169+
170+ @property
171+ def bssid (self ):
172+ """BSSID of the network (usually the AP’s MAC address)"""
173+ if self ._raw_bssid :
174+ response = self ._raw_bssid
175+ else :
176+ response = self ._get_response (_GET_CURR_BSSID_CMD )
177+ return bytes (response )
178+
179+ @property
180+ def rssi (self ):
181+ """Signal strength of the network"""
182+ if self ._raw_bssid :
183+ response = self ._raw_rssi
184+ else :
185+ response = self ._get_response (_GET_CURR_RSSI_CMD )
186+ return struct .unpack ("<i" , response )[0 ]
187+
188+ @property
189+ def channel (self ):
190+ """Channel number the network is operating on"""
191+ if self ._raw_channel :
192+ return self ._raw_channel [0 ]
193+ return None
194+
195+ @property
196+ def country (self ):
197+ """String id of the country code"""
198+ return self ._raw_country
199+
200+ @property
201+ def authmode (self ):
202+ """String id of the authmode
203+
204+ derived from Nina code:
205+ https://github.com/adafruit/nina-fw/blob/master/arduino/libraries/WiFi/src/WiFi.cpp#L385
206+ """
207+ if self ._raw_authmode :
208+ response = self ._raw_authmode [0 ]
209+ else :
210+ response = self ._get_response (_GET_CURR_ENCT_CMD )[0 ]
211+
212+ if response == 7 :
213+ return "OPEN"
214+ if response == 5 :
215+ return "WEP"
216+ if response == 2 :
217+ return "PSK"
218+ if response == 4 :
219+ return "WPA2"
220+ return "UNKNOWN"
221+
222+
134223class ESP_SPIcontrol : # pylint: disable=too-many-public-methods, too-many-instance-attributes
135224 """A class that will talk to an ESP32 module programmed with special firmware
136225 that lets it act as a fast an efficient WiFi co-processor"""
@@ -359,7 +448,7 @@ def firmware_version(self):
359448 if self ._debug :
360449 print ("Firmware version" )
361450 resp = self ._send_command_get_response (_GET_FW_VERSION_CMD )
362- return resp [0 ]
451+ return resp [0 ]. decode ( "utf-8" ). replace ( " \x00 " , "" )
363452
364453 @property
365454 def MAC_address (self ): # pylint: disable=invalid-name
@@ -397,16 +486,19 @@ def get_scan_networks(self):
397486 # print("SSID names:", names)
398487 APs = [] # pylint: disable=invalid-name
399488 for i , name in enumerate (names ):
400- a_p = {"ssid" : name }
401- rssi = self ._send_command_get_response (_GET_IDX_RSSI_CMD , ((i ,),))[0 ]
402- a_p ["rssi" ] = struct .unpack ("<i" , rssi )[0 ]
403- encr = self ._send_command_get_response (_GET_IDX_ENCT_CMD , ((i ,),))[0 ]
404- a_p ["encryption" ] = encr [0 ]
405489 bssid = self ._send_command_get_response (_GET_IDX_BSSID_CMD , ((i ,),))[0 ]
406- a_p ["bssid" ] = bssid
407- chan = self ._send_command_get_response (_GET_IDX_CHAN_CMD , ((i ,),))[0 ]
408- a_p ["channel" ] = chan [0 ]
409- APs .append (a_p )
490+ rssi = self ._send_command_get_response (_GET_IDX_RSSI_CMD , ((i ,),))[0 ]
491+ channel = self ._send_command_get_response (_GET_IDX_CHAN_CMD , ((i ,),))[0 ]
492+ authmode = self ._send_command_get_response (_GET_IDX_ENCT_CMD , ((i ,),))[0 ]
493+ APs .append (
494+ Network (
495+ raw_ssid = name ,
496+ raw_bssid = bssid ,
497+ raw_rssi = rssi ,
498+ raw_channel = channel ,
499+ raw_authmode = authmode ,
500+ )
501+ )
410502 return APs
411503
412504 def scan_networks (self ):
@@ -512,23 +604,12 @@ def _wifi_set_ap_passphrase(self, ssid, passphrase, channel):
512604 raise OSError ("Failed to setup AP password" )
513605
514606 @property
515- def ssid (self ):
516- """The name of the access point we're connected to"""
517- resp = self ._send_command_get_response (_GET_CURR_SSID_CMD , [b"\xFF " ])
518- return resp [0 ]
519-
520- @property
521- def bssid (self ):
522- """The MAC-formatted service set ID of the access point we're connected to"""
523- resp = self ._send_command_get_response (_GET_CURR_BSSID_CMD , [b"\xFF " ])
524- return resp [0 ]
525-
526- @property
527- def rssi (self ):
528- """The receiving signal strength indicator for the access point we're
529- connected to"""
530- resp = self ._send_command_get_response (_GET_CURR_RSSI_CMD , [b"\xFF " ])
531- return struct .unpack ("<i" , resp [0 ])[0 ]
607+ def ap_info (self ):
608+ """Network object containing BSSID, SSID, authmode, channel, country and RSSI when
609+ connected to an access point. None otherwise."""
610+ if self .is_connected :
611+ return Network (esp_spi_control = self )
612+ return None
532613
533614 @property
534615 def network_data (self ):
@@ -942,7 +1023,7 @@ def set_digital_read(self, pin):
9421023 :param int pin: ESP32 GPIO pin to read from.
9431024 """
9441025 # Verify nina-fw => 1.5.0
945- fw_semver_maj = bytes ( self .firmware_version ). decode ( "utf-8" ) [2 ]
1026+ fw_semver_maj = self .firmware_version [2 ]
9461027 assert int (fw_semver_maj ) >= 5 , "Please update nina-fw to 1.5.0 or above."
9471028
9481029 resp = self ._send_command_get_response (_SET_DIGITAL_READ_CMD , ((pin ,),))[0 ]
@@ -961,7 +1042,7 @@ def set_analog_read(self, pin, atten=ADC_ATTEN_DB_11):
9611042 :param int atten: attenuation constant
9621043 """
9631044 # Verify nina-fw => 1.5.0
964- fw_semver_maj = bytes ( self .firmware_version ). decode ( "utf-8" ) [2 ]
1045+ fw_semver_maj = self .firmware_version [2 ]
9651046 assert int (fw_semver_maj ) >= 5 , "Please update nina-fw to 1.5.0 or above."
9661047
9671048 resp = self ._send_command_get_response (_SET_ANALOG_READ_CMD , ((pin ,), (atten ,)))
0 commit comments