Thu, 02 Mar 2023 17:53:38 +0100
MicroPython
- completed the 'pico wireless' WiFi support
--- a/eric7.epj Wed Mar 01 19:54:23 2023 +0100 +++ b/eric7.epj Thu Mar 02 17:53:38 2023 +0100 @@ -1307,7 +1307,9 @@ "src/eric7/MicroPython/Devices/MCUScripts/__init__.py", "src/eric7/MicroPython/Devices/MCUScripts/circuitPy7WiFiConnect.py", "src/eric7/MicroPython/Devices/MCUScripts/esp32WiFiConnect.py", + "src/eric7/MicroPython/Devices/MCUScripts/mpyWiFiConnect.py", "src/eric7/MicroPython/Devices/MCUScripts/picowWiFiConnect.py", + "src/eric7/MicroPython/Devices/MCUScripts/pimoroniWiFiConnect.py", "src/eric7/MicroPython/Devices/MicrobitDevices.py", "src/eric7/MicroPython/Devices/PyBoardDevices.py", "src/eric7/MicroPython/Devices/RP2040Devices.py",
--- a/src/eric7/MicroPython/Devices/CircuitPythonDevices.py Wed Mar 01 19:54:23 2023 +0100 +++ b/src/eric7/MicroPython/Devices/CircuitPythonDevices.py Thu Mar 02 17:53:38 2023 +0100 @@ -932,7 +932,7 @@ r = wifi.radio if r.ipv4_address is not None: - ping = r.ping(ipaddress.IPv4Address("8.8.8.8")) + ping = r.ping(ipaddress.IPv4Address("9.9.9.9")) print(ping is not None) else: print(False)
--- a/src/eric7/MicroPython/Devices/EspDevices.py Wed Mar 01 19:54:23 2023 +0100 +++ b/src/eric7/MicroPython/Devices/EspDevices.py Thu Mar 02 17:53:38 2023 +0100 @@ -847,7 +847,7 @@ if wifi.isconnected(): s = socket.socket() try: - s.connect(socket.getaddrinfo('google.com', 80)[0][-1]) + s.connect(socket.getaddrinfo('quad9.net', 80)[0][-1]) s.close() print(True) except:
--- a/src/eric7/MicroPython/Devices/MCUScripts/circuitPy7WiFiConnect.py Wed Mar 01 19:54:23 2023 +0100 +++ b/src/eric7/MicroPython/Devices/MCUScripts/circuitPy7WiFiConnect.py Thu Mar 02 17:53:38 2023 +0100 @@ -4,6 +4,7 @@ def connectWiFi(): import wifi + print("Connecting WiFi to '{0}' ...".format(secrets["ssid"])) wifi.radio.start_station() try: wifi.radio.connect(
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/eric7/MicroPython/Devices/MCUScripts/mpyWiFiConnect.py Thu Mar 02 17:53:38 2023 +0100 @@ -0,0 +1,26 @@ +try: + import secrets + + def connectWiFi(): + import network + from time import sleep + + print("Connecting WiFi to '{0}' ...".format(secrets.WIFI_SSID)) + wifi = network.WLAN(network.STA_IF) + wifi.active(False) + wifi.active(True) + wifi.connect(secrets.WIFI_SSID, secrets.WIFI_KEY if secrets.WIFI_KEY else None) + max_wait = 140 + while max_wait: + if wifi.status() < 0 or wifi.status() >= 3: + break + max_wait -= 1 + sleep(0.1) + if wifi.isconnected(): + print("WiFi connected:", wifi.ifconfig()) + else: + print("WiFi connection failed") + + connectWiFi() +except ImportError: + print("WiFi secrets are kept in 'secrets.py', please add them there!")
--- a/src/eric7/MicroPython/Devices/MCUScripts/picowWiFiConnect.py Wed Mar 01 19:54:23 2023 +0100 +++ b/src/eric7/MicroPython/Devices/MCUScripts/picowWiFiConnect.py Thu Mar 02 17:53:38 2023 +0100 @@ -10,6 +10,7 @@ if country: rp2.country(country) + print("Connecting WiFi to '{0}' ...".format(secrets.WIFI_SSID)) wifi = network.WLAN(network.STA_IF) wifi.active(False) wifi.active(True)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/eric7/MicroPython/Devices/MCUScripts/pimoroniWiFiConnect.py Thu Mar 02 17:53:38 2023 +0100 @@ -0,0 +1,30 @@ +try: + import secrets + + def connectWiFi(): + import picowireless as pw + from time import sleep + + print("Connecting WiFi to '{0}' ...".format(secrets.WIFI_SSID)) + pw.init() + if bool(secrets.WIFI_KEY): + pw.wifi_set_passphrase(secrets.WIFI_SSID, secrets.WIFI_KEY) + else: + pw.wifi_set_network(secrets.WIFI_SSID) + + max_wait = 140 + while max_wait: + if pw.get_connection_status() == 3: + break + max_wait -= 1 + sleep(0.1) + if pw.get_connection_status() == 3: + pw.set_led(0, 64, 0) + print("WiFi connected:", '.'.join(str(i) for i in pw.get_ip_address())) + else: + pw.set_led(64, 0, 0) + print("WiFi connection failed") + + connectWiFi() +except ImportError: + print("WiFi secrets are kept in 'secrets.py', please add them there!")
--- a/src/eric7/MicroPython/Devices/RP2040Devices.py Wed Mar 01 19:54:23 2023 +0100 +++ b/src/eric7/MicroPython/Devices/RP2040Devices.py Thu Mar 02 17:53:38 2023 +0100 @@ -72,14 +72,23 @@ } # TODO: must be specific (picow, pimoroni) self.__securityTranslations = { - 0: self.tr("open", "open WiFi network"), - 1: "WEP", - 2: "WPA", - 3: "WPA2", - 4: "WPA/WPA2", - 5: "WPA2 (CCMP)", - 6: "WPA3", - 7: "WPA2/WPA3", + "picow": { + 0: self.tr("open", "open WiFi network"), + 1: "WEP", + 2: "WPA", + 3: "WPA2", + 4: "WPA/WPA2", + 5: "WPA2 (CCMP)", + 6: "WPA3", + 7: "WPA2/WPA3", + }, + "pimoroni": { + 2: "WPA", + 4: "WPA2 (CCMP)", + 5: "WEP", + 7: self.tr("open", "open WiFi network"), + 8: self.tr("automatic"), + }, } def setButtons(self): @@ -433,9 +442,13 @@ return True, 'picow' except ImportError: try: - import picowireless - picowireless.init() - return True, 'pimoroni' + import picowireless as pw + try: + if pw.get_fw_version() != '': + return True, 'pimoroni' + except RuntimeError: + picowireless.init() + return True, 'pimoroni' except ImportError: pass @@ -448,7 +461,7 @@ command, mode=self._submitMode, timeout=10000 ) if err: - if not err.startswith("Timeout "): + if not err.startswith(b"Timeout "): raise OSError(self._shortError(err)) else: return False # pimoroni firmware loaded but no pico wireless present @@ -507,7 +520,6 @@ del wifi_status """ elif self._deviceData["wifi_type"] == "pimoroni": - # TODO: not yet implemented command = """ def wifi_status(): import picowireless as pw @@ -532,7 +544,7 @@ if station['connected']: station.update({ 'ap_ssid': pw.get_current_ssid(), - 'ap_bssid': binascii.hexlify(pw.get_current_bssid(), ':'), + 'ap_bssid': ubinascii.hexlify(pw.get_current_bssid(), ':'), 'ap_rssi': pw.get_current_rssi(), 'ap_security': pw.get_current_encryption_type(), }) @@ -546,6 +558,12 @@ } if ap['active']: ap['essid'] = pw.get_current_ssid() + ap['ifconfig'] = ( + ip_str(pw.get_ip_address()), + ip_str(pw.get_subnet_mask()), + ip_str(pw.get_gateway_ip()), + '0.0.0.0' + ) print(ujson.dumps(ap)) overall = { @@ -567,18 +585,32 @@ station = json.loads(stationStr) ap = json.loads(apStr) overall = json.loads(overallStr) - try: - station["status"] = self.__statusTranslations[ - self._deviceData["wifi_type"] - ][station["status"]] - except KeyError: - station["status"] = str(station["status"]) - try: - ap["status"] = self.__statusTranslations[self._deviceData["wifi_type"]][ - ap["status"] - ] - except KeyError: - ap["status"] = str(ap["status"]) + if "status" in station: + # translate the numerical status to a string + try: + station["status"] = self.__statusTranslations[ + self._deviceData["wifi_type"] + ][station["status"]] + except KeyError: + station["status"] = str(station["status"]) + if "status" in station: + # translate the numerical status to a string + try: + ap["status"] = self.__statusTranslations[self._deviceData["wifi_type"]][ + ap["status"] + ] + except KeyError: + ap["status"] = str(ap["status"]) + if "ap_security" in station: + # translate the numerical AP security to a string + try: + station["ap_security"] = self.__securityTranslations[ + self._deviceData["wifi_type"] + ][station["ap_security"]] + except KeyError: + station["ap_security"] = self.tr("unknown ({0})").format( + station["ap_security"] + ) return station, ap, overall def connectWifi(self, ssid, password): @@ -624,8 +656,37 @@ repr(country if country else "XX"), ) elif self._deviceData["wifi_type"] == "pimoroni": - # TODO: not yet implemented - pass + command = """ +def connect_wifi(ssid, password): + import picowireless as pw + import ujson + from time import sleep + + pw.init() + if bool(password): + pw.wifi_set_passphrase(ssid, password) + else: + pw.wifi_set_network(ssid) + + max_wait = 140 + while max_wait: + if pw.get_connection_status() == 3: + break + max_wait -= 1 + sleep(0.1) + status = pw.get_connection_status() + if status == 3: + pw.set_led(0, 64, 0) + else: + pw.set_led(64, 0, 0) + print(ujson.dumps({{'connected': status == 3, 'status': status}})) + +connect_wifi({0}, {1}) +del connect_wifi +""".format( + repr(ssid), + repr(password if password else ""), + ) else: return super().connectWifi(ssid, password) @@ -672,8 +733,19 @@ del disconnect_wifi """ elif self._deviceData["wifi_type"] == "pimoroni": - # TODO: not yet implemented - pass + command = """ +def disconnect_wifi(): + import picowireless as pw + from time import sleep + + pw.disconnect() + sleep(0.1) + print(pw.get_connection_status() != 3) + pw.set_led(0, 0, 0) + +disconnect_wifi() +del disconnect_wifi +""" else: return super().disconnectWifi() @@ -728,7 +800,10 @@ repr(ssid), repr(password) if password else '""', ) - wifiConnectFile = "mpyWiFiConnect.py" + if self._deviceData["wifi_type"] == "pimoroni": + wifiConnectFile = "pimoroniWiFiConnect.py" + else: + wifiConnectFile = "mpyWiFiConnect.py" try: # write secrets file self.putData("/secrets.py", secrets.encode("utf-8")) @@ -778,7 +853,7 @@ if wifi.isconnected(): s = socket.socket() try: - s.connect(socket.getaddrinfo('google.com', 80)[0][-1]) + s.connect(socket.getaddrinfo('quad9.net', 80)[0][-1]) s.close() print(True) except: @@ -790,12 +865,25 @@ del check_internet """ elif self._deviceData["wifi_type"] == "pimoroni": - # TODO: not yet implemented - pass + command = """ +def check_internet(): + import picowireless as pw + + if pw.get_connection_status() == 3: + res = pw.ping((9, 9, 9, 9), 300) + print(res >= 0) + else: + print(False) + +check_internet() +del check_internet +""" else: return super().checkInternet() - out, err = self._interface.execute(command, mode=self._submitMode) + out, err = self._interface.execute( + command, mode=self._submitMode, timeout=10000 + ) if err: return False, err @@ -834,8 +922,27 @@ ) elif self._deviceData["wifi_type"] == "pimoroni": - # TODO: not yet implemented - pass + command = """ +def scan_networks(): + import picowireless as pw + + network_list = [] + pw.init() + pw.start_scan_networks() + networks = pw.get_scan_networks() + for n in range(networks): + network_list.append(( + pw.get_ssid_networks(n), + pw.get_bssid_networks(n), + pw.get_channel_networks(n), + pw.get_rssi_networks(n), + pw.get_enc_type_networks(n), + )) + print(network_list) + +scan_networks() +del scan_networks +""" else: return super().scanNetworks() @@ -849,12 +956,22 @@ networks = [] for network in networksList: if network[0]: - ssid = network[0].decode("utf-8") - mac = binascii.hexlify(network[1], ":").decode("utf-8") + ssid = ( + network[0].decode("utf-8") + if isinstance(network[0], bytes) + else network[0] + ) + mac = ( + binascii.hexlify(network[1], ":").decode("utf-8") + if network[1] is not None + else "" + ) channel = network[2] rssi = network[3] try: - security = self.__securityTranslations[network[4]] + security = self.__securityTranslations[ + self._deviceData["wifi_type"] + ][network[4]] except KeyError: security = self.tr("unknown ({0})").format(network[4]) networks.append((ssid, mac, channel, rssi, security)) @@ -894,8 +1011,16 @@ interface ) elif self._deviceData["wifi_type"] == "pimoroni": - # TODO: not yet implemented - pass + command = """ +def deactivate(): + import picowireless as pw + + pw.init() + print(True) + +deactivate() +del deactivate +""" else: return super().deactivateInterface(interface) @@ -955,8 +1080,29 @@ repr(country if country else "XX"), ) elif self._deviceData["wifi_type"] == "pimoroni": - # TODO: not yet implemented - pass + # AP is fixed at channel 6 + command = """ +def start_ap(ssid, password): + import picowireless as pw + + pw.init() + if bool(password): + res = pw.wifi_set_ap_passphrase(ssid, password, 6) + else: + res = pw.wifi_set_ap_network(ssid, 6) + status = pw.get_connection_status() + if status in (7, 8): + pw.set_led(0, 64, 0) + else: + pw.set_led(64, 0, 0) + print(res >= 0) + +start_ap({0}, {1}) +del start_ap +""".format( + repr(ssid), + repr(password if password else ""), + ) else: return super().startAccessPoint(ssid, security=security, password=password) @@ -975,11 +1121,8 @@ @return tuple containg a flag indicating success and an error message @rtype tuple of (bool, str) """ - if self._deviceData["wifi_type"] == "picow": + if self._deviceData["wifi_type"] in ("picow", "pimoroni"): return self.deactivateInterface("AP") - elif self._deviceData["wifi_type"] == "pimoroni": - # TODO: not yet implemented - pass else: return super().stopAccessPoint() @@ -1004,8 +1147,12 @@ del get_stations """ elif self._deviceData["wifi_type"] == "pimoroni": - # TODO: not yet implemented - pass + return ( + [], + self.tr( + "Showing connected clients is not supported for 'pico wireless'." + ), + ) else: return super().checkInternet()
--- a/src/eric7/MicroPython/WifiDialogs/WifiNetworksWindow.py Wed Mar 01 19:54:23 2023 +0100 +++ b/src/eric7/MicroPython/WifiDialogs/WifiNetworksWindow.py Thu Mar 02 17:53:38 2023 +0100 @@ -77,7 +77,10 @@ self.statusLabel.setText( self.tr("<p>Detected <b>%n</b> network(s).</p>", "", len(networks)) ) + macSeen = False for network in networks: + if network[1]: + macSeen = True itm = QTreeWidgetItem( self.networkList, [ @@ -93,6 +96,7 @@ itm.setTextAlignment(3, Qt.AlignmentFlag.AlignHCenter) itm.setTextAlignment(4, Qt.AlignmentFlag.AlignHCenter) + self.networkList.setColumnHidden(2, not macSeen) self.__resizeColumns() self.__resort()