src/eric7/MicroPython/Devices/RP2040Devices.py

branch
eric7
changeset 10153
ffe7432f716b
parent 10144
45a9177c8e77
child 10170
6cf1ee737d8f
--- a/src/eric7/MicroPython/Devices/RP2040Devices.py	Wed Aug 02 17:22:20 2023 +0200
+++ b/src/eric7/MicroPython/Devices/RP2040Devices.py	Thu Aug 03 17:33:07 2023 +0200
@@ -428,6 +428,9 @@
         menu.addAction(self.tr("Set Country"), self.__setCountry).setEnabled(
             self._deviceData["wifi_type"] == "picow"
         )
+        menu.addAction(self.tr("Reset Country"), self.__resetCountry).setEnabled(
+            self._deviceData["wifi_type"] == "picow"
+        )
 
     def hasWifi(self):
         """
@@ -473,6 +476,15 @@
                 return False, ""
         return ast.literal_eval(out.decode("utf-8"))
 
+    def hasWifiCountry(self):
+        """
+        Public method to check, if the device has support to set the WiFi country.
+
+        @return flag indicating the support of WiFi country
+        @rtype bool
+        """
+        return self._deviceData["wifi_type"] == "picow"
+
     def getWifiData(self):
         """
         Public method to get data related to the current WiFi status.
@@ -499,7 +511,6 @@
         'mac': ubinascii.hexlify(wifi.config('mac'), ':').decode(),
         'channel': wifi.config('channel'),
         'txpower': wifi.config('txpower'),
-        'country': rp2.country(),
     }
     print(ujson.dumps(station))
 
@@ -513,13 +524,20 @@
         'channel': wifi.config('channel'),
         'txpower': wifi.config('txpower'),
         'essid': wifi.config('essid'),
-        'country': rp2.country(),
     }
     print(ujson.dumps(ap))
 
     overall = {
         'active': station['active'] or ap['active']
     }
+    try:
+        overall['country'] = network.country()
+    except AttributeError:
+        overall['country'] = rp2.country()
+    try:
+        overall['hostname'] = network.hostname()
+    except AttributeError:
+        pass
     print(ujson.dumps(overall))
 
 wifi_status()
@@ -619,7 +637,7 @@
                 )
         return station, ap, overall
 
-    def connectWifi(self, ssid, password):
+    def connectWifi(self, ssid, password, hostname):
         """
         Public method to connect a device to a WiFi network.
 
@@ -627,13 +645,15 @@
         @type str
         @param password password needed to connect
         @type str
+        @param hostname host name of the device
+        @type str
         @return tuple containing the connection status and an error string
         @rtype tuple of (bool, str)
         """
         if self._deviceData["wifi_type"] == "picow":
             country = Preferences.getMicroPython("WifiCountry").upper()
             command = """
-def connect_wifi(ssid, password, country):
+def connect_wifi(ssid, password, hostname, country):
     import network
     import rp2
     import ujson
@@ -641,6 +661,12 @@
 
     rp2.country(country)
 
+    if hostname:
+        try:
+            network.hostname(hostname)
+        except AttributeError:
+            pass
+
     wifi = network.WLAN(network.STA_IF)
     wifi.active(False)
     wifi.active(True)
@@ -654,11 +680,12 @@
     status = wifi.status()
     print(ujson.dumps({{'connected': wifi.isconnected(), 'status': status}}))
 
-connect_wifi({0}, {1}, {2})
+connect_wifi({0}, {1}, {2}, {3})
 del connect_wifi
 """.format(
                 repr(ssid),
                 repr(password if password else ""),
+                repr(hostname),
                 repr(country if country else "XX"),
             )
         elif self._deviceData["wifi_type"] == "picowireless":
@@ -694,7 +721,7 @@
                 repr(password if password else ""),
             )
         else:
-            return super().connectWifi(ssid, password)
+            return super().connectWifi(ssid, password, hostname)
 
         with EricOverrideCursor():
             out, err = self.executeCommands(
@@ -835,7 +862,7 @@
 
         return out.strip() == b"True"
 
-    def writeCredentials(self, ssid, password):
+    def writeCredentials(self, ssid, password, hostname, country):
         """
         Public method to write the given credentials to the connected device and modify
         the start script to connect automatically.
@@ -844,6 +871,10 @@
         @type str
         @param password password needed to authenticate
         @type str
+        @param hostname host name of the device
+        @type str
+        @param country WiFi country code
+        @type str
         @return tuple containing a flag indicating success and an error message
         @rtype tuple of (bool, str)
         """
@@ -868,11 +899,14 @@
 """
 
         if self._deviceData["wifi_type"] == "picow":
-            country = Preferences.getMicroPython("WifiCountry").upper()
-            secrets = "WIFI_SSID = {0}\nWIFI_KEY = {1}\nWIFI_COUNTRY={2}".format(
+            secrets = (
+                "WIFI_SSID = {0}\nWIFI_KEY = {1}\nWIFI_COUNTRY={2}\n"
+                "WIFI_HOSTNAME = {3}\n"
+            ).format(
                 repr(ssid),
                 repr(password) if password else '""',
-                repr(country) if country else '""',
+                repr(country.upper()) if country else '""',
+                repr(hostname) if hostname else '""',
             )
             wifiConnectFile = "picowWiFiConnect.py"
         else:
@@ -883,6 +917,9 @@
             if self._deviceData["wifi_type"] == "picowireless":
                 wifiConnectFile = "pimoroniWiFiConnect.py"
             else:
+                secrets += "WIFI_HOSTNAME = {0}\n".format(
+                    repr(hostname if hostname else '""')
+                )
                 wifiConnectFile = "mpyWiFiConnect.py"
         try:
             # write secrets file
@@ -1106,7 +1143,14 @@
         else:
             return out.decode("utf-8").strip() == "True", ""
 
-    def startAccessPoint(self, ssid, security=None, password=None, ifconfig=None):
+    def startAccessPoint(
+        self,
+        ssid,
+        security=None,
+        password=None,
+        hostname=None,
+        ifconfig=None,
+    ):
         """
         Public method to start the access point interface.
 
@@ -1116,6 +1160,8 @@
         @type int (optional)
         @param password password (defaults to None)
         @type str (optional)
+        @param hostname host name of the device (defaults to None)
+        @type str (optional)
         @param ifconfig IPv4 configuration for the access point if not default
             (IPv4 address, netmask, gateway address, DNS server address)
         @type tuple of (str, str, str, str)
@@ -1131,13 +1177,19 @@
             if security:
                 security = 4  # Pico W supports just WPA/WPA2
             command = """
-def start_ap(ssid, security, password, ifconfig, country):
+def start_ap(ssid, security, password, hostname, ifconfig, country):
     import network
     import rp2
     from time import sleep
 
     rp2.country(country)
 
+    if hostname:
+        try:
+            network.hostname(hostname)
+        except AttributeError:
+            pass
+
     ap = network.WLAN(network.AP_IF)
     ap.active(True)
     if ifconfig:
@@ -1146,12 +1198,13 @@
     sleep(0.1)
     print(ap.isconnected())
 
-start_ap({0}, {1}, {2}, {3}, {4})
+start_ap({0}, {1}, {2}, {3}, {4}, {5})
 del start_ap
 """.format(
                 repr(ssid),
                 security,
                 repr(password),
+                repr(hostname),
                 ifconfig,
                 repr(country if country else "XX"),
             )
@@ -1189,7 +1242,13 @@
                 repr(password if password else ""),
             )
         else:
-            return super().startAccessPoint(ssid, security=security, password=password)
+            return super().startAccessPoint(
+                ssid,
+                security=security,
+                password=password,
+                hostname=hostname,
+                ifconfig=ifconfig,
+            )
 
         out, err = self.executeCommands(command, mode=self._submitMode, timeout=15000)
         if err:
@@ -1339,6 +1398,56 @@
 
         return out.decode("utf-8").strip() == "True", ""
 
+    @pyqtSlot()
+    def __setCountry(self):
+        """
+        Private slot to configure the country of the connected RP2040 device.
+
+        The country is the two-letter ISO 3166-1 Alpha-2 country code.
+        """
+        from ..WifiDialogs.WifiCountryDialog import WifiCountryDialog
+
+        dlg = WifiCountryDialog()
+        if dlg.exec() == QDialog.DialogCode.Accepted:
+            country, remember = dlg.getCountry()
+            if remember:
+                Preferences.setMicroPython("WifiCountry", country)
+
+            command = """
+try:
+    import network
+    network.country({0})
+except AttributeError:
+    import rp2
+    rp2.country({0})
+""".format(
+                repr(country)
+            )
+
+            out, err = self.executeCommands(command, mode=self._submitMode)
+            if err:
+                self.microPython.showError("country()", err)
+
+    @pyqtSlot()
+    def __resetCountry(self):
+        """
+        Private slot to reset the country of the connected ESP32 device.
+
+        The country is the two-letter ISO 3166-1 Alpha-2 country code. This method
+        resets it to the default code 'XX' representing the "worldwide" region.
+        """
+        command = """
+try:
+    import network
+    network.country('XX')
+except AttributeError:
+    pass
+"""
+
+        out, err = self.executeCommands(command, mode=self._submitMode)
+        if err:
+            self.microPython.showError("country()", err)
+
     ##################################################################
     ## Methods below implement Bluetooth related methods
     ##################################################################
@@ -1610,8 +1719,11 @@
         'status': nic.status(),
         'ifconfig': nic.ifconfig(),
         'mac': ubinascii.hexlify(nic.config('mac'), ':').decode(),
-        'hostname': network.hostname(),
     }}
+    try:
+        res['hostname'] = network.hostname()
+    except AttributeError:
+        res['hostname'] = ''
     print(ujson.dumps(res))
 
 ethernet_status()
@@ -1634,7 +1746,12 @@
                 self.__statusTranslations["picowiz"][ethStatus["status"]],
             )
         )
-        status.append((self.tr("Hostname"), ethStatus["hostname"]))
+        status.append(
+            (
+                self.tr("Hostname"),
+                ethStatus["hostname"] if ethStatus["hostname"] else self.tr("unknown"),
+            )
+        )
         status.append((self.tr("IPv4 Address"), ethStatus["ifconfig"][0]))
         status.append((self.tr("Netmask"), ethStatus["ifconfig"][1]))
         status.append((self.tr("Gateway"), ethStatus["ifconfig"][2]))
@@ -1643,20 +1760,29 @@
 
         return status
 
-    def connectToLan(self, config):
+    def connectToLan(self, config, hostname):
         """
         Public method to connect the connected device to the LAN.
 
         @param config configuration for the connection (either the string 'dhcp'
             for a dynamic address or a tuple of four strings with the IPv4 parameters.
         @type str or tuple of (str, str, str, str)
+        @param hostname host name of the device
+        @type str
         @return tuple containing a flag indicating success and an error message
         @rtype tuple of (bool, str)
         """
         command = """{0}
-def connect_lan(config):
+def connect_lan(config, hostname):
+    import network
     import time
 
+    if hostname:
+        try:
+            network.hostname(hostname)
+        except AttributeError:
+            pass
+
     w5x00_init()
 
     nic.active(False)
@@ -1670,10 +1796,12 @@
         time.sleep(0.1)
     print(nic.isconnected())
 
-connect_lan({1})
+connect_lan({1}, {2})
 del connect_lan, w5x00_init
 """.format(
-            WiznetUtilities.mpyWiznetInit(), "'dhcp'" if config == "dhcp" else config
+            WiznetUtilities.mpyWiznetInit(),
+            "'dhcp'" if config == "dhcp" else config,
+            repr(hostname) if hostname else "''",
         )
 
         with EricOverrideCursor():
@@ -1793,7 +1921,7 @@
 
         return self.disconnectFromLan()
 
-    def writeLanAutoConnect(self, config):
+    def writeLanAutoConnect(self, config, hostname):
         """
         Public method to generate a script and associated configuration to connect the
         device to the LAN during boot time.
@@ -1801,6 +1929,8 @@
         @param config configuration for the connection (either the string 'dhcp'
             for a dynamic address or a tuple of four strings with the IPv4 parameters.
         @type str or tuple of (str, str, str, str)
+        @param hostname host name of the device
+        @type str
         @return tuple containing a flag indicating success and an error message
         @rtype tuple of (bool, str)
         """
@@ -1825,10 +1955,13 @@
 modify_boot()
 del modify_boot
 """
-        ifconfig = "ifconfig = {0}\n".format("'dhcp'" if config == "dhcp" else config)
+        devconfig = "ifconfig = {0}\nhostname = {1}".format(
+            "'dhcp'" if config == "dhcp" else config,
+            repr(hostname) if hostname else "''",
+        )
         try:
             # write secrets file
-            self.putData("/wiznet_config.py", ifconfig.encode("utf-8"))
+            self.putData("/wiznet_config.py", devconfig.encode("utf-8"))
             # copy auto-connect file
             self.put(
                 os.path.join(
@@ -1955,36 +2088,6 @@
             res = ast.literal_eval(out.decode("utf-8"))
             return res["result"], res["error"]
 
-    ############################################################################
-    ## RP2 only methods below
-    ############################################################################
-
-    @pyqtSlot()
-    def __setCountry(self):
-        """
-        Private slot to configure the country of the connected RP2040 device.
-
-        The country is the two letter country code.
-        """
-        from ..WifiDialogs.WifiCountryDialog import WifiCountryDialog
-
-        dlg = WifiCountryDialog()
-        if dlg.exec() == QDialog.DialogCode.Accepted:
-            country, remember = dlg.getCountry()
-            if remember:
-                Preferences.setMicroPython("WifiCountry", country)
-
-            command = """
-import rp2
-rp2.country({0})
-""".format(
-                repr(country)
-            )
-
-            out, err = self.executeCommands(command, mode=self._submitMode)
-            if err:
-                self.microPython.showError("rp2.country()", err)
-
 
 def createDevice(
     microPythonWidget, deviceType, vid, pid, boardName, serialNumber  # noqa: U100

eric ide

mercurial