src/eric7/MicroPython/Devices/EspDevices.py

branch
eric7
changeset 10153
ffe7432f716b
parent 10144
45a9177c8e77
child 10170
6cf1ee737d8f
--- a/src/eric7/MicroPython/Devices/EspDevices.py	Wed Aug 02 17:22:20 2023 +0200
+++ b/src/eric7/MicroPython/Devices/EspDevices.py	Thu Aug 03 17:33:07 2023 +0200
@@ -615,6 +615,18 @@
     ## Methods below implement WiFi related methods
     ##################################################################
 
+    def addDeviceWifiEntries(self, menu):
+        """
+        Public method to add device specific entries to the given menu.
+
+        @param menu reference to the context menu
+        @type QMenu
+        """
+        if not self.hasCircuitPython():
+            menu.addSeparator()
+            menu.addAction(self.tr("Set Country"), self.__setCountry)
+            menu.addAction(self.tr("Reset Country"), self.__resetCountry)
+
     def hasWifi(self):
         """
         Public method to check the availability of WiFi.
@@ -629,6 +641,15 @@
 
         return True, "esp32"
 
+    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 True
+
     def getWifiData(self):
         """
         Public method to get data related to the current WiFi status.
@@ -682,6 +703,14 @@
     overall = {
         'active': station['active'] or ap['active']
     }
+    try:
+        overall['hostname'] = network.hostname()
+    except AttributeError:
+        pass
+    try:
+        overall['country'] = network.country()
+    except AttributeError:
+        pass
     print(ujson.dumps(overall))
 
 wifi_status()
@@ -706,7 +735,7 @@
             ap["status"] = str(ap["status"])
         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.
 
@@ -714,18 +743,26 @@
         @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.hasCircuitPython():
-            return self.__cpyDevice.connectWifi(ssid, password)
+            return self.__cpyDevice.connectWifi(ssid, password, hostname)
 
         command = """
-def connect_wifi(ssid, password):
+def connect_wifi(ssid, password, hostname):
     import network
     import ujson
     from time import sleep
 
+    if hostname:
+        try:
+            network.hostname(hostname)
+        except AttributeError:
+            pass
+
     wifi = network.WLAN(network.STA_IF)
     wifi.active(False)
     wifi.active(True)
@@ -737,11 +774,12 @@
     status = wifi.status()
     print(ujson.dumps({{'connected': wifi.isconnected(), 'status': status}}))
 
-connect_wifi({0}, {1})
+connect_wifi({0}, {1}, {2})
 del connect_wifi
 """.format(
             repr(ssid),
             repr(password if password else ""),
+            repr(hostname),
         )
 
         with EricOverrideCursor():
@@ -847,7 +885,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.
@@ -856,25 +894,34 @@
         @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)
         """
         if self.hasCircuitPython():
-            return self.__cpyDevice.writeCredentials(ssid, password)
+            return self.__cpyDevice.writeCredentials(ssid, password, hostname)
 
         nvsCommand = """
-def save_wifi_creds(ssid, password):
+def save_wifi_creds(ssid, password, hostname, country):
     import esp32
 
     nvs = esp32.NVS('wifi_creds')
     nvs.set_blob('ssid', ssid)
     nvs.set_blob('password', password)
+    nvs.set_blob('hostname', hostname)
+    nvs.set_blob('country', country)
     nvs.commit()
 
-save_wifi_creds({0}, {1})
+save_wifi_creds({0}, {1}, {2}, {3})
 del save_wifi_creds
 """.format(
-            repr(ssid), repr(password) if password else "''"
+            repr(ssid),
+            repr(password) if password else "''",
+            repr(hostname) if hostname else "''",
+            repr(country.upper()) if country else "''",
         )
         bootCommand = """
 def modify_boot():
@@ -1075,7 +1122,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.
 
@@ -1085,6 +1139,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)
@@ -1093,7 +1149,11 @@
         """
         if self.hasCircuitPython():
             return self.__cpyDevice.startAccessPoint(
-                ssid, security=security, password=password, ifconfig=ifconfig
+                ssid,
+                security=security,
+                password=password,
+                hostname=hostname,
+                ifconfig=ifconfig,
             )
 
         if security is None or password is None:
@@ -1103,9 +1163,15 @@
             security = 4  # security >4 cause an error thrown by the ESP32
 
         command = """
-def start_ap(ssid, authmode, password, ifconfig):
+def start_ap(ssid, authmode, password, hostname, ifconfig):
     import network
 
+    if hostname:
+        try:
+            network.hostname(hostname)
+        except AttributeError:
+            pass
+
     ap = network.WLAN(network.AP_IF)
     ap.active(False)
     if ifconfig:
@@ -1116,10 +1182,10 @@
     except:
         ap.config(essid=ssid, authmode=authmode, password=password)
 
-start_ap({0}, {1}, {2}, {3})
+start_ap({0}, {1}, {2}, {3}, {4})
 del start_ap
 """.format(
-            repr(ssid), security, repr(password), ifconfig
+            repr(ssid), security, repr(password), repr(hostname), ifconfig
         )
 
         out, err = self.executeCommands(command, mode=self._submitMode, timeout=15000)
@@ -1259,6 +1325,55 @@
 
         return out.decode("utf-8").strip() == "True", ""
 
+    @pyqtSlot()
+    def __setCountry(self):
+        """
+        Private slot to configure the country of the connected ESP32 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:
+    pass
+""".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
     ##################################################################

eric ide

mercurial