MicroPython mpy_network

Thu, 02 Mar 2023 17:53:38 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Thu, 02 Mar 2023 17:53:38 +0100
branch
mpy_network
changeset 9836
902ec9a04ebe
parent 9835
b4b07de1b695
child 9837
b1d925ecda15

MicroPython
- completed the 'pico wireless' WiFi support

eric7.epj file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/CircuitPythonDevices.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/EspDevices.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/MCUScripts/circuitPy7WiFiConnect.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/MCUScripts/mpyWiFiConnect.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/MCUScripts/picowWiFiConnect.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/MCUScripts/pimoroniWiFiConnect.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/RP2040Devices.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/WifiDialogs/WifiNetworksWindow.py file | annotate | diff | comparison | revisions
--- 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()
 

eric ide

mercurial