src/eric7/MicroPython/Devices/RP2040Devices.py

branch
mpy_network
changeset 9836
902ec9a04ebe
parent 9835
b4b07de1b695
child 9838
d6b87ef03c13
--- 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()
 

eric ide

mercurial