Skip to content

Commit

Permalink
Merge pull request #209 from justmobilize/add-ap-info
Browse files Browse the repository at this point in the history
Add ap_info
  • Loading branch information
dhalbert authored Jun 24, 2024
2 parents 7bf8763 + 2da9843 commit e7e129a
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 58 deletions.
139 changes: 110 additions & 29 deletions adafruit_esp32spi/adafruit_esp32spi.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,95 @@
# pylint: disable=too-many-lines


class Network:
"""A wifi network provided by a nearby access point."""

def __init__( # pylint: disable=too-many-arguments
self,
esp_spi_control=None,
raw_ssid=None,
raw_bssid=None,
raw_rssi=None,
raw_channel=None,
raw_country=None,
raw_authmode=None,
):
self._esp_spi_control = esp_spi_control
self._raw_ssid = raw_ssid
self._raw_bssid = raw_bssid
self._raw_rssi = raw_rssi
self._raw_channel = raw_channel
self._raw_country = raw_country
self._raw_authmode = raw_authmode

def _get_response(self, cmd):
respose = self._esp_spi_control._send_command_get_response( # pylint: disable=protected-access
cmd, [b"\xFF"]
)
return respose[0]

@property
def ssid(self):
"""String id of the network"""
if self._raw_ssid:
response = self._raw_ssid
else:
response = self._get_response(_GET_CURR_SSID_CMD)
return response.decode("utf-8")

@property
def bssid(self):
"""BSSID of the network (usually the AP’s MAC address)"""
if self._raw_bssid:
response = self._raw_bssid
else:
response = self._get_response(_GET_CURR_BSSID_CMD)
return bytes(response)

@property
def rssi(self):
"""Signal strength of the network"""
if self._raw_bssid:
response = self._raw_rssi
else:
response = self._get_response(_GET_CURR_RSSI_CMD)
return struct.unpack("<i", response)[0]

@property
def channel(self):
"""Channel number the network is operating on"""
if self._raw_channel:
return self._raw_channel[0]
return None

@property
def country(self):
"""String id of the country code"""
return self._raw_country

@property
def authmode(self):
"""String id of the authmode
derived from Nina code:
https://github.com/adafruit/nina-fw/blob/master/arduino/libraries/WiFi/src/WiFi.cpp#L385
"""
if self._raw_authmode:
response = self._raw_authmode[0]
else:
response = self._get_response(_GET_CURR_ENCT_CMD)[0]

if response == 7:
return "OPEN"
if response == 5:
return "WEP"
if response == 2:
return "PSK"
if response == 4:
return "WPA2"
return "UNKNOWN"


class ESP_SPIcontrol: # pylint: disable=too-many-public-methods, too-many-instance-attributes
"""A class that will talk to an ESP32 module programmed with special firmware
that lets it act as a fast an efficient WiFi co-processor"""
Expand Down Expand Up @@ -359,7 +448,7 @@ def firmware_version(self):
if self._debug:
print("Firmware version")
resp = self._send_command_get_response(_GET_FW_VERSION_CMD)
return resp[0]
return resp[0].decode("utf-8").replace("\x00", "")

@property
def MAC_address(self): # pylint: disable=invalid-name
Expand Down Expand Up @@ -397,16 +486,19 @@ def get_scan_networks(self):
# print("SSID names:", names)
APs = [] # pylint: disable=invalid-name
for i, name in enumerate(names):
a_p = {"ssid": name}
rssi = self._send_command_get_response(_GET_IDX_RSSI_CMD, ((i,),))[0]
a_p["rssi"] = struct.unpack("<i", rssi)[0]
encr = self._send_command_get_response(_GET_IDX_ENCT_CMD, ((i,),))[0]
a_p["encryption"] = encr[0]
bssid = self._send_command_get_response(_GET_IDX_BSSID_CMD, ((i,),))[0]
a_p["bssid"] = bssid
chan = self._send_command_get_response(_GET_IDX_CHAN_CMD, ((i,),))[0]
a_p["channel"] = chan[0]
APs.append(a_p)
rssi = self._send_command_get_response(_GET_IDX_RSSI_CMD, ((i,),))[0]
channel = self._send_command_get_response(_GET_IDX_CHAN_CMD, ((i,),))[0]
authmode = self._send_command_get_response(_GET_IDX_ENCT_CMD, ((i,),))[0]
APs.append(
Network(
raw_ssid=name,
raw_bssid=bssid,
raw_rssi=rssi,
raw_channel=channel,
raw_authmode=authmode,
)
)
return APs

def scan_networks(self):
Expand Down Expand Up @@ -512,23 +604,12 @@ def _wifi_set_ap_passphrase(self, ssid, passphrase, channel):
raise OSError("Failed to setup AP password")

@property
def ssid(self):
"""The name of the access point we're connected to"""
resp = self._send_command_get_response(_GET_CURR_SSID_CMD, [b"\xFF"])
return resp[0]

@property
def bssid(self):
"""The MAC-formatted service set ID of the access point we're connected to"""
resp = self._send_command_get_response(_GET_CURR_BSSID_CMD, [b"\xFF"])
return resp[0]

@property
def rssi(self):
"""The receiving signal strength indicator for the access point we're
connected to"""
resp = self._send_command_get_response(_GET_CURR_RSSI_CMD, [b"\xFF"])
return struct.unpack("<i", resp[0])[0]
def ap_info(self):
"""Network object containing BSSID, SSID, authmode, channel, country and RSSI when
connected to an access point. None otherwise."""
if self.is_connected:
return Network(esp_spi_control=self)
return None

@property
def network_data(self):
Expand Down Expand Up @@ -942,7 +1023,7 @@ def set_digital_read(self, pin):
:param int pin: ESP32 GPIO pin to read from.
"""
# Verify nina-fw => 1.5.0
fw_semver_maj = bytes(self.firmware_version).decode("utf-8")[2]
fw_semver_maj = self.firmware_version[2]
assert int(fw_semver_maj) >= 5, "Please update nina-fw to 1.5.0 or above."

resp = self._send_command_get_response(_SET_DIGITAL_READ_CMD, ((pin,),))[0]
Expand All @@ -961,7 +1042,7 @@ def set_analog_read(self, pin, atten=ADC_ATTEN_DB_11):
:param int atten: attenuation constant
"""
# Verify nina-fw => 1.5.0
fw_semver_maj = bytes(self.firmware_version).decode("utf-8")[2]
fw_semver_maj = self.firmware_version[2]
assert int(fw_semver_maj) >= 5, "Please update nina-fw to 1.5.0 or above."

resp = self._send_command_get_response(_SET_ANALOG_READ_CMD, ((pin,), (atten,)))
Expand Down
9 changes: 3 additions & 6 deletions adafruit_esp32spi/adafruit_esp32spi_wifimanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,7 @@ def connect(self):
print("Firmware vers.", self.esp.firmware_version)
print("MAC addr:", [hex(i) for i in self.esp.MAC_address])
for access_pt in self.esp.scan_networks():
print(
"\t%s\t\tRSSI: %d"
% (str(access_pt["ssid"], "utf-8"), access_pt["rssi"])
)
print("\t%s\t\tRSSI: %d" % (access_pt.ssid, access_pt.rssi))
if self._connection_type == ESPSPI_WiFiManager.NORMAL:
self.connect_normal()
elif self._connection_type == ESPSPI_WiFiManager.ENTERPRISE:
Expand Down Expand Up @@ -328,7 +325,7 @@ def ip_address(self):
self.connect()
self.pixel_status((0, 0, 100))
self.pixel_status(0)
return self.esp.pretty_ip(self.esp.ip_address)
return self.esp.ipv4_address

def pixel_status(self, value):
"""
Expand All @@ -349,4 +346,4 @@ def signal_strength(self):
"""
if not self.esp.is_connected:
self.connect()
return self.esp.rssi
return self.esp.ap_info.rssi
6 changes: 2 additions & 4 deletions examples/esp32spi_ipconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
except OSError as e:
print("could not connect to AP, retrying: ", e)
continue
print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi)
print("Connected to", esp.ap_info.ssid, "\tRSSI:", esp.ap_info.rssi)
ip1 = esp.ip_address

print("set ip dns")
Expand All @@ -91,9 +91,7 @@
esp.pretty_ip(info["netmask"]),
)

IP_ADDR = esp.pretty_ip(esp.ip_address)
print("ip:", IP_ADDR)
print("My IP address is", esp.pretty_ip(esp.ip_address))
print("My IP address is", esp.ipv4_address)
print("udp in addr: ", UDP_IN_ADDR, UDP_IN_PORT)

socketaddr_udp_in = pool.getaddrinfo(UDP_IN_ADDR, UDP_IN_PORT)[0][4]
Expand Down
8 changes: 4 additions & 4 deletions examples/esp32spi_simpletest.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@

if esp.status == adafruit_esp32spi.WL_IDLE_STATUS:
print("ESP32 found and in idle mode")
print("Firmware vers.", esp.firmware_version.decode("utf-8"))
print("Firmware vers.", esp.firmware_version)
print("MAC addr:", ":".join("%02X" % byte for byte in esp.MAC_address))

for ap in esp.scan_networks():
print("\t%-23s RSSI: %d" % (str(ap["ssid"], "utf-8"), ap["rssi"]))
print("\t%-23s RSSI: %d" % (ap.ssid, ap.rssi))

print("Connecting to AP...")
while not esp.is_connected:
Expand All @@ -76,8 +76,8 @@
except OSError as e:
print("could not connect to AP, retrying: ", e)
continue
print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi)
print("My IP address is", esp.pretty_ip(esp.ip_address))
print("Connected to", esp.ap_info.ssid, "\tRSSI:", esp.ap_info.rssi)
print("My IP address is", esp.ipv4_address)
print(
"IP lookup adafruit.com: %s" % esp.pretty_ip(esp.get_host_by_name("adafruit.com"))
)
Expand Down
6 changes: 3 additions & 3 deletions examples/esp32spi_simpletest_rp2040.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
print("MAC addr:", [hex(i) for i in esp.MAC_address])

for ap in esp.scan_networks():
print("\t%s\t\tRSSI: %d" % (str(ap["ssid"], "utf-8"), ap["rssi"]))
print("\t%s\t\tRSSI: %d" % (ap.ssid, ap.rssi))

print("Connecting to AP...")
while not esp.is_connected:
Expand All @@ -55,8 +55,8 @@
except OSError as e:
print("could not connect to AP, retrying: ", e)
continue
print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi)
print("My IP address is", esp.pretty_ip(esp.ip_address))
print("Connected to", esp.ap_info.ssid, "\tRSSI:", esp.ap_info.rssi)
print("My IP address is", esp.ipv4_address)
print(
"IP lookup adafruit.com: %s" % esp.pretty_ip(esp.get_host_by_name("adafruit.com"))
)
Expand Down
12 changes: 5 additions & 7 deletions examples/esp32spi_wpa2ent_simpletest.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,15 @@ def normalize(v):
if esp.status == adafruit_esp32spi.WL_IDLE_STATUS:
print("ESP32 found and in idle mode")

# Get the ESP32 fw version number, remove trailing byte off the returned bytearray
# and then convert it to a string for prettier printing and later comparison
firmware_version = "".join([chr(b) for b in esp.firmware_version[:-1]])
print("Firmware vers.", firmware_version)
# Get the ESP32 fw version number
print("Firmware vers.", esp.firmware_version)

print("MAC addr:", [hex(i) for i in esp.MAC_address])

# WPA2 Enterprise support was added in fw ver 1.3.0. Check that the ESP32
# is running at least that version, otherwise, bail out
assert (
version_compare(firmware_version, "1.3.0") >= 0
version_compare(esp.firmware_version, "1.3.0") >= 0
), "Incorrect ESP32 firmware version; >= 1.3.0 required."

# Set up the SSID you would like to connect to
Expand Down Expand Up @@ -98,8 +96,8 @@ def normalize(v):
time.sleep(2)

print("")
print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi)
print("My IP address is", esp.pretty_ip(esp.ip_address))
print("Connected to", esp.ap_info.ssid, "\tRSSI:", esp.ap_info.rssi)
print("My IP address is", esp.ipv4_address)
print(
"IP lookup adafruit.com: %s" % esp.pretty_ip(esp.get_host_by_name("adafruit.com"))
)
Expand Down
6 changes: 1 addition & 5 deletions examples/gpio/esp32spi_gpio.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,7 @@ def esp_init_pin_modes(din, dout):

esp_reset_all()

espfirmware = ""
for _ in esp.firmware_version:
if _ != 0:
espfirmware += "{:c}".format(_)
print("ESP32 Firmware:", espfirmware)
print("ESP32 Firmware:", esp.firmware_version)

print(
"ESP32 MAC: {5:02X}:{4:02X}:{3:02X}:{2:02X}:{1:02X}:{0:02X}".format(
Expand Down

0 comments on commit e7e129a

Please sign in to comment.