131
131
# pylint: disable=too-many-lines
132
132
133
133
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
+
134
223
class ESP_SPIcontrol : # pylint: disable=too-many-public-methods, too-many-instance-attributes
135
224
"""A class that will talk to an ESP32 module programmed with special firmware
136
225
that lets it act as a fast an efficient WiFi co-processor"""
@@ -359,7 +448,7 @@ def firmware_version(self):
359
448
if self ._debug :
360
449
print ("Firmware version" )
361
450
resp = self ._send_command_get_response (_GET_FW_VERSION_CMD )
362
- return resp [0 ]
451
+ return resp [0 ]. decode ( "utf-8" ). replace ( " \x00 " , "" )
363
452
364
453
@property
365
454
def MAC_address (self ): # pylint: disable=invalid-name
@@ -397,16 +486,19 @@ def get_scan_networks(self):
397
486
# print("SSID names:", names)
398
487
APs = [] # pylint: disable=invalid-name
399
488
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 ]
405
489
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
+ )
410
502
return APs
411
503
412
504
def scan_networks (self ):
@@ -512,23 +604,12 @@ def _wifi_set_ap_passphrase(self, ssid, passphrase, channel):
512
604
raise OSError ("Failed to setup AP password" )
513
605
514
606
@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
532
613
533
614
@property
534
615
def network_data (self ):
@@ -942,7 +1023,7 @@ def set_digital_read(self, pin):
942
1023
:param int pin: ESP32 GPIO pin to read from.
943
1024
"""
944
1025
# 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 ]
946
1027
assert int (fw_semver_maj ) >= 5 , "Please update nina-fw to 1.5.0 or above."
947
1028
948
1029
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):
961
1042
:param int atten: attenuation constant
962
1043
"""
963
1044
# 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 ]
965
1046
assert int (fw_semver_maj ) >= 5 , "Please update nina-fw to 1.5.0 or above."
966
1047
967
1048
resp = self ._send_command_get_response (_SET_ANALOG_READ_CMD , ((pin ,), (atten ,)))
0 commit comments