Merged with branch 'eric7' in order to prevent deviating too much. mpy_network

Sat, 25 Feb 2023 19:47:23 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 25 Feb 2023 19:47:23 +0100
branch
mpy_network
changeset 9802
22aeee2bf35f
parent 9800
25f388536caf (diff)
parent 9801
f2da2c1ab424 (current diff)
child 9803
2ab3de60b51c

Merged with branch 'eric7' in order to prevent deviating too much.

src/eric7/APIs/Python3/eric7.api file | annotate | diff | comparison | revisions
src/eric7/Documentation/Help/source.qch file | annotate | diff | comparison | revisions
src/eric7/Documentation/Help/source.qhp file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/DeviceBase.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/MicroPythonFileManagerWidget.py file | annotate | diff | comparison | revisions
--- a/eric7.epj	Sat Feb 25 19:43:06 2023 +0100
+++ b/eric7.epj	Sat Feb 25 19:47:23 2023 +0100
@@ -63,7 +63,7 @@
         "CopyrightMinFileSize": 0,
         "DocstringType": "eric_black",
         "EnabledCheckerCategories": "C, D, E, I, M, N, Y, W",
-        "ExcludeFiles": "*/ThirdParty/*, */coverage/*, */Ui_*.py, */Examples/*, */pycodestyle.py,*/pyflakes/checker.py,*/mccabe.py,*/eradicate.py,*/ast_unparse.py,*/piplicenses.py,*/pipdeptree.py",
+        "ExcludeFiles": "*/ThirdParty/*, */coverage/*, */Ui_*.py, */Examples/*, */pycodestyle.py,*/pyflakes/checker.py,*/mccabe.py,*/eradicate.py,*/ast_unparse.py,*/piplicenses.py,*/pipdeptree.py,*/MCUScripts/*",
         "ExcludeMessages": "C101,E203,E265,E266,E305,E402,M201,M301,M302,M303,M304,M305,M306,M307,M308,M311,M312,M313,M314,M315,M321,M701,M702,M811,M834,N802,N803,N807,N808,N821,W293,W503,Y401,Y402",
         "FixCodes": "",
         "FixIssues": false,
@@ -310,6 +310,7 @@
       "src/eric7/Debugger/StartRunDialog.ui",
       "src/eric7/Debugger/VariableDetailDialog.ui",
       "src/eric7/Debugger/VariablesFilterDialog.ui",
+      "src/eric7/EricNetwork/EricIPv4InputWidget.ui",
       "src/eric7/EricNetwork/EricSslCertificateSelectionDialog.ui",
       "src/eric7/EricNetwork/EricSslCertificatesDialog.ui",
       "src/eric7/EricNetwork/EricSslCertificatesInfoDialog.ui",
@@ -347,6 +348,12 @@
       "src/eric7/MicroPython/ShowModulesDialog.ui",
       "src/eric7/MicroPython/UF2FlashDialog.ui",
       "src/eric7/MicroPython/UnknownDevicesDialog.ui",
+      "src/eric7/MicroPython/WifiDialogs/WifiApConfigDialog.ui",
+      "src/eric7/MicroPython/WifiDialogs/WifiApStationsDialog.ui",
+      "src/eric7/MicroPython/WifiDialogs/WifiConnectionDialog.ui",
+      "src/eric7/MicroPython/WifiDialogs/WifiCountryDialog.ui",
+      "src/eric7/MicroPython/WifiDialogs/WifiNetworksWindow.ui",
+      "src/eric7/MicroPython/WifiDialogs/WifiStatusDialog.ui",
       "src/eric7/MultiProject/AddProjectDialog.ui",
       "src/eric7/MultiProject/PropertiesDialog.ui",
       "src/eric7/Network/IRC/IrcChannelEditDialog.ui",
@@ -976,7 +983,7 @@
     "OTHERTOOLSPARMS": {
       "Black": {
         "exclude": "/(\\.direnv|\\.eggs|\\.git|\\.hg|\\.mypy_cache|\\.nox|\\.tox|\\.venv|venv|\\.svn|\\.ipynb_checkpoints|_build|buck-out|build|dist|__pypackages__)/",
-        "extend-exclude": "/(\n\tExamples/\n\t| ThirdParty/\n\t| coverage/\n\t| Ui_.*\\.py\n\t| pycodestyle\\.py\n\t| pyflakes/checker\\.py\n\t| mccabe\\.py\n\t| eradicate\\.py\n\t| ast_unparse\\.py\n\t| piplicenses\\.py\n\t| pipdeptree\\.py\n)",
+        "extend-exclude": "/(\n\tExamples/\n\t| ThirdParty/\n\t| coverage/\n  | MCUScripts/\n\t| Ui_.*\\.py\n\t| pycodestyle\\.py\n\t| pyflakes/checker\\.py\n\t| mccabe\\.py\n\t| eradicate\\.py\n\t| ast_unparse\\.py\n\t| piplicenses\\.py\n\t| pipdeptree\\.py\n)",
         "force-exclude": "",
         "line-length": 88,
         "skip-magic-trailing-comma": false,
@@ -1003,6 +1010,7 @@
           "*/Examples/*",
           "*/ThirdParty/*",
           "*/coverage/*",
+          "*/MCUScripts/*",
           "*/Ui_*.py",
           "*/pycodestyle.py",
           "*/pyflakes/checker.py",
@@ -1148,6 +1156,7 @@
       "src/eric7/EricNetwork/EricFtp.py",
       "src/eric7/EricNetwork/EricGoogleMail.py",
       "src/eric7/EricNetwork/EricGoogleMailHelpers.py",
+      "src/eric7/EricNetwork/EricIPv4InputWidget.py",
       "src/eric7/EricNetwork/EricJsonClient.py",
       "src/eric7/EricNetwork/EricJsonServer.py",
       "src/eric7/EricNetwork/EricJsonStreamReader.py",
@@ -1295,6 +1304,9 @@
       "src/eric7/MicroPython/Devices/EspDialogs/EspFirmwareSelectionDialog.py",
       "src/eric7/MicroPython/Devices/EspDialogs/__init__.py",
       "src/eric7/MicroPython/Devices/GenericMicroPythonDevices.py",
+      "src/eric7/MicroPython/Devices/MCUScripts/__init__.py",
+      "src/eric7/MicroPython/Devices/MCUScripts/esp32WiFiConnect.py",
+      "src/eric7/MicroPython/Devices/MCUScripts/picowWiFiConnect.py",
       "src/eric7/MicroPython/Devices/MicrobitDevices.py",
       "src/eric7/MicroPython/Devices/PyBoardDevices.py",
       "src/eric7/MicroPython/Devices/RP2040Devices.py",
@@ -1312,6 +1324,14 @@
       "src/eric7/MicroPython/ShowModulesDialog.py",
       "src/eric7/MicroPython/UF2FlashDialog.py",
       "src/eric7/MicroPython/UnknownDevicesDialog.py",
+      "src/eric7/MicroPython/WifiDialogs/WifiApConfigDialog.py",
+      "src/eric7/MicroPython/WifiDialogs/WifiApStationsDialog.py",
+      "src/eric7/MicroPython/WifiDialogs/WifiConnectionDialog.py",
+      "src/eric7/MicroPython/WifiDialogs/WifiController.py",
+      "src/eric7/MicroPython/WifiDialogs/WifiCountryDialog.py",
+      "src/eric7/MicroPython/WifiDialogs/WifiNetworksWindow.py",
+      "src/eric7/MicroPython/WifiDialogs/WifiStatusDialog.py",
+      "src/eric7/MicroPython/WifiDialogs/__init__.py",
       "src/eric7/MicroPython/__init__.py",
       "src/eric7/MultiProject/AddProjectDialog.py",
       "src/eric7/MultiProject/MultiProject.py",
--- a/src/eric7/APIs/Python3/eric7.api	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/APIs/Python3/eric7.api	Sat Feb 25 19:47:23 2023 +0100
@@ -1124,6 +1124,15 @@
 eric7.EricNetwork.EricGoogleMailHelpers.TOKEN_FILE?7
 eric7.EricNetwork.EricGoogleMailHelpers.installGoogleAPIPackages?4()
 eric7.EricNetwork.EricGoogleMailHelpers.isClientSecretFileAvailable?4()
+eric7.EricNetwork.EricIPv4InputWidget.EricIPv4InputWidget.address?4()
+eric7.EricNetwork.EricIPv4InputWidget.EricIPv4InputWidget.addressChanged?7
+eric7.EricNetwork.EricIPv4InputWidget.EricIPv4InputWidget.clear?4()
+eric7.EricNetwork.EricIPv4InputWidget.EricIPv4InputWidget.eventFilter?4(obj, evt)
+eric7.EricNetwork.EricIPv4InputWidget.EricIPv4InputWidget.hasAcceptableInput?4()
+eric7.EricNetwork.EricIPv4InputWidget.EricIPv4InputWidget.setAddress?4(address)
+eric7.EricNetwork.EricIPv4InputWidget.EricIPv4InputWidget.setText?4(address)
+eric7.EricNetwork.EricIPv4InputWidget.EricIPv4InputWidget.text?4()
+eric7.EricNetwork.EricIPv4InputWidget.EricIPv4InputWidget?1(parent=None)
 eric7.EricNetwork.EricJsonClient.EricJsonClient.handleCall?4(method, params)
 eric7.EricNetwork.EricJsonClient.EricJsonClient.poll?4(waitMethod="")
 eric7.EricNetwork.EricJsonClient.EricJsonClient.run?4()
@@ -2590,43 +2599,55 @@
 eric7.MicroPython.Devices.DeviceBase.BaseDevice._getSetTimeCode?5()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice._shortError?5(error)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.addDeviceMenuEntries?4(menu)
+eric7.MicroPython.Devices.DeviceBase.BaseDevice.addDeviceWifiEntries?4(menu)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.canRunScript?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.canStartFileManager?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.canStartPlotter?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.canStartRepl?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.cd?4(dirname)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.checkDeviceData?4()
+eric7.MicroPython.Devices.DeviceBase.BaseDevice.checkInternet?4()
+eric7.MicroPython.Devices.DeviceBase.BaseDevice.connectWifi?4(ssid, password)
+eric7.MicroPython.Devices.DeviceBase.BaseDevice.deactivateInterface?4(interface)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.deviceName?4()
+eric7.MicroPython.Devices.DeviceBase.BaseDevice.disconnectWifi?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.downloadFirmware?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.fileSystemInfo?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.forceInterrupt?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.get?4(deviceFileName, hostFileName=None)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.getBoardInformation?4()
+eric7.MicroPython.Devices.DeviceBase.BaseDevice.getConnectedClients?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.getData?4(deviceFileName)
-eric7.MicroPython.Devices.DeviceBase.BaseDevice.getDeviceData?4()
+eric7.MicroPython.Devices.DeviceBase.BaseDevice.getDeviceData?4(key=None)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.getDeviceType?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.getDocumentationUrl?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.getDownloadMenuEntries?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.getFirmwareUrl?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.getModules?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.getTime?4()
+eric7.MicroPython.Devices.DeviceBase.BaseDevice.getWifiData?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.getWorkspace?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.handleDataFlood?4()
+eric7.MicroPython.Devices.DeviceBase.BaseDevice.hasBluetooth?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.hasCircuitPython?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.hasDocumentationUrl?4()
+eric7.MicroPython.Devices.DeviceBase.BaseDevice.hasEthernet?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.hasFirmwareUrl?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.hasFlashMenuEntry?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.hasTimeCommands?4()
+eric7.MicroPython.Devices.DeviceBase.BaseDevice.hasWifi?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.lls?4(dirname="", fullstat=False, showHidden=False)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.ls?4(dirname="")
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.mkdir?4(dirname)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.put?4(hostFileName, deviceFileName=None)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.putData?4(deviceFileName, content)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.pwd?4()
+eric7.MicroPython.Devices.DeviceBase.BaseDevice.removeCredentials?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.rm?4(filename)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.rmdir?4(dirname)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.rmrf?4(name, recursive=False, force=False)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.runScript?4(script)
+eric7.MicroPython.Devices.DeviceBase.BaseDevice.scanNetworks?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.selectDeviceDirectory?4(deviceDirectories)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.sendCommands?4(commandsList)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.setButtons?4()
@@ -2634,8 +2655,11 @@
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.setFileManager?4(on)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.setPlotter?4(on)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.setRepl?4(on)
+eric7.MicroPython.Devices.DeviceBase.BaseDevice.startAccessPoint?4(ssid, security=None, password=None, ifconfig=None)
+eric7.MicroPython.Devices.DeviceBase.BaseDevice.stopAccessPoint?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.supportsLocalFileAccess?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.syncTime?4(deviceType, hasCPy=False)
+eric7.MicroPython.Devices.DeviceBase.BaseDevice.writeCredentials?4(ssid, password)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice?1(microPythonWidget, deviceType, parent=None)
 eric7.MicroPython.Devices.EspDevices.EspDevice._getSetTimeCode?5()
 eric7.MicroPython.Devices.EspDevices.EspDevice.addDeviceMenuEntries?4(menu)
@@ -2643,13 +2667,25 @@
 eric7.MicroPython.Devices.EspDevices.EspDevice.canStartFileManager?4()
 eric7.MicroPython.Devices.EspDevices.EspDevice.canStartPlotter?4()
 eric7.MicroPython.Devices.EspDevices.EspDevice.canStartRepl?4()
+eric7.MicroPython.Devices.EspDevices.EspDevice.checkInternet?4()
+eric7.MicroPython.Devices.EspDevices.EspDevice.connectWifi?4(ssid, password)
+eric7.MicroPython.Devices.EspDevices.EspDevice.deactivateInterface?4(interface)
 eric7.MicroPython.Devices.EspDevices.EspDevice.deviceName?4()
+eric7.MicroPython.Devices.EspDevices.EspDevice.disconnectWifi?4()
 eric7.MicroPython.Devices.EspDevices.EspDevice.forceInterrupt?4()
+eric7.MicroPython.Devices.EspDevices.EspDevice.getConnectedClients?4()
 eric7.MicroPython.Devices.EspDevices.EspDevice.getDocumentationUrl?4()
 eric7.MicroPython.Devices.EspDevices.EspDevice.getFirmwareUrl?4()
+eric7.MicroPython.Devices.EspDevices.EspDevice.getWifiData?4()
 eric7.MicroPython.Devices.EspDevices.EspDevice.hasFlashMenuEntry?4()
+eric7.MicroPython.Devices.EspDevices.EspDevice.hasWifi?4()
+eric7.MicroPython.Devices.EspDevices.EspDevice.removeCredentials?4()
 eric7.MicroPython.Devices.EspDevices.EspDevice.runScript?4(script)
+eric7.MicroPython.Devices.EspDevices.EspDevice.scanNetworks?4()
 eric7.MicroPython.Devices.EspDevices.EspDevice.setButtons?4()
+eric7.MicroPython.Devices.EspDevices.EspDevice.startAccessPoint?4(ssid, security=None, password=None, ifconfig=None)
+eric7.MicroPython.Devices.EspDevices.EspDevice.stopAccessPoint?4()
+eric7.MicroPython.Devices.EspDevices.EspDevice.writeCredentials?4(ssid, password)
 eric7.MicroPython.Devices.EspDevices.EspDevice?1(microPythonWidget, deviceType, parent=None)
 eric7.MicroPython.Devices.EspDevices.createDevice?4(microPythonWidget, deviceType, vid, pid, boardName, serialNumber)
 eric7.MicroPython.Devices.EspDialogs.EspBackupRestoreFirmwareDialog.EspBackupRestoreFirmwareDialog.Chips?7
@@ -2681,6 +2717,8 @@
 eric7.MicroPython.Devices.GenericMicroPythonDevices.GenericMicroPythonDevice?1(microPythonWidget, deviceType, vid, pid, parent=None)
 eric7.MicroPython.Devices.GenericMicroPythonDevices.createDevice?4(microPythonWidget, deviceType, vid, pid, boardName, serialNumber)
 eric7.MicroPython.Devices.IgnoredBoards?7
+eric7.MicroPython.Devices.MCUScripts.esp32WiFiConnect.connectWiFi?4()
+eric7.MicroPython.Devices.MCUScripts.picowWiFiConnect.connectWiFi?4()
 eric7.MicroPython.Devices.MicrobitDevices.MicrobitDevice._getSetTimeCode?5()
 eric7.MicroPython.Devices.MicrobitDevices.MicrobitDevice.addDeviceMenuEntries?4(menu)
 eric7.MicroPython.Devices.MicrobitDevices.MicrobitDevice.canRunScript?4()
@@ -2721,17 +2759,30 @@
 eric7.MicroPython.Devices.PyBoardDevices.createDevice?4(microPythonWidget, deviceType, vid, pid, boardName, serialNumber)
 eric7.MicroPython.Devices.RP2040Devices.RP2040Device._getSetTimeCode?5()
 eric7.MicroPython.Devices.RP2040Devices.RP2040Device.addDeviceMenuEntries?4(menu)
+eric7.MicroPython.Devices.RP2040Devices.RP2040Device.addDeviceWifiEntries?4(menu)
 eric7.MicroPython.Devices.RP2040Devices.RP2040Device.canRunScript?4()
 eric7.MicroPython.Devices.RP2040Devices.RP2040Device.canStartFileManager?4()
 eric7.MicroPython.Devices.RP2040Devices.RP2040Device.canStartPlotter?4()
 eric7.MicroPython.Devices.RP2040Devices.RP2040Device.canStartRepl?4()
+eric7.MicroPython.Devices.RP2040Devices.RP2040Device.checkInternet?4()
+eric7.MicroPython.Devices.RP2040Devices.RP2040Device.connectWifi?4(ssid, password)
+eric7.MicroPython.Devices.RP2040Devices.RP2040Device.deactivateInterface?4(interface)
 eric7.MicroPython.Devices.RP2040Devices.RP2040Device.deviceName?4()
+eric7.MicroPython.Devices.RP2040Devices.RP2040Device.disconnectWifi?4()
 eric7.MicroPython.Devices.RP2040Devices.RP2040Device.forceInterrupt?4()
+eric7.MicroPython.Devices.RP2040Devices.RP2040Device.getConnectedClients?4()
 eric7.MicroPython.Devices.RP2040Devices.RP2040Device.getDocumentationUrl?4()
 eric7.MicroPython.Devices.RP2040Devices.RP2040Device.getDownloadMenuEntries?4()
+eric7.MicroPython.Devices.RP2040Devices.RP2040Device.getWifiData?4()
 eric7.MicroPython.Devices.RP2040Devices.RP2040Device.hasFlashMenuEntry?4()
+eric7.MicroPython.Devices.RP2040Devices.RP2040Device.hasWifi?4()
+eric7.MicroPython.Devices.RP2040Devices.RP2040Device.removeCredentials?4()
 eric7.MicroPython.Devices.RP2040Devices.RP2040Device.runScript?4(script)
+eric7.MicroPython.Devices.RP2040Devices.RP2040Device.scanNetworks?4()
 eric7.MicroPython.Devices.RP2040Devices.RP2040Device.setButtons?4()
+eric7.MicroPython.Devices.RP2040Devices.RP2040Device.startAccessPoint?4(ssid, security=None, password=None, ifconfig=None)
+eric7.MicroPython.Devices.RP2040Devices.RP2040Device.stopAccessPoint?4()
+eric7.MicroPython.Devices.RP2040Devices.RP2040Device.writeCredentials?4(ssid, password)
 eric7.MicroPython.Devices.RP2040Devices.RP2040Device?1(microPythonWidget, deviceType, parent=None)
 eric7.MicroPython.Devices.RP2040Devices.createDevice?4(microPythonWidget, deviceType, vid, pid, boardName, serialNumber)
 eric7.MicroPython.Devices.SupportedBoards?7
@@ -2755,12 +2806,15 @@
 eric7.MicroPython.Devices.getSupportedDevices?4()
 eric7.MicroPython.IgnoredDevicesDialog.IgnoredDevicesDialog.getDevices?4()
 eric7.MicroPython.IgnoredDevicesDialog.IgnoredDevicesDialog?1(deviceList, parent=None)
+eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.PasteModePrompt?7
+eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.TracebackMarker?7
 eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.connectToDevice?4(port)
 eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.dataReceived?7
 eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.disconnectFromDevice?4()
-eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.execute?4(commands)
+eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.execute?4(commands, *, mode="raw", timeout=0)
 eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.executeAsync?4(commandsList)
 eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.executeAsyncFinished?7
+eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.executeAsyncPaste?4(commandsList)
 eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.handlePreferencesChanged?4()
 eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.isConnected?4()
 eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.probeDevice?4()
@@ -2836,7 +2890,7 @@
 eric7.MicroPython.MicroPythonSerialPort.MicroPythonSerialPort.hasTimedOut?4()
 eric7.MicroPython.MicroPythonSerialPort.MicroPythonSerialPort.isConnected?4()
 eric7.MicroPython.MicroPythonSerialPort.MicroPythonSerialPort.openSerialLink?4(port)
-eric7.MicroPython.MicroPythonSerialPort.MicroPythonSerialPort.readUntil?4(expected=b"\n", size=None)
+eric7.MicroPython.MicroPythonSerialPort.MicroPythonSerialPort.readUntil?4(expected=b"\n", size=None, timeout=0)
 eric7.MicroPython.MicroPythonSerialPort.MicroPythonSerialPort.setTimeout?4(timeout)
 eric7.MicroPython.MicroPythonSerialPort.MicroPythonSerialPort?1(timeout=10000, parent=None)
 eric7.MicroPython.MicroPythonWidget.AnsiColorSchemes?7
@@ -2855,6 +2909,7 @@
 eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.eventFilter?4(obj, evt)
 eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.getCurrentBoard?4()
 eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.getCurrentPort?4()
+eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.getDevice?4()
 eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.getDeviceWorkspace?4()
 eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.handleDataFlood?4()
 eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.isConnected?4()
@@ -2868,6 +2923,7 @@
 eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.on_replButton_clicked?4(checked)
 eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.on_runButton_clicked?4()
 eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.setActionButtons?4(**kwargs)
+eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.showError?4(method, error)
 eric7.MicroPython.MicroPythonWidget.MicroPythonWidget?1(parent=None)
 eric7.MicroPython.ShowModulesDialog.ShowModulesDialog.getSelection?4()
 eric7.MicroPython.ShowModulesDialog.ShowModulesDialog.on_modulesList_itemChanged?4(item)
@@ -2894,6 +2950,25 @@
 eric7.MicroPython.UnknownDevicesDialog.UnknownDevicesDialog.on_reportButton_clicked?4()
 eric7.MicroPython.UnknownDevicesDialog.UnknownDevicesDialog.on_restoreButton_clicked?4()
 eric7.MicroPython.UnknownDevicesDialog.UnknownDevicesDialog?1(parent=None)
+eric7.MicroPython.WifiDialogs.WifiApConfigDialog.WifiApConfigDialog.getApConfig?4()
+eric7.MicroPython.WifiDialogs.WifiApConfigDialog.WifiApConfigDialog.on_apShowPasswordButton_clicked?4(checked)
+eric7.MicroPython.WifiDialogs.WifiApConfigDialog.WifiApConfigDialog?1(withIP, parent=None)
+eric7.MicroPython.WifiDialogs.WifiApStationsDialog.WifiApStationsDialog?1(stations, parent=None)
+eric7.MicroPython.WifiDialogs.WifiConnectionDialog.WifiConnectionDialog.getConnectionParameters?4()
+eric7.MicroPython.WifiDialogs.WifiConnectionDialog.WifiConnectionDialog.on_showPasswordButton_clicked?4(checked)
+eric7.MicroPython.WifiDialogs.WifiConnectionDialog.WifiConnectionDialog.on_ssidEdit_textChanged?4(ssid)
+eric7.MicroPython.WifiDialogs.WifiConnectionDialog.WifiConnectionDialog?1(parent=None)
+eric7.MicroPython.WifiDialogs.WifiController.WifiController.createMenu?4(menu)
+eric7.MicroPython.WifiDialogs.WifiController.WifiController?1(microPython, parent=None)
+eric7.MicroPython.WifiDialogs.WifiCountryDialog.WifiCountryDialog.getCountry?4()
+eric7.MicroPython.WifiDialogs.WifiCountryDialog.WifiCountryDialog.on_countryEdit_textChanged?4(country)
+eric7.MicroPython.WifiDialogs.WifiCountryDialog.WifiCountryDialog?1(parent=None)
+eric7.MicroPython.WifiDialogs.WifiNetworksWindow.WifiNetworksWindow.closeEvent?4(evt)
+eric7.MicroPython.WifiDialogs.WifiNetworksWindow.WifiNetworksWindow.on_intervalSpinBox_valueChanged?4(interval)
+eric7.MicroPython.WifiDialogs.WifiNetworksWindow.WifiNetworksWindow.on_periodicCheckBox_toggled?4(checked)
+eric7.MicroPython.WifiDialogs.WifiNetworksWindow.WifiNetworksWindow.scanNetworks?4()
+eric7.MicroPython.WifiDialogs.WifiNetworksWindow.WifiNetworksWindow?1(device, parent=None)
+eric7.MicroPython.WifiDialogs.WifiStatusDialog.WifiStatusDialog?1(clientStatus, apStatus, overallStatus, parent=None)
 eric7.MultiProject.AddProjectDialog.AddProjectDialog.getData?4()
 eric7.MultiProject.AddProjectDialog.AddProjectDialog.on_filenamePicker_textChanged?4(txt)
 eric7.MultiProject.AddProjectDialog.AddProjectDialog.on_nameEdit_textChanged?4(txt)
@@ -7295,6 +7370,8 @@
 eric7.Preferences.ConfigurationPages.MasterPasswordEntryDialog.MasterPasswordEntryDialog.on_newPasswordAgainEdit_textChanged?4(txt)
 eric7.Preferences.ConfigurationPages.MasterPasswordEntryDialog.MasterPasswordEntryDialog.on_newPasswordEdit_textChanged?4(txt)
 eric7.Preferences.ConfigurationPages.MasterPasswordEntryDialog.MasterPasswordEntryDialog?1(oldPasswordHash, parent=None)
+eric7.Preferences.ConfigurationPages.MicroPythonPage.MicroPythonPage.on_apShowPasswordButton_clicked?4(checked)
+eric7.Preferences.ConfigurationPages.MicroPythonPage.MicroPythonPage.on_showPasswordButton_clicked?4(checked)
 eric7.Preferences.ConfigurationPages.MicroPythonPage.MicroPythonPage.save?4()
 eric7.Preferences.ConfigurationPages.MicroPythonPage.MicroPythonPage?1(parent=None)
 eric7.Preferences.ConfigurationPages.MicroPythonPage.create?4(dlg)
--- a/src/eric7/APIs/Python3/eric7.bas	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/APIs/Python3/eric7.bas	Sat Feb 25 19:47:23 2023 +0100
@@ -240,6 +240,7 @@
 EricGoogleMail QObject
 EricGraphicsView QGraphicsView
 EricHorizontalToolBox EricTabWidget
+EricIPv4InputWidget QWidget Ui_EricIPv4InputWidget
 EricIconBar QWidget
 EricJsonReader QTcpServer
 EricJsonServer QTcpServer
@@ -1123,6 +1124,13 @@
 WebInspector QWebEngineView
 WidgetArea QMdiArea
 WidgetView QWidget
+WifiApConfigDialog QDialog Ui_WifiApConfigDialog
+WifiApStationsDialog QDialog Ui_WifiApStationsDialog
+WifiConnectionDialog QDialog Ui_WifiConnectionDialog
+WifiController QObject
+WifiCountryDialog QDialog Ui_WifiCountryDialog
+WifiNetworksWindow QWidget Ui_WifiNetworksWindow
+WifiStatusDialog QDialog Ui_WifiStatusDialog
 WizardEricPluginWizard QObject
 XMLStreamReaderBase QXmlStreamReader
 XbelImporter BookmarksImporter
Binary file src/eric7/Documentation/Help/source.qch has changed
--- a/src/eric7/Documentation/Help/source.qhp	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/Documentation/Help/source.qhp	Sat Feb 25 19:47:23 2023 +0100
@@ -126,6 +126,7 @@
             <section title="eric7.EricNetwork.EricFtp" ref="eric7.EricNetwork.EricFtp.html" />
             <section title="eric7.EricNetwork.EricGoogleMail" ref="eric7.EricNetwork.EricGoogleMail.html" />
             <section title="eric7.EricNetwork.EricGoogleMailHelpers" ref="eric7.EricNetwork.EricGoogleMailHelpers.html" />
+            <section title="eric7.EricNetwork.EricIPv4InputWidget" ref="eric7.EricNetwork.EricIPv4InputWidget.html" />
             <section title="eric7.EricNetwork.EricJsonClient" ref="eric7.EricNetwork.EricJsonClient.html" />
             <section title="eric7.EricNetwork.EricJsonServer" ref="eric7.EricNetwork.EricJsonServer.html" />
             <section title="eric7.EricNetwork.EricJsonStreamReader" ref="eric7.EricNetwork.EricJsonStreamReader.html" />
@@ -280,6 +281,10 @@
                 <section title="eric7.MicroPython.Devices.EspDialogs.EspBackupRestoreFirmwareDialog" ref="eric7.MicroPython.Devices.EspDialogs.EspBackupRestoreFirmwareDialog.html" />
                 <section title="eric7.MicroPython.Devices.EspDialogs.EspFirmwareSelectionDialog" ref="eric7.MicroPython.Devices.EspDialogs.EspFirmwareSelectionDialog.html" />
               </section>
+              <section title="eric7.MicroPython.Devices.MCUScripts" ref="index-eric7.MicroPython.Devices.MCUScripts.html">
+                <section title="eric7.MicroPython.Devices.MCUScripts.esp32WiFiConnect" ref="eric7.MicroPython.Devices.MCUScripts.esp32WiFiConnect.html" />
+                <section title="eric7.MicroPython.Devices.MCUScripts.picowWiFiConnect" ref="eric7.MicroPython.Devices.MCUScripts.picowWiFiConnect.html" />
+              </section>
               <section title="eric7.MicroPython.Devices.CircuitPythonDevices" ref="eric7.MicroPython.Devices.CircuitPythonDevices.html" />
               <section title="eric7.MicroPython.Devices.DeviceBase" ref="eric7.MicroPython.Devices.DeviceBase.html" />
               <section title="eric7.MicroPython.Devices.EspDevices" ref="eric7.MicroPython.Devices.EspDevices.html" />
@@ -290,6 +295,15 @@
               <section title="eric7.MicroPython.Devices.TeensyDevices" ref="eric7.MicroPython.Devices.TeensyDevices.html" />
               <section title="eric7.MicroPython.Devices.__init__" ref="eric7.MicroPython.Devices.__init__.html" />
             </section>
+            <section title="eric7.MicroPython.WifiDialogs" ref="index-eric7.MicroPython.WifiDialogs.html">
+              <section title="eric7.MicroPython.WifiDialogs.WifiApConfigDialog" ref="eric7.MicroPython.WifiDialogs.WifiApConfigDialog.html" />
+              <section title="eric7.MicroPython.WifiDialogs.WifiApStationsDialog" ref="eric7.MicroPython.WifiDialogs.WifiApStationsDialog.html" />
+              <section title="eric7.MicroPython.WifiDialogs.WifiConnectionDialog" ref="eric7.MicroPython.WifiDialogs.WifiConnectionDialog.html" />
+              <section title="eric7.MicroPython.WifiDialogs.WifiController" ref="eric7.MicroPython.WifiDialogs.WifiController.html" />
+              <section title="eric7.MicroPython.WifiDialogs.WifiCountryDialog" ref="eric7.MicroPython.WifiDialogs.WifiCountryDialog.html" />
+              <section title="eric7.MicroPython.WifiDialogs.WifiNetworksWindow" ref="eric7.MicroPython.WifiDialogs.WifiNetworksWindow.html" />
+              <section title="eric7.MicroPython.WifiDialogs.WifiStatusDialog" ref="eric7.MicroPython.WifiDialogs.WifiStatusDialog.html" />
+            </section>
             <section title="eric7.MicroPython.AddEditDevicesDialog" ref="eric7.MicroPython.AddEditDevicesDialog.html" />
             <section title="eric7.MicroPython.BoardDataDialog" ref="eric7.MicroPython.BoardDataDialog.html" />
             <section title="eric7.MicroPython.ConnectionSelectionDialog" ref="eric7.MicroPython.ConnectionSelectionDialog.html" />
@@ -2048,18 +2062,24 @@
       <keyword name="BaseDevice._getSetTimeCode" id="BaseDevice._getSetTimeCode" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice._getSetTimeCode" />
       <keyword name="BaseDevice._shortError" id="BaseDevice._shortError" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice._shortError" />
       <keyword name="BaseDevice.addDeviceMenuEntries" id="BaseDevice.addDeviceMenuEntries" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.addDeviceMenuEntries" />
+      <keyword name="BaseDevice.addDeviceWifiEntries" id="BaseDevice.addDeviceWifiEntries" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.addDeviceWifiEntries" />
       <keyword name="BaseDevice.canRunScript" id="BaseDevice.canRunScript" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.canRunScript" />
       <keyword name="BaseDevice.canStartFileManager" id="BaseDevice.canStartFileManager" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.canStartFileManager" />
       <keyword name="BaseDevice.canStartPlotter" id="BaseDevice.canStartPlotter" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.canStartPlotter" />
       <keyword name="BaseDevice.canStartRepl" id="BaseDevice.canStartRepl" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.canStartRepl" />
       <keyword name="BaseDevice.cd" id="BaseDevice.cd" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.cd" />
       <keyword name="BaseDevice.checkDeviceData" id="BaseDevice.checkDeviceData" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.checkDeviceData" />
+      <keyword name="BaseDevice.checkInternet" id="BaseDevice.checkInternet" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.checkInternet" />
+      <keyword name="BaseDevice.connectWifi" id="BaseDevice.connectWifi" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.connectWifi" />
+      <keyword name="BaseDevice.deactivateInterface" id="BaseDevice.deactivateInterface" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.deactivateInterface" />
       <keyword name="BaseDevice.deviceName" id="BaseDevice.deviceName" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.deviceName" />
+      <keyword name="BaseDevice.disconnectWifi" id="BaseDevice.disconnectWifi" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.disconnectWifi" />
       <keyword name="BaseDevice.downloadFirmware" id="BaseDevice.downloadFirmware" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.downloadFirmware" />
       <keyword name="BaseDevice.fileSystemInfo" id="BaseDevice.fileSystemInfo" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.fileSystemInfo" />
       <keyword name="BaseDevice.forceInterrupt" id="BaseDevice.forceInterrupt" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.forceInterrupt" />
       <keyword name="BaseDevice.get" id="BaseDevice.get" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.get" />
       <keyword name="BaseDevice.getBoardInformation" id="BaseDevice.getBoardInformation" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.getBoardInformation" />
+      <keyword name="BaseDevice.getConnectedClients" id="BaseDevice.getConnectedClients" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.getConnectedClients" />
       <keyword name="BaseDevice.getData" id="BaseDevice.getData" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.getData" />
       <keyword name="BaseDevice.getDeviceData" id="BaseDevice.getDeviceData" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.getDeviceData" />
       <keyword name="BaseDevice.getDeviceType" id="BaseDevice.getDeviceType" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.getDeviceType" />
@@ -2068,23 +2088,29 @@
       <keyword name="BaseDevice.getFirmwareUrl" id="BaseDevice.getFirmwareUrl" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.getFirmwareUrl" />
       <keyword name="BaseDevice.getModules" id="BaseDevice.getModules" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.getModules" />
       <keyword name="BaseDevice.getTime" id="BaseDevice.getTime" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.getTime" />
+      <keyword name="BaseDevice.getWifiData" id="BaseDevice.getWifiData" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.getWifiData" />
       <keyword name="BaseDevice.getWorkspace" id="BaseDevice.getWorkspace" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.getWorkspace" />
       <keyword name="BaseDevice.handleDataFlood" id="BaseDevice.handleDataFlood" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.handleDataFlood" />
+      <keyword name="BaseDevice.hasBluetooth" id="BaseDevice.hasBluetooth" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.hasBluetooth" />
       <keyword name="BaseDevice.hasCircuitPython" id="BaseDevice.hasCircuitPython" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.hasCircuitPython" />
       <keyword name="BaseDevice.hasDocumentationUrl" id="BaseDevice.hasDocumentationUrl" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.hasDocumentationUrl" />
+      <keyword name="BaseDevice.hasEthernet" id="BaseDevice.hasEthernet" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.hasEthernet" />
       <keyword name="BaseDevice.hasFirmwareUrl" id="BaseDevice.hasFirmwareUrl" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.hasFirmwareUrl" />
       <keyword name="BaseDevice.hasFlashMenuEntry" id="BaseDevice.hasFlashMenuEntry" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.hasFlashMenuEntry" />
       <keyword name="BaseDevice.hasTimeCommands" id="BaseDevice.hasTimeCommands" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.hasTimeCommands" />
+      <keyword name="BaseDevice.hasWifi" id="BaseDevice.hasWifi" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.hasWifi" />
       <keyword name="BaseDevice.lls" id="BaseDevice.lls" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.lls" />
       <keyword name="BaseDevice.ls" id="BaseDevice.ls" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.ls" />
       <keyword name="BaseDevice.mkdir" id="BaseDevice.mkdir" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.mkdir" />
       <keyword name="BaseDevice.put" id="BaseDevice.put" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.put" />
       <keyword name="BaseDevice.putData" id="BaseDevice.putData" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.putData" />
       <keyword name="BaseDevice.pwd" id="BaseDevice.pwd" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.pwd" />
+      <keyword name="BaseDevice.removeCredentials" id="BaseDevice.removeCredentials" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.removeCredentials" />
       <keyword name="BaseDevice.rm" id="BaseDevice.rm" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.rm" />
       <keyword name="BaseDevice.rmdir" id="BaseDevice.rmdir" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.rmdir" />
       <keyword name="BaseDevice.rmrf" id="BaseDevice.rmrf" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.rmrf" />
       <keyword name="BaseDevice.runScript" id="BaseDevice.runScript" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.runScript" />
+      <keyword name="BaseDevice.scanNetworks" id="BaseDevice.scanNetworks" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.scanNetworks" />
       <keyword name="BaseDevice.selectDeviceDirectory" id="BaseDevice.selectDeviceDirectory" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.selectDeviceDirectory" />
       <keyword name="BaseDevice.sendCommands" id="BaseDevice.sendCommands" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.sendCommands" />
       <keyword name="BaseDevice.setButtons" id="BaseDevice.setButtons" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.setButtons" />
@@ -2092,8 +2118,11 @@
       <keyword name="BaseDevice.setFileManager" id="BaseDevice.setFileManager" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.setFileManager" />
       <keyword name="BaseDevice.setPlotter" id="BaseDevice.setPlotter" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.setPlotter" />
       <keyword name="BaseDevice.setRepl" id="BaseDevice.setRepl" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.setRepl" />
+      <keyword name="BaseDevice.startAccessPoint" id="BaseDevice.startAccessPoint" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.startAccessPoint" />
+      <keyword name="BaseDevice.stopAccessPoint" id="BaseDevice.stopAccessPoint" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.stopAccessPoint" />
       <keyword name="BaseDevice.supportsLocalFileAccess" id="BaseDevice.supportsLocalFileAccess" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.supportsLocalFileAccess" />
       <keyword name="BaseDevice.syncTime" id="BaseDevice.syncTime" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.syncTime" />
+      <keyword name="BaseDevice.writeCredentials" id="BaseDevice.writeCredentials" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.writeCredentials" />
       <keyword name="BaseDocstringGenerator" id="BaseDocstringGenerator" ref="eric7.QScintilla.DocstringGenerator.BaseDocstringGenerator.html#BaseDocstringGenerator" />
       <keyword name="BaseDocstringGenerator (Constructor)" id="BaseDocstringGenerator (Constructor)" ref="eric7.QScintilla.DocstringGenerator.BaseDocstringGenerator.html#BaseDocstringGenerator.__init__" />
       <keyword name="BaseDocstringGenerator (Module)" id="BaseDocstringGenerator (Module)" ref="eric7.QScintilla.DocstringGenerator.BaseDocstringGenerator.html" />
@@ -5213,6 +5242,17 @@
       <keyword name="EricHorizontalToolBox.removeItem" id="EricHorizontalToolBox.removeItem" ref="eric7.EricWidgets.EricToolBox.html#EricHorizontalToolBox.removeItem" />
       <keyword name="EricHorizontalToolBox.setItemEnabled" id="EricHorizontalToolBox.setItemEnabled" ref="eric7.EricWidgets.EricToolBox.html#EricHorizontalToolBox.setItemEnabled" />
       <keyword name="EricHorizontalToolBox.setItemToolTip" id="EricHorizontalToolBox.setItemToolTip" ref="eric7.EricWidgets.EricToolBox.html#EricHorizontalToolBox.setItemToolTip" />
+      <keyword name="EricIPv4InputWidget" id="EricIPv4InputWidget" ref="eric7.EricNetwork.EricIPv4InputWidget.html#EricIPv4InputWidget" />
+      <keyword name="EricIPv4InputWidget (Constructor)" id="EricIPv4InputWidget (Constructor)" ref="eric7.EricNetwork.EricIPv4InputWidget.html#EricIPv4InputWidget.__init__" />
+      <keyword name="EricIPv4InputWidget (Module)" id="EricIPv4InputWidget (Module)" ref="eric7.EricNetwork.EricIPv4InputWidget.html" />
+      <keyword name="EricIPv4InputWidget.__clear" id="EricIPv4InputWidget.__clear" ref="eric7.EricNetwork.EricIPv4InputWidget.html#EricIPv4InputWidget.__clear" />
+      <keyword name="EricIPv4InputWidget.address" id="EricIPv4InputWidget.address" ref="eric7.EricNetwork.EricIPv4InputWidget.html#EricIPv4InputWidget.address" />
+      <keyword name="EricIPv4InputWidget.clear" id="EricIPv4InputWidget.clear" ref="eric7.EricNetwork.EricIPv4InputWidget.html#EricIPv4InputWidget.clear" />
+      <keyword name="EricIPv4InputWidget.eventFilter" id="EricIPv4InputWidget.eventFilter" ref="eric7.EricNetwork.EricIPv4InputWidget.html#EricIPv4InputWidget.eventFilter" />
+      <keyword name="EricIPv4InputWidget.hasAcceptableInput" id="EricIPv4InputWidget.hasAcceptableInput" ref="eric7.EricNetwork.EricIPv4InputWidget.html#EricIPv4InputWidget.hasAcceptableInput" />
+      <keyword name="EricIPv4InputWidget.setAddress" id="EricIPv4InputWidget.setAddress" ref="eric7.EricNetwork.EricIPv4InputWidget.html#EricIPv4InputWidget.setAddress" />
+      <keyword name="EricIPv4InputWidget.setText" id="EricIPv4InputWidget.setText" ref="eric7.EricNetwork.EricIPv4InputWidget.html#EricIPv4InputWidget.setText" />
+      <keyword name="EricIPv4InputWidget.text" id="EricIPv4InputWidget.text" ref="eric7.EricNetwork.EricIPv4InputWidget.html#EricIPv4InputWidget.text" />
       <keyword name="EricIconBar" id="EricIconBar" ref="eric7.EricWidgets.EricIconBar.html#EricIconBar" />
       <keyword name="EricIconBar (Constructor)" id="EricIconBar (Constructor)" ref="eric7.EricWidgets.EricIconBar.html#EricIconBar.__init__" />
       <keyword name="EricIconBar (Module)" id="EricIconBar (Module)" ref="eric7.EricWidgets.EricIconBar.html" />
@@ -6132,13 +6172,25 @@
       <keyword name="EspDevice.canStartFileManager" id="EspDevice.canStartFileManager" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.canStartFileManager" />
       <keyword name="EspDevice.canStartPlotter" id="EspDevice.canStartPlotter" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.canStartPlotter" />
       <keyword name="EspDevice.canStartRepl" id="EspDevice.canStartRepl" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.canStartRepl" />
+      <keyword name="EspDevice.checkInternet" id="EspDevice.checkInternet" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.checkInternet" />
+      <keyword name="EspDevice.connectWifi" id="EspDevice.connectWifi" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.connectWifi" />
+      <keyword name="EspDevice.deactivateInterface" id="EspDevice.deactivateInterface" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.deactivateInterface" />
       <keyword name="EspDevice.deviceName" id="EspDevice.deviceName" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.deviceName" />
+      <keyword name="EspDevice.disconnectWifi" id="EspDevice.disconnectWifi" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.disconnectWifi" />
       <keyword name="EspDevice.forceInterrupt" id="EspDevice.forceInterrupt" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.forceInterrupt" />
+      <keyword name="EspDevice.getConnectedClients" id="EspDevice.getConnectedClients" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.getConnectedClients" />
       <keyword name="EspDevice.getDocumentationUrl" id="EspDevice.getDocumentationUrl" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.getDocumentationUrl" />
       <keyword name="EspDevice.getFirmwareUrl" id="EspDevice.getFirmwareUrl" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.getFirmwareUrl" />
+      <keyword name="EspDevice.getWifiData" id="EspDevice.getWifiData" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.getWifiData" />
       <keyword name="EspDevice.hasFlashMenuEntry" id="EspDevice.hasFlashMenuEntry" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.hasFlashMenuEntry" />
+      <keyword name="EspDevice.hasWifi" id="EspDevice.hasWifi" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.hasWifi" />
+      <keyword name="EspDevice.removeCredentials" id="EspDevice.removeCredentials" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.removeCredentials" />
       <keyword name="EspDevice.runScript" id="EspDevice.runScript" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.runScript" />
+      <keyword name="EspDevice.scanNetworks" id="EspDevice.scanNetworks" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.scanNetworks" />
       <keyword name="EspDevice.setButtons" id="EspDevice.setButtons" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.setButtons" />
+      <keyword name="EspDevice.startAccessPoint" id="EspDevice.startAccessPoint" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.startAccessPoint" />
+      <keyword name="EspDevice.stopAccessPoint" id="EspDevice.stopAccessPoint" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.stopAccessPoint" />
+      <keyword name="EspDevice.writeCredentials" id="EspDevice.writeCredentials" ref="eric7.MicroPython.Devices.EspDevices.html#EspDevice.writeCredentials" />
       <keyword name="EspDevices (Module)" id="EspDevices (Module)" ref="eric7.MicroPython.Devices.EspDevices.html" />
       <keyword name="EspDialogs (Package)" id="EspDialogs (Package)" ref="index-eric7.MicroPython.Devices.EspDialogs.html" />
       <keyword name="EspFirmwareSelectionDialog" id="EspFirmwareSelectionDialog" ref="eric7.MicroPython.Devices.EspDialogs.EspFirmwareSelectionDialog.html#EspFirmwareSelectionDialog" />
@@ -10430,6 +10482,7 @@
       <keyword name="M520NameFinder.visit_Lambda" id="M520NameFinder.visit_Lambda" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#M520NameFinder.visit_Lambda" />
       <keyword name="M520NameFinder.visit_ListComp" id="M520NameFinder.visit_ListComp" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#M520NameFinder.visit_ListComp" />
       <keyword name="M520NameFinder.visit_comprehension" id="M520NameFinder.visit_comprehension" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#M520NameFinder.visit_comprehension" />
+      <keyword name="MCUScripts (Package)" id="MCUScripts (Package)" ref="index-eric7.MicroPython.Devices.MCUScripts.html" />
       <keyword name="MakePropertiesDialog" id="MakePropertiesDialog" ref="eric7.Project.MakePropertiesDialog.html#MakePropertiesDialog" />
       <keyword name="MakePropertiesDialog (Constructor)" id="MakePropertiesDialog (Constructor)" ref="eric7.Project.MakePropertiesDialog.html#MakePropertiesDialog.__init__" />
       <keyword name="MakePropertiesDialog (Module)" id="MakePropertiesDialog (Module)" ref="eric7.Project.MakePropertiesDialog.html" />
@@ -10564,6 +10617,10 @@
       <keyword name="MicroPythonDeviceInterface" id="MicroPythonDeviceInterface" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface" />
       <keyword name="MicroPythonDeviceInterface (Constructor)" id="MicroPythonDeviceInterface (Constructor)" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.__init__" />
       <keyword name="MicroPythonDeviceInterface (Module)" id="MicroPythonDeviceInterface (Module)" ref="eric7.MicroPython.MicroPythonDeviceInterface.html" />
+      <keyword name="MicroPythonDeviceInterface.__execute_paste" id="MicroPythonDeviceInterface.__execute_paste" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.__execute_paste" />
+      <keyword name="MicroPythonDeviceInterface.__execute_raw" id="MicroPythonDeviceInterface.__execute_raw" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.__execute_raw" />
+      <keyword name="MicroPythonDeviceInterface.__pasteOff" id="MicroPythonDeviceInterface.__pasteOff" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.__pasteOff" />
+      <keyword name="MicroPythonDeviceInterface.__pasteOn" id="MicroPythonDeviceInterface.__pasteOn" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.__pasteOn" />
       <keyword name="MicroPythonDeviceInterface.__rawOff" id="MicroPythonDeviceInterface.__rawOff" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.__rawOff" />
       <keyword name="MicroPythonDeviceInterface.__rawOn" id="MicroPythonDeviceInterface.__rawOn" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.__rawOn" />
       <keyword name="MicroPythonDeviceInterface.__readSerial" id="MicroPythonDeviceInterface.__readSerial" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.__readSerial" />
@@ -10571,6 +10628,7 @@
       <keyword name="MicroPythonDeviceInterface.disconnectFromDevice" id="MicroPythonDeviceInterface.disconnectFromDevice" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.disconnectFromDevice" />
       <keyword name="MicroPythonDeviceInterface.execute" id="MicroPythonDeviceInterface.execute" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.execute" />
       <keyword name="MicroPythonDeviceInterface.executeAsync" id="MicroPythonDeviceInterface.executeAsync" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.executeAsync" />
+      <keyword name="MicroPythonDeviceInterface.executeAsyncPaste" id="MicroPythonDeviceInterface.executeAsyncPaste" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.executeAsyncPaste" />
       <keyword name="MicroPythonDeviceInterface.handlePreferencesChanged" id="MicroPythonDeviceInterface.handlePreferencesChanged" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.handlePreferencesChanged" />
       <keyword name="MicroPythonDeviceInterface.isConnected" id="MicroPythonDeviceInterface.isConnected" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.isConnected" />
       <keyword name="MicroPythonDeviceInterface.probeDevice" id="MicroPythonDeviceInterface.probeDevice" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.probeDevice" />
@@ -10656,6 +10714,8 @@
       <keyword name="MicroPythonPage" id="MicroPythonPage" ref="eric7.Preferences.ConfigurationPages.MicroPythonPage.html#MicroPythonPage" />
       <keyword name="MicroPythonPage (Constructor)" id="MicroPythonPage (Constructor)" ref="eric7.Preferences.ConfigurationPages.MicroPythonPage.html#MicroPythonPage.__init__" />
       <keyword name="MicroPythonPage (Module)" id="MicroPythonPage (Module)" ref="eric7.Preferences.ConfigurationPages.MicroPythonPage.html" />
+      <keyword name="MicroPythonPage.on_apShowPasswordButton_clicked" id="MicroPythonPage.on_apShowPasswordButton_clicked" ref="eric7.Preferences.ConfigurationPages.MicroPythonPage.html#MicroPythonPage.on_apShowPasswordButton_clicked" />
+      <keyword name="MicroPythonPage.on_showPasswordButton_clicked" id="MicroPythonPage.on_showPasswordButton_clicked" ref="eric7.Preferences.ConfigurationPages.MicroPythonPage.html#MicroPythonPage.on_showPasswordButton_clicked" />
       <keyword name="MicroPythonPage.save" id="MicroPythonPage.save" ref="eric7.Preferences.ConfigurationPages.MicroPythonPage.html#MicroPythonPage.save" />
       <keyword name="MicroPythonProgressInfoDialog" id="MicroPythonProgressInfoDialog" ref="eric7.MicroPython.MicroPythonProgressInfoDialog.html#MicroPythonProgressInfoDialog" />
       <keyword name="MicroPythonProgressInfoDialog (Constructor)" id="MicroPythonProgressInfoDialog (Constructor)" ref="eric7.MicroPython.MicroPythonProgressInfoDialog.html#MicroPythonProgressInfoDialog.__init__" />
@@ -10703,7 +10763,6 @@
       <keyword name="MicroPythonWidget.__showDeviceTime" id="MicroPythonWidget.__showDeviceTime" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.__showDeviceTime" />
       <keyword name="MicroPythonWidget.__showDeviceVersion" id="MicroPythonWidget.__showDeviceVersion" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.__showDeviceVersion" />
       <keyword name="MicroPythonWidget.__showDocumentation" id="MicroPythonWidget.__showDocumentation" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.__showDocumentation" />
-      <keyword name="MicroPythonWidget.__showError" id="MicroPythonWidget.__showError" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.__showError" />
       <keyword name="MicroPythonWidget.__showImplementation" id="MicroPythonWidget.__showImplementation" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.__showImplementation" />
       <keyword name="MicroPythonWidget.__showLocalAndDeviceTime" id="MicroPythonWidget.__showLocalAndDeviceTime" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.__showLocalAndDeviceTime" />
       <keyword name="MicroPythonWidget.__showLocalTime" id="MicroPythonWidget.__showLocalTime" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.__showLocalTime" />
@@ -10714,6 +10773,7 @@
       <keyword name="MicroPythonWidget.eventFilter" id="MicroPythonWidget.eventFilter" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.eventFilter" />
       <keyword name="MicroPythonWidget.getCurrentBoard" id="MicroPythonWidget.getCurrentBoard" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.getCurrentBoard" />
       <keyword name="MicroPythonWidget.getCurrentPort" id="MicroPythonWidget.getCurrentPort" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.getCurrentPort" />
+      <keyword name="MicroPythonWidget.getDevice" id="MicroPythonWidget.getDevice" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.getDevice" />
       <keyword name="MicroPythonWidget.getDeviceWorkspace" id="MicroPythonWidget.getDeviceWorkspace" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.getDeviceWorkspace" />
       <keyword name="MicroPythonWidget.handleDataFlood" id="MicroPythonWidget.handleDataFlood" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.handleDataFlood" />
       <keyword name="MicroPythonWidget.isConnected" id="MicroPythonWidget.isConnected" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.isConnected" />
@@ -10727,6 +10787,7 @@
       <keyword name="MicroPythonWidget.on_replButton_clicked" id="MicroPythonWidget.on_replButton_clicked" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.on_replButton_clicked" />
       <keyword name="MicroPythonWidget.on_runButton_clicked" id="MicroPythonWidget.on_runButton_clicked" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.on_runButton_clicked" />
       <keyword name="MicroPythonWidget.setActionButtons" id="MicroPythonWidget.setActionButtons" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.setActionButtons" />
+      <keyword name="MicroPythonWidget.showError" id="MicroPythonWidget.showError" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.showError" />
       <keyword name="MicrobitDevice" id="MicrobitDevice" ref="eric7.MicroPython.Devices.MicrobitDevices.html#MicrobitDevice" />
       <keyword name="MicrobitDevice (Constructor)" id="MicrobitDevice (Constructor)" ref="eric7.MicroPython.Devices.MicrobitDevices.html#MicrobitDevice.__init__" />
       <keyword name="MicrobitDevice.__createMicrobitMenu" id="MicrobitDevice.__createMicrobitMenu" ref="eric7.MicroPython.Devices.MicrobitDevices.html#MicrobitDevice.__createMicrobitMenu" />
@@ -13652,20 +13713,34 @@
       <keyword name="RP2040Device.__createRP2040Menu" id="RP2040Device.__createRP2040Menu" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.__createRP2040Menu" />
       <keyword name="RP2040Device.__firmwareVersionResponse" id="RP2040Device.__firmwareVersionResponse" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.__firmwareVersionResponse" />
       <keyword name="RP2040Device.__flashPython" id="RP2040Device.__flashPython" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.__flashPython" />
+      <keyword name="RP2040Device.__setCountry" id="RP2040Device.__setCountry" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.__setCountry" />
       <keyword name="RP2040Device.__showFirmwareVersions" id="RP2040Device.__showFirmwareVersions" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.__showFirmwareVersions" />
       <keyword name="RP2040Device._getSetTimeCode" id="RP2040Device._getSetTimeCode" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device._getSetTimeCode" />
       <keyword name="RP2040Device.addDeviceMenuEntries" id="RP2040Device.addDeviceMenuEntries" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.addDeviceMenuEntries" />
+      <keyword name="RP2040Device.addDeviceWifiEntries" id="RP2040Device.addDeviceWifiEntries" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.addDeviceWifiEntries" />
       <keyword name="RP2040Device.canRunScript" id="RP2040Device.canRunScript" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.canRunScript" />
       <keyword name="RP2040Device.canStartFileManager" id="RP2040Device.canStartFileManager" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.canStartFileManager" />
       <keyword name="RP2040Device.canStartPlotter" id="RP2040Device.canStartPlotter" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.canStartPlotter" />
       <keyword name="RP2040Device.canStartRepl" id="RP2040Device.canStartRepl" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.canStartRepl" />
+      <keyword name="RP2040Device.checkInternet" id="RP2040Device.checkInternet" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.checkInternet" />
+      <keyword name="RP2040Device.connectWifi" id="RP2040Device.connectWifi" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.connectWifi" />
+      <keyword name="RP2040Device.deactivateInterface" id="RP2040Device.deactivateInterface" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.deactivateInterface" />
       <keyword name="RP2040Device.deviceName" id="RP2040Device.deviceName" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.deviceName" />
+      <keyword name="RP2040Device.disconnectWifi" id="RP2040Device.disconnectWifi" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.disconnectWifi" />
       <keyword name="RP2040Device.forceInterrupt" id="RP2040Device.forceInterrupt" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.forceInterrupt" />
+      <keyword name="RP2040Device.getConnectedClients" id="RP2040Device.getConnectedClients" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.getConnectedClients" />
       <keyword name="RP2040Device.getDocumentationUrl" id="RP2040Device.getDocumentationUrl" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.getDocumentationUrl" />
       <keyword name="RP2040Device.getDownloadMenuEntries" id="RP2040Device.getDownloadMenuEntries" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.getDownloadMenuEntries" />
+      <keyword name="RP2040Device.getWifiData" id="RP2040Device.getWifiData" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.getWifiData" />
       <keyword name="RP2040Device.hasFlashMenuEntry" id="RP2040Device.hasFlashMenuEntry" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.hasFlashMenuEntry" />
+      <keyword name="RP2040Device.hasWifi" id="RP2040Device.hasWifi" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.hasWifi" />
+      <keyword name="RP2040Device.removeCredentials" id="RP2040Device.removeCredentials" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.removeCredentials" />
       <keyword name="RP2040Device.runScript" id="RP2040Device.runScript" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.runScript" />
+      <keyword name="RP2040Device.scanNetworks" id="RP2040Device.scanNetworks" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.scanNetworks" />
       <keyword name="RP2040Device.setButtons" id="RP2040Device.setButtons" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.setButtons" />
+      <keyword name="RP2040Device.startAccessPoint" id="RP2040Device.startAccessPoint" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.startAccessPoint" />
+      <keyword name="RP2040Device.stopAccessPoint" id="RP2040Device.stopAccessPoint" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.stopAccessPoint" />
+      <keyword name="RP2040Device.writeCredentials" id="RP2040Device.writeCredentials" ref="eric7.MicroPython.Devices.RP2040Devices.html#RP2040Device.writeCredentials" />
       <keyword name="RP2040Devices (Module)" id="RP2040Devices (Module)" ref="eric7.MicroPython.Devices.RP2040Devices.html" />
       <keyword name="RbModule" id="RbModule" ref="eric7.Utilities.ModuleParser.html#RbModule" />
       <keyword name="RbModule (Constructor)" id="RbModule (Constructor)" ref="eric7.Utilities.ModuleParser.html#RbModule.__init__" />
@@ -18566,6 +18641,56 @@
       <keyword name="WidgetView.buildWidget" id="WidgetView.buildWidget" ref="eric7.Tools.TRPreviewer.html#WidgetView.buildWidget" />
       <keyword name="WidgetView.isValid" id="WidgetView.isValid" ref="eric7.Tools.TRPreviewer.html#WidgetView.isValid" />
       <keyword name="WidgetView.uiFileName" id="WidgetView.uiFileName" ref="eric7.Tools.TRPreviewer.html#WidgetView.uiFileName" />
+      <keyword name="WifiApConfigDialog" id="WifiApConfigDialog" ref="eric7.MicroPython.WifiDialogs.WifiApConfigDialog.html#WifiApConfigDialog" />
+      <keyword name="WifiApConfigDialog (Constructor)" id="WifiApConfigDialog (Constructor)" ref="eric7.MicroPython.WifiDialogs.WifiApConfigDialog.html#WifiApConfigDialog.__init__" />
+      <keyword name="WifiApConfigDialog (Module)" id="WifiApConfigDialog (Module)" ref="eric7.MicroPython.WifiDialogs.WifiApConfigDialog.html" />
+      <keyword name="WifiApConfigDialog.__updateOk" id="WifiApConfigDialog.__updateOk" ref="eric7.MicroPython.WifiDialogs.WifiApConfigDialog.html#WifiApConfigDialog.__updateOk" />
+      <keyword name="WifiApConfigDialog.getApConfig" id="WifiApConfigDialog.getApConfig" ref="eric7.MicroPython.WifiDialogs.WifiApConfigDialog.html#WifiApConfigDialog.getApConfig" />
+      <keyword name="WifiApConfigDialog.on_apShowPasswordButton_clicked" id="WifiApConfigDialog.on_apShowPasswordButton_clicked" ref="eric7.MicroPython.WifiDialogs.WifiApConfigDialog.html#WifiApConfigDialog.on_apShowPasswordButton_clicked" />
+      <keyword name="WifiApStationsDialog" id="WifiApStationsDialog" ref="eric7.MicroPython.WifiDialogs.WifiApStationsDialog.html#WifiApStationsDialog" />
+      <keyword name="WifiApStationsDialog (Constructor)" id="WifiApStationsDialog (Constructor)" ref="eric7.MicroPython.WifiDialogs.WifiApStationsDialog.html#WifiApStationsDialog.__init__" />
+      <keyword name="WifiApStationsDialog (Module)" id="WifiApStationsDialog (Module)" ref="eric7.MicroPython.WifiDialogs.WifiApStationsDialog.html" />
+      <keyword name="WifiConnectionDialog" id="WifiConnectionDialog" ref="eric7.MicroPython.WifiDialogs.WifiConnectionDialog.html#WifiConnectionDialog" />
+      <keyword name="WifiConnectionDialog (Constructor)" id="WifiConnectionDialog (Constructor)" ref="eric7.MicroPython.WifiDialogs.WifiConnectionDialog.html#WifiConnectionDialog.__init__" />
+      <keyword name="WifiConnectionDialog (Module)" id="WifiConnectionDialog (Module)" ref="eric7.MicroPython.WifiDialogs.WifiConnectionDialog.html" />
+      <keyword name="WifiConnectionDialog.getConnectionParameters" id="WifiConnectionDialog.getConnectionParameters" ref="eric7.MicroPython.WifiDialogs.WifiConnectionDialog.html#WifiConnectionDialog.getConnectionParameters" />
+      <keyword name="WifiConnectionDialog.on_showPasswordButton_clicked" id="WifiConnectionDialog.on_showPasswordButton_clicked" ref="eric7.MicroPython.WifiDialogs.WifiConnectionDialog.html#WifiConnectionDialog.on_showPasswordButton_clicked" />
+      <keyword name="WifiConnectionDialog.on_ssidEdit_textChanged" id="WifiConnectionDialog.on_ssidEdit_textChanged" ref="eric7.MicroPython.WifiDialogs.WifiConnectionDialog.html#WifiConnectionDialog.on_ssidEdit_textChanged" />
+      <keyword name="WifiController" id="WifiController" ref="eric7.MicroPython.WifiDialogs.WifiController.html#WifiController" />
+      <keyword name="WifiController (Constructor)" id="WifiController (Constructor)" ref="eric7.MicroPython.WifiDialogs.WifiController.html#WifiController.__init__" />
+      <keyword name="WifiController (Module)" id="WifiController (Module)" ref="eric7.MicroPython.WifiDialogs.WifiController.html" />
+      <keyword name="WifiController.__checkInternet" id="WifiController.__checkInternet" ref="eric7.MicroPython.WifiDialogs.WifiController.html#WifiController.__checkInternet" />
+      <keyword name="WifiController.__connectWifi" id="WifiController.__connectWifi" ref="eric7.MicroPython.WifiDialogs.WifiController.html#WifiController.__connectWifi" />
+      <keyword name="WifiController.__deactivateInterface" id="WifiController.__deactivateInterface" ref="eric7.MicroPython.WifiDialogs.WifiController.html#WifiController.__deactivateInterface" />
+      <keyword name="WifiController.__disconnectWifi" id="WifiController.__disconnectWifi" ref="eric7.MicroPython.WifiDialogs.WifiController.html#WifiController.__disconnectWifi" />
+      <keyword name="WifiController.__removeCredentials" id="WifiController.__removeCredentials" ref="eric7.MicroPython.WifiDialogs.WifiController.html#WifiController.__removeCredentials" />
+      <keyword name="WifiController.__scanNetwork" id="WifiController.__scanNetwork" ref="eric7.MicroPython.WifiDialogs.WifiController.html#WifiController.__scanNetwork" />
+      <keyword name="WifiController.__showConnectedClients" id="WifiController.__showConnectedClients" ref="eric7.MicroPython.WifiDialogs.WifiController.html#WifiController.__showConnectedClients" />
+      <keyword name="WifiController.__showWifiStatus" id="WifiController.__showWifiStatus" ref="eric7.MicroPython.WifiDialogs.WifiController.html#WifiController.__showWifiStatus" />
+      <keyword name="WifiController.__startAccessPoint" id="WifiController.__startAccessPoint" ref="eric7.MicroPython.WifiDialogs.WifiController.html#WifiController.__startAccessPoint" />
+      <keyword name="WifiController.__startAccessPointIP" id="WifiController.__startAccessPointIP" ref="eric7.MicroPython.WifiDialogs.WifiController.html#WifiController.__startAccessPointIP" />
+      <keyword name="WifiController.__stopAccessPoint" id="WifiController.__stopAccessPoint" ref="eric7.MicroPython.WifiDialogs.WifiController.html#WifiController.__stopAccessPoint" />
+      <keyword name="WifiController.__writeCredentials" id="WifiController.__writeCredentials" ref="eric7.MicroPython.WifiDialogs.WifiController.html#WifiController.__writeCredentials" />
+      <keyword name="WifiController.createMenu" id="WifiController.createMenu" ref="eric7.MicroPython.WifiDialogs.WifiController.html#WifiController.createMenu" />
+      <keyword name="WifiCountryDialog" id="WifiCountryDialog" ref="eric7.MicroPython.WifiDialogs.WifiCountryDialog.html#WifiCountryDialog" />
+      <keyword name="WifiCountryDialog (Constructor)" id="WifiCountryDialog (Constructor)" ref="eric7.MicroPython.WifiDialogs.WifiCountryDialog.html#WifiCountryDialog.__init__" />
+      <keyword name="WifiCountryDialog (Module)" id="WifiCountryDialog (Module)" ref="eric7.MicroPython.WifiDialogs.WifiCountryDialog.html" />
+      <keyword name="WifiCountryDialog.getCountry" id="WifiCountryDialog.getCountry" ref="eric7.MicroPython.WifiDialogs.WifiCountryDialog.html#WifiCountryDialog.getCountry" />
+      <keyword name="WifiCountryDialog.on_countryEdit_textChanged" id="WifiCountryDialog.on_countryEdit_textChanged" ref="eric7.MicroPython.WifiDialogs.WifiCountryDialog.html#WifiCountryDialog.on_countryEdit_textChanged" />
+      <keyword name="WifiDialogs (Package)" id="WifiDialogs (Package)" ref="index-eric7.MicroPython.WifiDialogs.html" />
+      <keyword name="WifiNetworksWindow" id="WifiNetworksWindow" ref="eric7.MicroPython.WifiDialogs.WifiNetworksWindow.html#WifiNetworksWindow" />
+      <keyword name="WifiNetworksWindow (Constructor)" id="WifiNetworksWindow (Constructor)" ref="eric7.MicroPython.WifiDialogs.WifiNetworksWindow.html#WifiNetworksWindow.__init__" />
+      <keyword name="WifiNetworksWindow (Module)" id="WifiNetworksWindow (Module)" ref="eric7.MicroPython.WifiDialogs.WifiNetworksWindow.html" />
+      <keyword name="WifiNetworksWindow.__resizeColumns" id="WifiNetworksWindow.__resizeColumns" ref="eric7.MicroPython.WifiDialogs.WifiNetworksWindow.html#WifiNetworksWindow.__resizeColumns" />
+      <keyword name="WifiNetworksWindow.__resort" id="WifiNetworksWindow.__resort" ref="eric7.MicroPython.WifiDialogs.WifiNetworksWindow.html#WifiNetworksWindow.__resort" />
+      <keyword name="WifiNetworksWindow.closeEvent" id="WifiNetworksWindow.closeEvent" ref="eric7.MicroPython.WifiDialogs.WifiNetworksWindow.html#WifiNetworksWindow.closeEvent" />
+      <keyword name="WifiNetworksWindow.on_intervalSpinBox_valueChanged" id="WifiNetworksWindow.on_intervalSpinBox_valueChanged" ref="eric7.MicroPython.WifiDialogs.WifiNetworksWindow.html#WifiNetworksWindow.on_intervalSpinBox_valueChanged" />
+      <keyword name="WifiNetworksWindow.on_periodicCheckBox_toggled" id="WifiNetworksWindow.on_periodicCheckBox_toggled" ref="eric7.MicroPython.WifiDialogs.WifiNetworksWindow.html#WifiNetworksWindow.on_periodicCheckBox_toggled" />
+      <keyword name="WifiNetworksWindow.scanNetworks" id="WifiNetworksWindow.scanNetworks" ref="eric7.MicroPython.WifiDialogs.WifiNetworksWindow.html#WifiNetworksWindow.scanNetworks" />
+      <keyword name="WifiStatusDialog" id="WifiStatusDialog" ref="eric7.MicroPython.WifiDialogs.WifiStatusDialog.html#WifiStatusDialog" />
+      <keyword name="WifiStatusDialog (Constructor)" id="WifiStatusDialog (Constructor)" ref="eric7.MicroPython.WifiDialogs.WifiStatusDialog.html#WifiStatusDialog.__init__" />
+      <keyword name="WifiStatusDialog (Module)" id="WifiStatusDialog (Module)" ref="eric7.MicroPython.WifiDialogs.WifiStatusDialog.html" />
+      <keyword name="WifiStatusDialog.__createHeader" id="WifiStatusDialog.__createHeader" ref="eric7.MicroPython.WifiDialogs.WifiStatusDialog.html#WifiStatusDialog.__createHeader" />
       <keyword name="WizardEricPluginWizard" id="WizardEricPluginWizard" ref="eric7.Plugins.PluginWizardEricPlugin.html#WizardEricPluginWizard" />
       <keyword name="WizardEricPluginWizard (Constructor)" id="WizardEricPluginWizard (Constructor)" ref="eric7.Plugins.PluginWizardEricPlugin.html#WizardEricPluginWizard.__init__" />
       <keyword name="WizardEricPluginWizard.__callForm" id="WizardEricPluginWizard.__callForm" ref="eric7.Plugins.PluginWizardEricPlugin.html#WizardEricPluginWizard.__callForm" />
@@ -18912,6 +19037,8 @@
       <keyword name="condaVersionStr" id="condaVersionStr" ref="eric7.CondaInterface.__init__.html#condaVersionStr" />
       <keyword name="confirmOverwrite" id="confirmOverwrite" ref="eric7.EricWidgets.EricFileSaveConfirmDialog.html#confirmOverwrite" />
       <keyword name="conflicting_deps" id="conflicting_deps" ref="eric7.PipInterface.pipdeptree.html#conflicting_deps" />
+      <keyword name="connectWiFi" id="connectWiFi" ref="eric7.MicroPython.Devices.MCUScripts.esp32WiFiConnect.html#connectWiFi" />
+      <keyword name="connectWiFi" id="connectWiFi" ref="eric7.MicroPython.Devices.MCUScripts.picowWiFiConnect.html#connectWiFi" />
       <keyword name="containsSpace" id="containsSpace" ref="eric7.WebBrowser.Tools.WebBrowserTools.html#containsSpace" />
       <keyword name="continued_indentation" id="continued_indentation" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#continued_indentation" />
       <keyword name="convertLineEnds" id="convertLineEnds" ref="eric7.Utilities.__init__.html#convertLineEnds" />
@@ -19170,6 +19297,7 @@
       <keyword name="escape_entities" id="escape_entities" ref="eric7.Utilities.__init__.html#escape_entities" />
       <keyword name="escape_uentities" id="escape_uentities" ref="eric7.Utilities.__init__.html#escape_uentities" />
       <keyword name="escapedBytesRepresentation" id="escapedBytesRepresentation" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.SecurityUtils.html#escapedBytesRepresentation" />
+      <keyword name="esp32WiFiConnect (Module)" id="esp32WiFiConnect (Module)" ref="eric7.MicroPython.Devices.MCUScripts.esp32WiFiConnect.html" />
       <keyword name="evaluateCall" id="evaluateCall" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.djangoXssVulnerability.html#evaluateCall" />
       <keyword name="evaluateVar" id="evaluateVar" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.djangoXssVulnerability.html#evaluateVar" />
       <keyword name="excepthook" id="excepthook" ref="eric7.eric7_ide.html#excepthook" />
@@ -19641,6 +19769,7 @@
       <keyword name="patchSubprocess" id="patchSubprocess" ref="eric7.DebugClients.Python.SubprocessExtension.html#patchSubprocess" />
       <keyword name="patch_circup" id="patch_circup" ref="eric7.MicroPython.Devices.CircuitPythonUpdater.CircupFunctions.html#patch_circup" />
       <keyword name="pbkdf2" id="pbkdf2" ref="eric7.Utilities.crypto.py3PBKDF2.html#pbkdf2" />
+      <keyword name="picowWiFiConnect (Module)" id="picowWiFiConnect (Module)" ref="eric7.MicroPython.Devices.MCUScripts.picowWiFiConnect.html" />
       <keyword name="pipdeptree (Module)" id="pipdeptree (Module)" ref="eric7.PipInterface.pipdeptree.html" />
       <keyword name="piplicenses (Module)" id="piplicenses (Module)" ref="eric7.PipInterface.piplicenses.html" />
       <keyword name="pixmapFileToDataUrl" id="pixmapFileToDataUrl" ref="eric7.WebBrowser.Tools.WebBrowserTools.html#pixmapFileToDataUrl" />
@@ -20013,6 +20142,7 @@
       <file>eric7.EricNetwork.EricFtp.html</file>
       <file>eric7.EricNetwork.EricGoogleMail.html</file>
       <file>eric7.EricNetwork.EricGoogleMailHelpers.html</file>
+      <file>eric7.EricNetwork.EricIPv4InputWidget.html</file>
       <file>eric7.EricNetwork.EricJsonClient.html</file>
       <file>eric7.EricNetwork.EricJsonServer.html</file>
       <file>eric7.EricNetwork.EricJsonStreamReader.html</file>
@@ -20147,6 +20277,8 @@
       <file>eric7.MicroPython.Devices.EspDialogs.EspBackupRestoreFirmwareDialog.html</file>
       <file>eric7.MicroPython.Devices.EspDialogs.EspFirmwareSelectionDialog.html</file>
       <file>eric7.MicroPython.Devices.GenericMicroPythonDevices.html</file>
+      <file>eric7.MicroPython.Devices.MCUScripts.esp32WiFiConnect.html</file>
+      <file>eric7.MicroPython.Devices.MCUScripts.picowWiFiConnect.html</file>
       <file>eric7.MicroPython.Devices.MicrobitDevices.html</file>
       <file>eric7.MicroPython.Devices.PyBoardDevices.html</file>
       <file>eric7.MicroPython.Devices.RP2040Devices.html</file>
@@ -20164,6 +20296,13 @@
       <file>eric7.MicroPython.ShowModulesDialog.html</file>
       <file>eric7.MicroPython.UF2FlashDialog.html</file>
       <file>eric7.MicroPython.UnknownDevicesDialog.html</file>
+      <file>eric7.MicroPython.WifiDialogs.WifiApConfigDialog.html</file>
+      <file>eric7.MicroPython.WifiDialogs.WifiApStationsDialog.html</file>
+      <file>eric7.MicroPython.WifiDialogs.WifiConnectionDialog.html</file>
+      <file>eric7.MicroPython.WifiDialogs.WifiController.html</file>
+      <file>eric7.MicroPython.WifiDialogs.WifiCountryDialog.html</file>
+      <file>eric7.MicroPython.WifiDialogs.WifiNetworksWindow.html</file>
+      <file>eric7.MicroPython.WifiDialogs.WifiStatusDialog.html</file>
       <file>eric7.MultiProject.AddProjectDialog.html</file>
       <file>eric7.MultiProject.MultiProject.html</file>
       <file>eric7.MultiProject.MultiProjectBrowser.html</file>
@@ -21141,7 +21280,9 @@
       <file>index-eric7.JediInterface.html</file>
       <file>index-eric7.MicroPython.Devices.CircuitPythonUpdater.html</file>
       <file>index-eric7.MicroPython.Devices.EspDialogs.html</file>
+      <file>index-eric7.MicroPython.Devices.MCUScripts.html</file>
       <file>index-eric7.MicroPython.Devices.html</file>
+      <file>index-eric7.MicroPython.WifiDialogs.html</file>
       <file>index-eric7.MicroPython.html</file>
       <file>index-eric7.MultiProject.html</file>
       <file>index-eric7.Network.IRC.html</file>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.EricNetwork.EricIPv4InputWidget.html	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,241 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.EricNetwork.EricIPv4InputWidget</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.EricNetwork.EricIPv4InputWidget</h1>
+
+<p>
+Module implementing a widget to enter an IPv4 address.
+</p>
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+
+<tr>
+<td><a href="#EricIPv4InputWidget">EricIPv4InputWidget</a></td>
+<td>Class implementing a widget to enter an IPv4 address.</td>
+</tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<hr />
+<hr />
+<a NAME="EricIPv4InputWidget" ID="EricIPv4InputWidget"></a>
+<h2>EricIPv4InputWidget</h2>
+
+<p>
+    Class implementing a widget to enter an IPv4 address.
+</p>
+<h3>Signals</h3>
+<dl>
+
+<dt>addressChanged()</dt>
+<dd>
+emitted to indicate a change of the entered IPv4 address
+</dd>
+</dl>
+<h3>Derived from</h3>
+QWidget, Ui_EricIPv4InputWidget
+<h3>Class Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Class Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#EricIPv4InputWidget.__init__">EricIPv4InputWidget</a></td>
+<td>Constructor</td>
+</tr>
+<tr>
+<td><a href="#EricIPv4InputWidget.__clear">__clear</a></td>
+<td>Private slot to handle the clear button press.</td>
+</tr>
+<tr>
+<td><a href="#EricIPv4InputWidget.address">address</a></td>
+<td>Public method to get the IPv4 address as an ipaddress.IPv4Address object.</td>
+</tr>
+<tr>
+<td><a href="#EricIPv4InputWidget.clear">clear</a></td>
+<td>Public slot to clear the input fields.</td>
+</tr>
+<tr>
+<td><a href="#EricIPv4InputWidget.eventFilter">eventFilter</a></td>
+<td>Public method to filter pressing '.' to give focus to the next input field.</td>
+</tr>
+<tr>
+<td><a href="#EricIPv4InputWidget.hasAcceptableInput">hasAcceptableInput</a></td>
+<td>Public method to check, if the input is acceptable.</td>
+</tr>
+<tr>
+<td><a href="#EricIPv4InputWidget.setAddress">setAddress</a></td>
+<td>Public method to set the IPv4 address given an ipaddress.IPv4Address object.</td>
+</tr>
+<tr>
+<td><a href="#EricIPv4InputWidget.setText">setText</a></td>
+<td>Public method to set the IPv4 address given a string.</td>
+</tr>
+<tr>
+<td><a href="#EricIPv4InputWidget.text">text</a></td>
+<td>Public method to get the IPv4 address as a string.</td>
+</tr>
+</table>
+<h3>Static Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+
+<a NAME="EricIPv4InputWidget.__init__" ID="EricIPv4InputWidget.__init__"></a>
+<h4>EricIPv4InputWidget (Constructor)</h4>
+<b>EricIPv4InputWidget</b>(<i>parent=None</i>)
+
+<p>
+        Constructor
+</p>
+<dl>
+
+<dt><i>parent</i> (QWidget (optional))</dt>
+<dd>
+reference to the parent widget (defaults to None)
+</dd>
+</dl>
+<a NAME="EricIPv4InputWidget.__clear" ID="EricIPv4InputWidget.__clear"></a>
+<h4>EricIPv4InputWidget.__clear</h4>
+<b>__clear</b>(<i></i>)
+
+<p>
+        Private slot to handle the clear button press.
+</p>
+<a NAME="EricIPv4InputWidget.address" ID="EricIPv4InputWidget.address"></a>
+<h4>EricIPv4InputWidget.address</h4>
+<b>address</b>(<i></i>)
+
+<p>
+        Public method to get the IPv4 address as an ipaddress.IPv4Address object.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+IPv4 address
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+ipaddress.IPv4Address
+</dd>
+</dl>
+<a NAME="EricIPv4InputWidget.clear" ID="EricIPv4InputWidget.clear"></a>
+<h4>EricIPv4InputWidget.clear</h4>
+<b>clear</b>(<i></i>)
+
+<p>
+        Public slot to clear the input fields.
+</p>
+<a NAME="EricIPv4InputWidget.eventFilter" ID="EricIPv4InputWidget.eventFilter"></a>
+<h4>EricIPv4InputWidget.eventFilter</h4>
+<b>eventFilter</b>(<i>obj, evt</i>)
+
+<p>
+        Public method to filter pressing '.' to give focus to the next input field.
+</p>
+<dl>
+
+<dt><i>obj</i> (QObject)</dt>
+<dd>
+reference to the object
+</dd>
+<dt><i>evt</i> (QEvent)</dt>
+<dd>
+reference to the event object
+</dd>
+</dl>
+<a NAME="EricIPv4InputWidget.hasAcceptableInput" ID="EricIPv4InputWidget.hasAcceptableInput"></a>
+<h4>EricIPv4InputWidget.hasAcceptableInput</h4>
+<b>hasAcceptableInput</b>(<i></i>)
+
+<p>
+        Public method to check, if the input is acceptable.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating acceptable input
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
+<a NAME="EricIPv4InputWidget.setAddress" ID="EricIPv4InputWidget.setAddress"></a>
+<h4>EricIPv4InputWidget.setAddress</h4>
+<b>setAddress</b>(<i>address</i>)
+
+<p>
+        Public method to set the IPv4 address given an ipaddress.IPv4Address object.
+</p>
+<dl>
+
+<dt><i>address</i> (ipaddress.IPv4Address)</dt>
+<dd>
+IPv4 address
+</dd>
+</dl>
+<a NAME="EricIPv4InputWidget.setText" ID="EricIPv4InputWidget.setText"></a>
+<h4>EricIPv4InputWidget.setText</h4>
+<b>setText</b>(<i>address</i>)
+
+<p>
+        Public method to set the IPv4 address given a string.
+</p>
+<dl>
+
+<dt><i>address</i> (str)</dt>
+<dd>
+IPv4 address
+</dd>
+</dl>
+<a NAME="EricIPv4InputWidget.text" ID="EricIPv4InputWidget.text"></a>
+<h4>EricIPv4InputWidget.text</h4>
+<b>text</b>(<i></i>)
+
+<p>
+        Public method to get the IPv4 address as a string.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+IPv4 address
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
--- a/src/eric7/Documentation/Source/eric7.MicroPython.Devices.DeviceBase.html	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/Documentation/Source/eric7.MicroPython.Devices.DeviceBase.html	Sat Feb 25 19:47:23 2023 +0100
@@ -47,19 +47,19 @@
     the time on the board and getting board related data. Supported file system
     commands are:
     <ul>
-    <li>ls: directory listing</li>
+    <li>cd: change directory</li>
+    <li>fileSystemInfo: get information about the file system
+    <li>get: get a file from the connected device</li>
+    <li>getData: read data of a file of the connected device</li>
     <li>lls: directory listing with meta data</li>
-    <li>cd: change directory</li>
-    <li>pwd: get the current directory</li>
+    <li>ls: directory listing</li>
+    <li>mkdir: create a new directory</li>
     <li>put: copy a file to the connected device</li>
     <li>putData: write data to a file of the connected device</li>
-    <li>get: get a file from the connected device</li>
-    <li>getData: read data of a file of the connected device</li>
+    <li>pwd: get the current directory</li>
     <li>rm: remove a file from the connected device</li>
+    <li>rmdir: remove an empty directory</li>
     <li>rmrf: remove a file/directory recursively (like 'rm -rf' in bash)
-    <li>mkdir: create a new directory</li>
-    <li>rmdir: remove an empty directory</li>
-    <li>fileSystemInfo: get information about the file system
     </ul>
 </p>
 <p>
@@ -70,8 +70,26 @@
         information</li>
     <li>getModules: get a list of built-in modules</li>
     <li>getTime: get the current time</li>
+    <li>showTime: show the current time of the connected device</li>
     <li>syncTime: synchronize the time of the connected device</li>
-    <li>showTime: show the current time of the connected device</li>
+    </ul>
+</p>
+<p>
+    Supported WiFi commands are:
+    <ul>
+    <li>hasWifi: check, if the board has WiFi functionality</li>
+    <li>getWifiData: get WiFi status data</li>
+    <li>connectWifi: connect to a WiFi network</li>
+    <li>disconnectWifi: disconnect from a WiFi network</li>
+    <li>writeCredentials: save the WiFi credentials to the board and create
+        functionality to auto-connect at boot time</li>
+    <li>removeCredentials: remove the saved credentials</li>
+    <li>checkInternet: check, if internet access is possible</li>
+    <li>scanNetworks: scan for available WiFi networks</li>
+    <li>deactivateInterface: deactivate a WiFi interface</li>
+    <li>startAccessPoint: start an access point</li>
+    <li>stopAccessPoint: stop the access point</li>
+    <li>getConnectedClients: get a list of connected WiFi clients</li>
     </ul>
 </p>
 <h3>Derived from</h3>
@@ -111,6 +129,10 @@
 <td>Public method to add device specific entries to the given menu.</td>
 </tr>
 <tr>
+<td><a href="#BaseDevice.addDeviceWifiEntries">addDeviceWifiEntries</a></td>
+<td>Public method to add device specific entries to the given menu.</td>
+</tr>
+<tr>
 <td><a href="#BaseDevice.canRunScript">canRunScript</a></td>
 <td>Public method to determine, if a script can be executed.</td>
 </tr>
@@ -135,10 +157,26 @@
 <td>Public method to check the validity of the device data determined during connecting the device.</td>
 </tr>
 <tr>
+<td><a href="#BaseDevice.checkInternet">checkInternet</a></td>
+<td>Public method to check, if the internet can be reached.</td>
+</tr>
+<tr>
+<td><a href="#BaseDevice.connectWifi">connectWifi</a></td>
+<td>Public method to connect a device to a WiFi network.</td>
+</tr>
+<tr>
+<td><a href="#BaseDevice.deactivateInterface">deactivateInterface</a></td>
+<td>Public method to deactivate a given WiFi interface of the connected device.</td>
+</tr>
+<tr>
 <td><a href="#BaseDevice.deviceName">deviceName</a></td>
 <td>Public method to get the name of the device.</td>
 </tr>
 <tr>
+<td><a href="#BaseDevice.disconnectWifi">disconnectWifi</a></td>
+<td>Public method to disconnect a device from the WiFi network.</td>
+</tr>
+<tr>
 <td><a href="#BaseDevice.downloadFirmware">downloadFirmware</a></td>
 <td>Public method to download the device firmware.</td>
 </tr>
@@ -159,6 +197,10 @@
 <td>Public method to get some information data of the connected board.</td>
 </tr>
 <tr>
+<td><a href="#BaseDevice.getConnectedClients">getConnectedClients</a></td>
+<td>Public method to get a list of connected clients.</td>
+</tr>
+<tr>
 <td><a href="#BaseDevice.getData">getData</a></td>
 <td>Public method to read data from the connected device.</td>
 </tr>
@@ -191,6 +233,10 @@
 <td>Public method to get the current time of the device.</td>
 </tr>
 <tr>
+<td><a href="#BaseDevice.getWifiData">getWifiData</a></td>
+<td>Public method to get data related to the current WiFi status.</td>
+</tr>
+<tr>
 <td><a href="#BaseDevice.getWorkspace">getWorkspace</a></td>
 <td>Public method to get the workspace directory.</td>
 </tr>
@@ -199,6 +245,10 @@
 <td>Public slot handling a data floof from the device.</td>
 </tr>
 <tr>
+<td><a href="#BaseDevice.hasBluetooth">hasBluetooth</a></td>
+<td>Public method to check the availability of Bluetooth.</td>
+</tr>
+<tr>
 <td><a href="#BaseDevice.hasCircuitPython">hasCircuitPython</a></td>
 <td>Public method to check, if the connected device is flashed with CircuitPython.</td>
 </tr>
@@ -207,6 +257,10 @@
 <td>Public method to check, if the device has a configured documentation URL.</td>
 </tr>
 <tr>
+<td><a href="#BaseDevice.hasEthernet">hasEthernet</a></td>
+<td>Public method to check the availability of Ethernet.</td>
+</tr>
+<tr>
 <td><a href="#BaseDevice.hasFirmwareUrl">hasFirmwareUrl</a></td>
 <td>Public method to check, if the device has a configured firmware download URL.</td>
 </tr>
@@ -219,6 +273,10 @@
 <td>Public method to check, if the device supports time commands.</td>
 </tr>
 <tr>
+<td><a href="#BaseDevice.hasWifi">hasWifi</a></td>
+<td>Public method to check the availability of WiFi.</td>
+</tr>
+<tr>
 <td><a href="#BaseDevice.lls">lls</a></td>
 <td>Public method to get a long directory listing of the connected device including meta data.</td>
 </tr>
@@ -243,6 +301,10 @@
 <td>Public method to get the current directory of the connected device.</td>
 </tr>
 <tr>
+<td><a href="#BaseDevice.removeCredentials">removeCredentials</a></td>
+<td>Public method to remove the saved credentials from the connected device.</td>
+</tr>
+<tr>
 <td><a href="#BaseDevice.rm">rm</a></td>
 <td>Public method to remove a file from the connected device.</td>
 </tr>
@@ -259,6 +321,10 @@
 <td>Public method to run the given Python script.</td>
 </tr>
 <tr>
+<td><a href="#BaseDevice.scanNetworks">scanNetworks</a></td>
+<td>Public method to scan for available WiFi networks.</td>
+</tr>
+<tr>
 <td><a href="#BaseDevice.selectDeviceDirectory">selectDeviceDirectory</a></td>
 <td>Public method to select the device directory from a list of detected ones.</td>
 </tr>
@@ -287,6 +353,14 @@
 <td>Public method to set the REPL status and dependent status.</td>
 </tr>
 <tr>
+<td><a href="#BaseDevice.startAccessPoint">startAccessPoint</a></td>
+<td>Public method to start the access point interface.</td>
+</tr>
+<tr>
+<td><a href="#BaseDevice.stopAccessPoint">stopAccessPoint</a></td>
+<td>Public method to stop the access point interface.</td>
+</tr>
+<tr>
 <td><a href="#BaseDevice.supportsLocalFileAccess">supportsLocalFileAccess</a></td>
 <td>Public method to indicate file access via a local directory.</td>
 </tr>
@@ -294,6 +368,10 @@
 <td><a href="#BaseDevice.syncTime">syncTime</a></td>
 <td>Public method to set the time of the connected device to the local computer's time.</td>
 </tr>
+<tr>
+<td><a href="#BaseDevice.writeCredentials">writeCredentials</a></td>
+<td>Public method to write the given credentials to the connected device and modify the start script to connect automatically.</td>
+</tr>
 </table>
 <h3>Static Methods</h3>
 
@@ -412,6 +490,20 @@
 reference to the context menu
 </dd>
 </dl>
+<a NAME="BaseDevice.addDeviceWifiEntries" ID="BaseDevice.addDeviceWifiEntries"></a>
+<h4>BaseDevice.addDeviceWifiEntries</h4>
+<b>addDeviceWifiEntries</b>(<i>menu</i>)
+
+<p>
+        Public method to add device specific entries to the given menu.
+</p>
+<dl>
+
+<dt><i>menu</i> (QMenu)</dt>
+<dd>
+reference to the context menu
+</dd>
+</dl>
 <a NAME="BaseDevice.canRunScript" ID="BaseDevice.canRunScript"></a>
 <h4>BaseDevice.canRunScript</h4>
 <b>canRunScript</b>(<i></i>)
@@ -533,6 +625,82 @@
 bool
 </dd>
 </dl>
+<a NAME="BaseDevice.checkInternet" ID="BaseDevice.checkInternet"></a>
+<h4>BaseDevice.checkInternet</h4>
+<b>checkInternet</b>(<i></i>)
+
+<p>
+        Public method to check, if the internet can be reached.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating reachability and an error string
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
+<a NAME="BaseDevice.connectWifi" ID="BaseDevice.connectWifi"></a>
+<h4>BaseDevice.connectWifi</h4>
+<b>connectWifi</b>(<i>ssid, password</i>)
+
+<p>
+        Public method to connect a device to a WiFi network.
+</p>
+<dl>
+
+<dt><i>ssid</i> (str)</dt>
+<dd>
+name (SSID) of the WiFi network
+</dd>
+<dt><i>password</i> (str)</dt>
+<dd>
+password needed to connect
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing the connection status and an error string
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
+<a NAME="BaseDevice.deactivateInterface" ID="BaseDevice.deactivateInterface"></a>
+<h4>BaseDevice.deactivateInterface</h4>
+<b>deactivateInterface</b>(<i>interface</i>)
+
+<p>
+        Public method to deactivate a given WiFi interface of the connected device.
+</p>
+<dl>
+
+<dt><i>interface</i> (str)</dt>
+<dd>
+designation of the interface to be deactivated (one of 'AP'
+            or 'STA')
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containg a flag indicating success and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
 <a NAME="BaseDevice.deviceName" ID="BaseDevice.deviceName"></a>
 <h4>BaseDevice.deviceName</h4>
 <b>deviceName</b>(<i></i>)
@@ -552,6 +720,25 @@
 str
 </dd>
 </dl>
+<a NAME="BaseDevice.disconnectWifi" ID="BaseDevice.disconnectWifi"></a>
+<h4>BaseDevice.disconnectWifi</h4>
+<b>disconnectWifi</b>(<i></i>)
+
+<p>
+        Public method to disconnect a device from the WiFi network.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating success and an error string
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
 <a NAME="BaseDevice.downloadFirmware" ID="BaseDevice.downloadFirmware"></a>
 <h4>BaseDevice.downloadFirmware</h4>
 <b>downloadFirmware</b>(<i></i>)
@@ -670,6 +857,26 @@
 raised to indicate an issue with the device
 </dd>
 </dl>
+<a NAME="BaseDevice.getConnectedClients" ID="BaseDevice.getConnectedClients"></a>
+<h4>BaseDevice.getConnectedClients</h4>
+<b>getConnectedClients</b>(<i></i>)
+
+<p>
+        Public method to get a list of connected clients.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+a tuple containing a list of tuples containing the client MAC-Address
+            and the RSSI (if supported and available) and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of ([(bytes, int)], str)
+</dd>
+</dl>
 <a NAME="BaseDevice.getData" ID="BaseDevice.getData"></a>
 <h4>BaseDevice.getData</h4>
 <b>getData</b>(<i>deviceFileName</i>)
@@ -705,12 +912,19 @@
 </dl>
 <a NAME="BaseDevice.getDeviceData" ID="BaseDevice.getDeviceData"></a>
 <h4>BaseDevice.getDeviceData</h4>
-<b>getDeviceData</b>(<i></i>)
+<b>getDeviceData</b>(<i>key=None</i>)
 
 <p>
         Public method to get a copy of the determined device data.
 </p>
 <dl>
+
+<dt><i>key</i> (str (optional))</dt>
+<dd>
+name of the data to get (None to get all data) (defaults to None)
+</dd>
+</dl>
+<dl>
 <dt>Return:</dt>
 <dd>
 dictionary containing the essential device data
@@ -851,6 +1065,26 @@
 raised to indicate an issue with the device
 </dd>
 </dl>
+<a NAME="BaseDevice.getWifiData" ID="BaseDevice.getWifiData"></a>
+<h4>BaseDevice.getWifiData</h4>
+<b>getWifiData</b>(<i></i>)
+
+<p>
+        Public method to get data related to the current WiFi status.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple of three dictionaries containing the WiFi status data
+            for the WiFi client, access point and overall data
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (dict, dict, dict)
+</dd>
+</dl>
 <a NAME="BaseDevice.getWorkspace" ID="BaseDevice.getWorkspace"></a>
 <h4>BaseDevice.getWorkspace</h4>
 <b>getWorkspace</b>(<i></i>)
@@ -877,6 +1111,25 @@
 <p>
         Public slot handling a data floof from the device.
 </p>
+<a NAME="BaseDevice.hasBluetooth" ID="BaseDevice.hasBluetooth"></a>
+<h4>BaseDevice.hasBluetooth</h4>
+<b>hasBluetooth</b>(<i></i>)
+
+<p>
+        Public method to check the availability of Bluetooth.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating the availability of Bluetooth
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
 <a NAME="BaseDevice.hasCircuitPython" ID="BaseDevice.hasCircuitPython"></a>
 <h4>BaseDevice.hasCircuitPython</h4>
 <b>hasCircuitPython</b>(<i></i>)
@@ -916,6 +1169,25 @@
 bool
 </dd>
 </dl>
+<a NAME="BaseDevice.hasEthernet" ID="BaseDevice.hasEthernet"></a>
+<h4>BaseDevice.hasEthernet</h4>
+<b>hasEthernet</b>(<i></i>)
+
+<p>
+        Public method to check the availability of Ethernet.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating the availability of Ethernet
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
 <a NAME="BaseDevice.hasFirmwareUrl" ID="BaseDevice.hasFirmwareUrl"></a>
 <h4>BaseDevice.hasFirmwareUrl</h4>
 <b>hasFirmwareUrl</b>(<i></i>)
@@ -977,6 +1249,26 @@
 bool
 </dd>
 </dl>
+<a NAME="BaseDevice.hasWifi" ID="BaseDevice.hasWifi"></a>
+<h4>BaseDevice.hasWifi</h4>
+<b>hasWifi</b>(<i></i>)
+
+<p>
+        Public method to check the availability of WiFi.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating the availability of WiFi
+            and the WiFi type (picow or pimoroni)
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
 <a NAME="BaseDevice.lls" ID="BaseDevice.lls"></a>
 <h4>BaseDevice.lls</h4>
 <b>lls</b>(<i>dirname="", fullstat=False, showHidden=False</i>)
@@ -1176,6 +1468,25 @@
 raised to indicate an issue with the device
 </dd>
 </dl>
+<a NAME="BaseDevice.removeCredentials" ID="BaseDevice.removeCredentials"></a>
+<h4>BaseDevice.removeCredentials</h4>
+<b>removeCredentials</b>(<i></i>)
+
+<p>
+        Public method to remove the saved credentials from the connected device.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating success and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
 <a NAME="BaseDevice.rm" ID="BaseDevice.rm"></a>
 <h4>BaseDevice.rm</h4>
 <b>rm</b>(<i>filename</i>)
@@ -1273,6 +1584,26 @@
 script to be executed
 </dd>
 </dl>
+<a NAME="BaseDevice.scanNetworks" ID="BaseDevice.scanNetworks"></a>
+<h4>BaseDevice.scanNetworks</h4>
+<b>scanNetworks</b>(<i></i>)
+
+<p>
+        Public method to scan for available WiFi networks.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing the list of available networks as a tuple of 'Name',
+            'MAC-Address', 'channel', 'RSSI' and 'security' and an error string
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (list of tuple of (str, str, int, int, str), str)
+</dd>
+</dl>
 <a NAME="BaseDevice.selectDeviceDirectory" ID="BaseDevice.selectDeviceDirectory"></a>
 <h4>BaseDevice.selectDeviceDirectory</h4>
 <b>selectDeviceDirectory</b>(<i>deviceDirectories</i>)
@@ -1381,6 +1712,64 @@
 flag indicating the active status
 </dd>
 </dl>
+<a NAME="BaseDevice.startAccessPoint" ID="BaseDevice.startAccessPoint"></a>
+<h4>BaseDevice.startAccessPoint</h4>
+<b>startAccessPoint</b>(<i>ssid, security=None, password=None, ifconfig=None</i>)
+
+<p>
+        Public method to start the access point interface.
+</p>
+<dl>
+
+<dt><i>ssid</i> (str)</dt>
+<dd>
+SSID of the access point
+</dd>
+<dt><i>security</i> (int (optional))</dt>
+<dd>
+security method (defaults to None)
+</dd>
+<dt><i>password</i> (str (optional))</dt>
+<dd>
+password (defaults to None)
+</dd>
+<dt><i>ifconfig</i> (tuple of (str, str, str, str))</dt>
+<dd>
+IPv4 configuration for the access point if not default
+            (IPv4 address, netmask, gateway address, DNS server address)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating success and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
+<a NAME="BaseDevice.stopAccessPoint" ID="BaseDevice.stopAccessPoint"></a>
+<h4>BaseDevice.stopAccessPoint</h4>
+<b>stopAccessPoint</b>(<i></i>)
+
+<p>
+        Public method to stop the access point interface.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containg a flag indicating success and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
 <a NAME="BaseDevice.supportsLocalFileAccess" ID="BaseDevice.supportsLocalFileAccess"></a>
 <h4>BaseDevice.supportsLocalFileAccess</h4>
 <b>supportsLocalFileAccess</b>(<i></i>)
@@ -1427,6 +1816,37 @@
 raised to indicate an issue with the device
 </dd>
 </dl>
+<a NAME="BaseDevice.writeCredentials" ID="BaseDevice.writeCredentials"></a>
+<h4>BaseDevice.writeCredentials</h4>
+<b>writeCredentials</b>(<i>ssid, password</i>)
+
+<p>
+        Public method to write the given credentials to the connected device and modify
+        the start script to connect automatically.
+</p>
+<dl>
+
+<dt><i>ssid</i> (str)</dt>
+<dd>
+SSID of the network to connect to
+</dd>
+<dt><i>password</i> (str)</dt>
+<dd>
+password needed to authenticate
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating success and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 </body></html>
\ No newline at end of file
--- a/src/eric7/Documentation/Source/eric7.MicroPython.Devices.EspDevices.html	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/Documentation/Source/eric7.MicroPython.Devices.EspDevices.html	Sat Feb 25 19:47:23 2023 +0100
@@ -140,14 +140,34 @@
 <td>Public method to determine, if a REPL can be started.</td>
 </tr>
 <tr>
+<td><a href="#EspDevice.checkInternet">checkInternet</a></td>
+<td>Public method to check, if the internet can be reached.</td>
+</tr>
+<tr>
+<td><a href="#EspDevice.connectWifi">connectWifi</a></td>
+<td>Public method to connect a device to a WiFi network.</td>
+</tr>
+<tr>
+<td><a href="#EspDevice.deactivateInterface">deactivateInterface</a></td>
+<td>Public method to deactivate a given WiFi interface of the connected device.</td>
+</tr>
+<tr>
 <td><a href="#EspDevice.deviceName">deviceName</a></td>
 <td>Public method to get the name of the device.</td>
 </tr>
 <tr>
+<td><a href="#EspDevice.disconnectWifi">disconnectWifi</a></td>
+<td>Public method to disconnect a device from the WiFi network.</td>
+</tr>
+<tr>
 <td><a href="#EspDevice.forceInterrupt">forceInterrupt</a></td>
 <td>Public method to determine the need for an interrupt when opening the serial connection.</td>
 </tr>
 <tr>
+<td><a href="#EspDevice.getConnectedClients">getConnectedClients</a></td>
+<td>Public method to get a list of connected clients.</td>
+</tr>
+<tr>
 <td><a href="#EspDevice.getDocumentationUrl">getDocumentationUrl</a></td>
 <td>Public method to get the device documentation URL.</td>
 </tr>
@@ -156,17 +176,45 @@
 <td>Public method to get the device firmware download URL.</td>
 </tr>
 <tr>
+<td><a href="#EspDevice.getWifiData">getWifiData</a></td>
+<td>Public method to get data related to the current WiFi status.</td>
+</tr>
+<tr>
 <td><a href="#EspDevice.hasFlashMenuEntry">hasFlashMenuEntry</a></td>
 <td>Public method to check, if the device has its own flash menu entry.</td>
 </tr>
 <tr>
+<td><a href="#EspDevice.hasWifi">hasWifi</a></td>
+<td>Public method to check the availability of WiFi.</td>
+</tr>
+<tr>
+<td><a href="#EspDevice.removeCredentials">removeCredentials</a></td>
+<td>Public method to remove the saved credentials from the connected device.</td>
+</tr>
+<tr>
 <td><a href="#EspDevice.runScript">runScript</a></td>
 <td>Public method to run the given Python script.</td>
 </tr>
 <tr>
+<td><a href="#EspDevice.scanNetworks">scanNetworks</a></td>
+<td>Public method to scan for available WiFi networks.</td>
+</tr>
+<tr>
 <td><a href="#EspDevice.setButtons">setButtons</a></td>
 <td>Public method to enable the supported action buttons.</td>
 </tr>
+<tr>
+<td><a href="#EspDevice.startAccessPoint">startAccessPoint</a></td>
+<td>Public method to start the access point interface.</td>
+</tr>
+<tr>
+<td><a href="#EspDevice.stopAccessPoint">stopAccessPoint</a></td>
+<td>Public method to stop the access point interface.</td>
+</tr>
+<tr>
+<td><a href="#EspDevice.writeCredentials">writeCredentials</a></td>
+<td>Public method to write the given credentials to the connected device and modify the start script to connect automatically.</td>
+</tr>
 </table>
 <h3>Static Methods</h3>
 
@@ -412,6 +460,89 @@
 tuple of (bool, str)
 </dd>
 </dl>
+<a NAME="EspDevice.checkInternet" ID="EspDevice.checkInternet"></a>
+<h4>EspDevice.checkInternet</h4>
+<b>checkInternet</b>(<i></i>)
+
+<p>
+        Public method to check, if the internet can be reached.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating reachability and an error string
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
+<a NAME="EspDevice.connectWifi" ID="EspDevice.connectWifi"></a>
+<h4>EspDevice.connectWifi</h4>
+<b>connectWifi</b>(<i>ssid, password</i>)
+
+<p>
+        Public method to connect a device to a WiFi network.
+</p>
+<dl>
+
+<dt><i>ssid</i> (str)</dt>
+<dd>
+name (SSID) of the WiFi network
+</dd>
+<dt><i>password</i> (str)</dt>
+<dd>
+password needed to connect
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing the connection status and an error string
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
+<a NAME="EspDevice.deactivateInterface" ID="EspDevice.deactivateInterface"></a>
+<h4>EspDevice.deactivateInterface</h4>
+<b>deactivateInterface</b>(<i>interface</i>)
+
+<p>
+        Public method to deactivate a given WiFi interface of the connected device.
+</p>
+<dl>
+
+<dt><i>interface</i> (str)</dt>
+<dd>
+designation of the interface to be deactivated (one of 'AP'
+            or 'STA')
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containg a flag indicating success and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
+<dl>
+
+<dt>Raises <b>ValueError</b>:</dt>
+<dd>
+raised to indicate a wrong value for the interface type
+</dd>
+</dl>
 <a NAME="EspDevice.deviceName" ID="EspDevice.deviceName"></a>
 <h4>EspDevice.deviceName</h4>
 <b>deviceName</b>(<i></i>)
@@ -431,6 +562,25 @@
 str
 </dd>
 </dl>
+<a NAME="EspDevice.disconnectWifi" ID="EspDevice.disconnectWifi"></a>
+<h4>EspDevice.disconnectWifi</h4>
+<b>disconnectWifi</b>(<i></i>)
+
+<p>
+        Public method to disconnect a device from the WiFi network.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating success and an error string
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
 <a NAME="EspDevice.forceInterrupt" ID="EspDevice.forceInterrupt"></a>
 <h4>EspDevice.forceInterrupt</h4>
 <b>forceInterrupt</b>(<i></i>)
@@ -451,6 +601,26 @@
 bool
 </dd>
 </dl>
+<a NAME="EspDevice.getConnectedClients" ID="EspDevice.getConnectedClients"></a>
+<h4>EspDevice.getConnectedClients</h4>
+<b>getConnectedClients</b>(<i></i>)
+
+<p>
+        Public method to get a list of connected clients.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+a tuple containing a list of tuples containing the client MAC-Address
+            and the RSSI (if supported and available) and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of ([(bytes, int)], str)
+</dd>
+</dl>
 <a NAME="EspDevice.getDocumentationUrl" ID="EspDevice.getDocumentationUrl"></a>
 <h4>EspDevice.getDocumentationUrl</h4>
 <b>getDocumentationUrl</b>(<i></i>)
@@ -489,6 +659,33 @@
 str
 </dd>
 </dl>
+<a NAME="EspDevice.getWifiData" ID="EspDevice.getWifiData"></a>
+<h4>EspDevice.getWifiData</h4>
+<b>getWifiData</b>(<i></i>)
+
+<p>
+        Public method to get data related to the current WiFi status.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple of three dictionaries containing the WiFi status data
+            for the WiFi client, access point and overall data
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (dict, dict, dict)
+</dd>
+</dl>
+<dl>
+
+<dt>Raises <b>OSError</b>:</dt>
+<dd>
+raised to indicate an issue with the device
+</dd>
+</dl>
 <a NAME="EspDevice.hasFlashMenuEntry" ID="EspDevice.hasFlashMenuEntry"></a>
 <h4>EspDevice.hasFlashMenuEntry</h4>
 <b>hasFlashMenuEntry</b>(<i></i>)
@@ -508,6 +705,45 @@
 bool
 </dd>
 </dl>
+<a NAME="EspDevice.hasWifi" ID="EspDevice.hasWifi"></a>
+<h4>EspDevice.hasWifi</h4>
+<b>hasWifi</b>(<i></i>)
+
+<p>
+        Public method to check the availability of WiFi.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating the availability of WiFi
+            and the WiFi type (esp32)
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
+<a NAME="EspDevice.removeCredentials" ID="EspDevice.removeCredentials"></a>
+<h4>EspDevice.removeCredentials</h4>
+<b>removeCredentials</b>(<i></i>)
+
+<p>
+        Public method to remove the saved credentials from the connected device.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating success and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
 <a NAME="EspDevice.runScript" ID="EspDevice.runScript"></a>
 <h4>EspDevice.runScript</h4>
 <b>runScript</b>(<i>script</i>)
@@ -522,6 +758,26 @@
 script to be executed
 </dd>
 </dl>
+<a NAME="EspDevice.scanNetworks" ID="EspDevice.scanNetworks"></a>
+<h4>EspDevice.scanNetworks</h4>
+<b>scanNetworks</b>(<i></i>)
+
+<p>
+        Public method to scan for available WiFi networks.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing the list of available networks as a tuple of 'Name',
+            'MAC-Address', 'channel', 'RSSI' and 'security' and an error string
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (list of tuple of (str, str, int, int, str), str)
+</dd>
+</dl>
 <a NAME="EspDevice.setButtons" ID="EspDevice.setButtons"></a>
 <h4>EspDevice.setButtons</h4>
 <b>setButtons</b>(<i></i>)
@@ -529,6 +785,95 @@
 <p>
         Public method to enable the supported action buttons.
 </p>
+<a NAME="EspDevice.startAccessPoint" ID="EspDevice.startAccessPoint"></a>
+<h4>EspDevice.startAccessPoint</h4>
+<b>startAccessPoint</b>(<i>ssid, security=None, password=None, ifconfig=None</i>)
+
+<p>
+        Public method to start the access point interface.
+</p>
+<dl>
+
+<dt><i>ssid</i> (str)</dt>
+<dd>
+SSID of the access point
+</dd>
+<dt><i>security</i> (int (optional))</dt>
+<dd>
+security method (defaults to None)
+</dd>
+<dt><i>password</i> (str (optional))</dt>
+<dd>
+password (defaults to None)
+</dd>
+<dt><i>ifconfig</i> (tuple of (str, str, str, str))</dt>
+<dd>
+IPv4 configuration for the access point if not default
+            (IPv4 address, netmask, gateway address, DNS server address)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating success and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
+<a NAME="EspDevice.stopAccessPoint" ID="EspDevice.stopAccessPoint"></a>
+<h4>EspDevice.stopAccessPoint</h4>
+<b>stopAccessPoint</b>(<i></i>)
+
+<p>
+        Public method to stop the access point interface.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containg a flag indicating success and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
+<a NAME="EspDevice.writeCredentials" ID="EspDevice.writeCredentials"></a>
+<h4>EspDevice.writeCredentials</h4>
+<b>writeCredentials</b>(<i>ssid, password</i>)
+
+<p>
+        Public method to write the given credentials to the connected device and modify
+        the start script to connect automatically.
+</p>
+<dl>
+
+<dt><i>ssid</i> (str)</dt>
+<dd>
+SSID of the network to connect to
+</dd>
+<dt><i>password</i> (str)</dt>
+<dd>
+password needed to authenticate
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating success and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.MicroPython.Devices.MCUScripts.esp32WiFiConnect.html	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.MicroPython.Devices.MCUScripts.esp32WiFiConnect</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.MicroPython.Devices.MCUScripts.esp32WiFiConnect</h1>
+
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+
+<tr>
+<td><a href="#connectWiFi">connectWiFi</a></td>
+<td></td>
+</tr>
+</table>
+<hr />
+<hr />
+<a NAME="connectWiFi" ID="connectWiFi"></a>
+<h2>connectWiFi</h2>
+<b>connectWiFi</b>(<i></i>)
+
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.MicroPython.Devices.MCUScripts.picowWiFiConnect.html	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.MicroPython.Devices.MCUScripts.picowWiFiConnect</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.MicroPython.Devices.MCUScripts.picowWiFiConnect</h1>
+
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+
+<tr>
+<td><a href="#connectWiFi">connectWiFi</a></td>
+<td></td>
+</tr>
+</table>
+<hr />
+<hr />
+<a NAME="connectWiFi" ID="connectWiFi"></a>
+<h2>connectWiFi</h2>
+<b>connectWiFi</b>(<i></i>)
+
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
--- a/src/eric7/Documentation/Source/eric7.MicroPython.Devices.RP2040Devices.html	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/Documentation/Source/eric7.MicroPython.Devices.RP2040Devices.html	Sat Feb 25 19:47:23 2023 +0100
@@ -80,6 +80,10 @@
 <td>Private slot to flash a MicroPython firmware to the device.</td>
 </tr>
 <tr>
+<td><a href="#RP2040Device.__setCountry">__setCountry</a></td>
+<td>Private slot to configure the country of the connected RP2040 device.</td>
+</tr>
+<tr>
 <td><a href="#RP2040Device.__showFirmwareVersions">__showFirmwareVersions</a></td>
 <td>Private slot to show the firmware version of the connected device and the available firmware version.</td>
 </tr>
@@ -92,6 +96,10 @@
 <td>Public method to add device specific entries to the given menu.</td>
 </tr>
 <tr>
+<td><a href="#RP2040Device.addDeviceWifiEntries">addDeviceWifiEntries</a></td>
+<td>Public method to add device specific entries to the given menu.</td>
+</tr>
+<tr>
 <td><a href="#RP2040Device.canRunScript">canRunScript</a></td>
 <td>Public method to determine, if a script can be executed.</td>
 </tr>
@@ -108,14 +116,34 @@
 <td>Public method to determine, if a REPL can be started.</td>
 </tr>
 <tr>
+<td><a href="#RP2040Device.checkInternet">checkInternet</a></td>
+<td>Public method to check, if the internet can be reached.</td>
+</tr>
+<tr>
+<td><a href="#RP2040Device.connectWifi">connectWifi</a></td>
+<td>Public method to connect a device to a WiFi network.</td>
+</tr>
+<tr>
+<td><a href="#RP2040Device.deactivateInterface">deactivateInterface</a></td>
+<td>Public method to deactivate a given WiFi interface of the connected device.</td>
+</tr>
+<tr>
 <td><a href="#RP2040Device.deviceName">deviceName</a></td>
 <td>Public method to get the name of the device.</td>
 </tr>
 <tr>
+<td><a href="#RP2040Device.disconnectWifi">disconnectWifi</a></td>
+<td>Public method to disconnect a device from the WiFi network.</td>
+</tr>
+<tr>
 <td><a href="#RP2040Device.forceInterrupt">forceInterrupt</a></td>
 <td>Public method to determine the need for an interrupt when opening the serial connection.</td>
 </tr>
 <tr>
+<td><a href="#RP2040Device.getConnectedClients">getConnectedClients</a></td>
+<td>Public method to get a list of connected clients.</td>
+</tr>
+<tr>
 <td><a href="#RP2040Device.getDocumentationUrl">getDocumentationUrl</a></td>
 <td>Public method to get the device documentation URL.</td>
 </tr>
@@ -124,17 +152,45 @@
 <td>Public method to retrieve the entries for the downloads menu.</td>
 </tr>
 <tr>
+<td><a href="#RP2040Device.getWifiData">getWifiData</a></td>
+<td>Public method to get data related to the current WiFi status.</td>
+</tr>
+<tr>
 <td><a href="#RP2040Device.hasFlashMenuEntry">hasFlashMenuEntry</a></td>
 <td>Public method to check, if the device has its own flash menu entry.</td>
 </tr>
 <tr>
+<td><a href="#RP2040Device.hasWifi">hasWifi</a></td>
+<td>Public method to check the availability of WiFi.</td>
+</tr>
+<tr>
+<td><a href="#RP2040Device.removeCredentials">removeCredentials</a></td>
+<td>Public method to remove the saved credentials from the connected device.</td>
+</tr>
+<tr>
 <td><a href="#RP2040Device.runScript">runScript</a></td>
 <td>Public method to run the given Python script.</td>
 </tr>
 <tr>
+<td><a href="#RP2040Device.scanNetworks">scanNetworks</a></td>
+<td>Public method to scan for available WiFi networks.</td>
+</tr>
+<tr>
 <td><a href="#RP2040Device.setButtons">setButtons</a></td>
 <td>Public method to enable the supported action buttons.</td>
 </tr>
+<tr>
+<td><a href="#RP2040Device.startAccessPoint">startAccessPoint</a></td>
+<td>Public method to start the access point interface.</td>
+</tr>
+<tr>
+<td><a href="#RP2040Device.stopAccessPoint">stopAccessPoint</a></td>
+<td>Public method to stop the access point interface.</td>
+</tr>
+<tr>
+<td><a href="#RP2040Device.writeCredentials">writeCredentials</a></td>
+<td>Public method to write the given credentials to the connected device and modify the start script to connect automatically.</td>
+</tr>
 </table>
 <h3>Static Methods</h3>
 
@@ -199,6 +255,16 @@
 <p>
         Private slot to flash a MicroPython firmware to the device.
 </p>
+<a NAME="RP2040Device.__setCountry" ID="RP2040Device.__setCountry"></a>
+<h4>RP2040Device.__setCountry</h4>
+<b>__setCountry</b>(<i></i>)
+
+<p>
+        Private slot to configure the country of the connected RP2040 device.
+</p>
+<p>
+        The country is the two letter country code.
+</p>
 <a NAME="RP2040Device.__showFirmwareVersions" ID="RP2040Device.__showFirmwareVersions"></a>
 <h4>RP2040Device.__showFirmwareVersions</h4>
 <b>__showFirmwareVersions</b>(<i></i>)
@@ -244,6 +310,20 @@
 reference to the context menu
 </dd>
 </dl>
+<a NAME="RP2040Device.addDeviceWifiEntries" ID="RP2040Device.addDeviceWifiEntries"></a>
+<h4>RP2040Device.addDeviceWifiEntries</h4>
+<b>addDeviceWifiEntries</b>(<i>menu</i>)
+
+<p>
+        Public method to add device specific entries to the given menu.
+</p>
+<dl>
+
+<dt><i>menu</i> (QMenu)</dt>
+<dd>
+reference to the context menu
+</dd>
+</dl>
 <a NAME="RP2040Device.canRunScript" ID="RP2040Device.canRunScript"></a>
 <h4>RP2040Device.canRunScript</h4>
 <b>canRunScript</b>(<i></i>)
@@ -324,6 +404,89 @@
 tuple of (bool, str)
 </dd>
 </dl>
+<a NAME="RP2040Device.checkInternet" ID="RP2040Device.checkInternet"></a>
+<h4>RP2040Device.checkInternet</h4>
+<b>checkInternet</b>(<i></i>)
+
+<p>
+        Public method to check, if the internet can be reached.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating reachability and an error string
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
+<a NAME="RP2040Device.connectWifi" ID="RP2040Device.connectWifi"></a>
+<h4>RP2040Device.connectWifi</h4>
+<b>connectWifi</b>(<i>ssid, password</i>)
+
+<p>
+        Public method to connect a device to a WiFi network.
+</p>
+<dl>
+
+<dt><i>ssid</i> (str)</dt>
+<dd>
+name (SSID) of the WiFi network
+</dd>
+<dt><i>password</i> (str)</dt>
+<dd>
+password needed to connect
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing the connection status and an error string
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
+<a NAME="RP2040Device.deactivateInterface" ID="RP2040Device.deactivateInterface"></a>
+<h4>RP2040Device.deactivateInterface</h4>
+<b>deactivateInterface</b>(<i>interface</i>)
+
+<p>
+        Public method to deactivate a given WiFi interface of the connected device.
+</p>
+<dl>
+
+<dt><i>interface</i> (str)</dt>
+<dd>
+designation of the interface to be deactivated (one of 'AP'
+            or 'STA')
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containg a flag indicating success and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
+<dl>
+
+<dt>Raises <b>ValueError</b>:</dt>
+<dd>
+raised to indicate a wrong value for the interface type
+</dd>
+</dl>
 <a NAME="RP2040Device.deviceName" ID="RP2040Device.deviceName"></a>
 <h4>RP2040Device.deviceName</h4>
 <b>deviceName</b>(<i></i>)
@@ -343,6 +506,25 @@
 str
 </dd>
 </dl>
+<a NAME="RP2040Device.disconnectWifi" ID="RP2040Device.disconnectWifi"></a>
+<h4>RP2040Device.disconnectWifi</h4>
+<b>disconnectWifi</b>(<i></i>)
+
+<p>
+        Public method to disconnect a device from the WiFi network.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating success and an error string
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
 <a NAME="RP2040Device.forceInterrupt" ID="RP2040Device.forceInterrupt"></a>
 <h4>RP2040Device.forceInterrupt</h4>
 <b>forceInterrupt</b>(<i></i>)
@@ -363,6 +545,26 @@
 bool
 </dd>
 </dl>
+<a NAME="RP2040Device.getConnectedClients" ID="RP2040Device.getConnectedClients"></a>
+<h4>RP2040Device.getConnectedClients</h4>
+<b>getConnectedClients</b>(<i></i>)
+
+<p>
+        Public method to get a list of connected clients.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+a tuple containing a list of tuples containing the client MAC-Address
+            and the RSSI (if supported and available) and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of ([(bytes, int)], str)
+</dd>
+</dl>
 <a NAME="RP2040Device.getDocumentationUrl" ID="RP2040Device.getDocumentationUrl"></a>
 <h4>RP2040Device.getDocumentationUrl</h4>
 <b>getDocumentationUrl</b>(<i></i>)
@@ -402,6 +604,33 @@
 list of tuple of (str, str)
 </dd>
 </dl>
+<a NAME="RP2040Device.getWifiData" ID="RP2040Device.getWifiData"></a>
+<h4>RP2040Device.getWifiData</h4>
+<b>getWifiData</b>(<i></i>)
+
+<p>
+        Public method to get data related to the current WiFi status.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple of three dictionaries containing the WiFi status data
+            for the WiFi client, access point and overall data
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (dict, dict, dict)
+</dd>
+</dl>
+<dl>
+
+<dt>Raises <b>OSError</b>:</dt>
+<dd>
+raised to indicate an issue with the device
+</dd>
+</dl>
 <a NAME="RP2040Device.hasFlashMenuEntry" ID="RP2040Device.hasFlashMenuEntry"></a>
 <h4>RP2040Device.hasFlashMenuEntry</h4>
 <b>hasFlashMenuEntry</b>(<i></i>)
@@ -421,6 +650,52 @@
 bool
 </dd>
 </dl>
+<a NAME="RP2040Device.hasWifi" ID="RP2040Device.hasWifi"></a>
+<h4>RP2040Device.hasWifi</h4>
+<b>hasWifi</b>(<i></i>)
+
+<p>
+        Public method to check the availability of WiFi.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating the availability of WiFi
+            and the WiFi type (picow or pimoroni)
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
+<dl>
+
+<dt>Raises <b>OSError</b>:</dt>
+<dd>
+raised to indicate an issue with the device
+</dd>
+</dl>
+<a NAME="RP2040Device.removeCredentials" ID="RP2040Device.removeCredentials"></a>
+<h4>RP2040Device.removeCredentials</h4>
+<b>removeCredentials</b>(<i></i>)
+
+<p>
+        Public method to remove the saved credentials from the connected device.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating success and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
 <a NAME="RP2040Device.runScript" ID="RP2040Device.runScript"></a>
 <h4>RP2040Device.runScript</h4>
 <b>runScript</b>(<i>script</i>)
@@ -435,6 +710,26 @@
 script to be executed
 </dd>
 </dl>
+<a NAME="RP2040Device.scanNetworks" ID="RP2040Device.scanNetworks"></a>
+<h4>RP2040Device.scanNetworks</h4>
+<b>scanNetworks</b>(<i></i>)
+
+<p>
+        Public method to scan for available WiFi networks.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing the list of available networks as a tuple of 'Name',
+            'MAC-Address', 'channel', 'RSSI' and 'security' and an error string
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (list of tuple of (str, str, int, int, str), str)
+</dd>
+</dl>
 <a NAME="RP2040Device.setButtons" ID="RP2040Device.setButtons"></a>
 <h4>RP2040Device.setButtons</h4>
 <b>setButtons</b>(<i></i>)
@@ -442,6 +737,95 @@
 <p>
         Public method to enable the supported action buttons.
 </p>
+<a NAME="RP2040Device.startAccessPoint" ID="RP2040Device.startAccessPoint"></a>
+<h4>RP2040Device.startAccessPoint</h4>
+<b>startAccessPoint</b>(<i>ssid, security=None, password=None, ifconfig=None</i>)
+
+<p>
+        Public method to start the access point interface.
+</p>
+<dl>
+
+<dt><i>ssid</i> (str)</dt>
+<dd>
+SSID of the access point
+</dd>
+<dt><i>security</i> (int (optional))</dt>
+<dd>
+security method (defaults to None)
+</dd>
+<dt><i>password</i> (str (optional))</dt>
+<dd>
+password (defaults to None)
+</dd>
+<dt><i>ifconfig</i> (tuple of (str, str, str, str))</dt>
+<dd>
+IPv4 configuration for the access point if not default
+            (IPv4 address, netmask, gateway address, DNS server address)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating success and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
+<a NAME="RP2040Device.stopAccessPoint" ID="RP2040Device.stopAccessPoint"></a>
+<h4>RP2040Device.stopAccessPoint</h4>
+<b>stopAccessPoint</b>(<i></i>)
+
+<p>
+        Public method to stop the access point interface.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containg a flag indicating success and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
+<a NAME="RP2040Device.writeCredentials" ID="RP2040Device.writeCredentials"></a>
+<h4>RP2040Device.writeCredentials</h4>
+<b>writeCredentials</b>(<i>ssid, password</i>)
+
+<p>
+        Public method to write the given credentials to the connected device and modify
+        the start script to connect automatically.
+</p>
+<dl>
+
+<dt><i>ssid</i> (str)</dt>
+<dd>
+SSID of the network to connect to
+</dd>
+<dt><i>password</i> (str)</dt>
+<dd>
+password needed to authenticate
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a flag indicating success and an error message
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bool, str)
+</dd>
+</dl>
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
--- a/src/eric7/Documentation/Source/eric7.MicroPython.MicroPythonDeviceInterface.html	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/Documentation/Source/eric7.MicroPython.MicroPythonDeviceInterface.html	Sat Feb 25 19:47:23 2023 +0100
@@ -57,7 +57,7 @@
 <h3>Class Attributes</h3>
 
 <table>
-<tr><td>None</td></tr>
+<tr><td>PasteModePrompt</td></tr><tr><td>TracebackMarker</td></tr>
 </table>
 <h3>Class Methods</h3>
 
@@ -73,6 +73,22 @@
 <td>Constructor</td>
 </tr>
 <tr>
+<td><a href="#MicroPythonDeviceInterface.__execute_paste">__execute_paste</a></td>
+<td>Private method to send commands to the connected device using 'paste' mode and return the result.</td>
+</tr>
+<tr>
+<td><a href="#MicroPythonDeviceInterface.__execute_raw">__execute_raw</a></td>
+<td>Private method to send commands to the connected device using 'raw REPL' mode and return the result.</td>
+</tr>
+<tr>
+<td><a href="#MicroPythonDeviceInterface.__pasteOff">__pasteOff</a></td>
+<td>Private method to switch 'paste' mode off.</td>
+</tr>
+<tr>
+<td><a href="#MicroPythonDeviceInterface.__pasteOn">__pasteOn</a></td>
+<td>Private method to switch the connected device to 'paste' mode.</td>
+</tr>
+<tr>
 <td><a href="#MicroPythonDeviceInterface.__rawOff">__rawOff</a></td>
 <td>Private method to switch 'raw' mode off.</td>
 </tr>
@@ -101,6 +117,10 @@
 <td>Public method to execute a series of commands over a period of time without returning any result (asynchronous execution).</td>
 </tr>
 <tr>
+<td><a href="#MicroPythonDeviceInterface.executeAsyncPaste">executeAsyncPaste</a></td>
+<td>Public method to execute a series of commands over a period of time without returning any result (asynchronous execution).</td>
+</tr>
+<tr>
 <td><a href="#MicroPythonDeviceInterface.handlePreferencesChanged">handlePreferencesChanged</a></td>
 <td>Public slot to handle a change of the preferences.</td>
 </tr>
@@ -137,6 +157,105 @@
 reference to the parent object
 </dd>
 </dl>
+<a NAME="MicroPythonDeviceInterface.__execute_paste" ID="MicroPythonDeviceInterface.__execute_paste"></a>
+<h4>MicroPythonDeviceInterface.__execute_paste</h4>
+<b>__execute_paste</b>(<i>commands, timeout=0</i>)
+
+<p>
+        Private method to send commands to the connected device using 'paste' mode
+        and return the result.
+</p>
+<p>
+        If no serial connection is available, empty results will be returned.
+</p>
+<dl>
+
+<dt><i>commands</i> (str or list of str)</dt>
+<dd>
+list of commands to be executed
+</dd>
+<dt><i>timeout</i> (int (optional))</dt>
+<dd>
+per command timeout in milliseconds (0 for configured default)
+            (defaults to 0)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing stdout and stderr output of the device
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bytes, bytes)
+</dd>
+</dl>
+<a NAME="MicroPythonDeviceInterface.__execute_raw" ID="MicroPythonDeviceInterface.__execute_raw"></a>
+<h4>MicroPythonDeviceInterface.__execute_raw</h4>
+<b>__execute_raw</b>(<i>commands, timeout=0</i>)
+
+<p>
+        Private method to send commands to the connected device using 'raw REPL' mode
+        and return the result.
+</p>
+<p>
+        If no serial connection is available, empty results will be returned.
+</p>
+<dl>
+
+<dt><i>commands</i> (str or list of str)</dt>
+<dd>
+list of commands to be executed
+</dd>
+<dt><i>timeout</i> (int (optional))</dt>
+<dd>
+per command timeout in milliseconds (0 for configured default)
+            (defaults to 0)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing stdout and stderr output of the device
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bytes, bytes)
+</dd>
+</dl>
+<a NAME="MicroPythonDeviceInterface.__pasteOff" ID="MicroPythonDeviceInterface.__pasteOff"></a>
+<h4>MicroPythonDeviceInterface.__pasteOff</h4>
+<b>__pasteOff</b>(<i></i>)
+
+<p>
+        Private method to switch 'paste' mode off.
+</p>
+<a NAME="MicroPythonDeviceInterface.__pasteOn" ID="MicroPythonDeviceInterface.__pasteOn"></a>
+<h4>MicroPythonDeviceInterface.__pasteOn</h4>
+<b>__pasteOn</b>(<i></i>)
+
+<p>
+        Private method to switch the connected device to 'paste' mode.
+</p>
+<p>
+        Note: switching to paste mode is done with synchronous writes.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating success
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
 <a NAME="MicroPythonDeviceInterface.__rawOff" ID="MicroPythonDeviceInterface.__rawOff"></a>
 <h4>MicroPythonDeviceInterface.__rawOff</h4>
 <b>__rawOff</b>(<i></i>)
@@ -158,7 +277,12 @@
 <dt>Return:</dt>
 <dd>
 flag indicating success
-@rtype bool
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
 </dd>
 </dl>
 <a NAME="MicroPythonDeviceInterface.__readSerial" ID="MicroPythonDeviceInterface.__readSerial"></a>
@@ -204,7 +328,7 @@
 </p>
 <a NAME="MicroPythonDeviceInterface.execute" ID="MicroPythonDeviceInterface.execute"></a>
 <h4>MicroPythonDeviceInterface.execute</h4>
-<b>execute</b>(<i>commands</i>)
+<b>execute</b>(<i>commands, *, mode="raw", timeout=0</i>)
 
 <p>
         Public method to send commands to the connected device and return the
@@ -219,6 +343,16 @@
 <dd>
 list of commands to be executed
 </dd>
+<dt><i>mode=</i> (str)</dt>
+<dd>
+submit mode to be used (one of 'raw' or 'paste') (defaults to
+            'raw')
+</dd>
+<dt><i>timeout=</i> (int (optional))</dt>
+<dd>
+per command timeout in milliseconds (0 for configured default)
+            (defaults to 0)
+</dd>
 </dl>
 <dl>
 <dt>Return:</dt>
@@ -232,6 +366,13 @@
 tuple of (bytes, bytes)
 </dd>
 </dl>
+<dl>
+
+<dt>Raises <b>ValueError</b>:</dt>
+<dd>
+raised in case of an unsupported submit mode
+</dd>
+</dl>
 <a NAME="MicroPythonDeviceInterface.executeAsync" ID="MicroPythonDeviceInterface.executeAsync"></a>
 <h4>MicroPythonDeviceInterface.executeAsync</h4>
 <b>executeAsync</b>(<i>commandsList</i>)
@@ -247,6 +388,21 @@
 list of commands to be execute on the device
 </dd>
 </dl>
+<a NAME="MicroPythonDeviceInterface.executeAsyncPaste" ID="MicroPythonDeviceInterface.executeAsyncPaste"></a>
+<h4>MicroPythonDeviceInterface.executeAsyncPaste</h4>
+<b>executeAsyncPaste</b>(<i>commandsList</i>)
+
+<p>
+        Public method to execute a series of commands over a period of time
+        without returning any result (asynchronous execution).
+</p>
+<dl>
+
+<dt><i>commandsList</i> (list of bytes)</dt>
+<dd>
+list of commands to be execute on the device
+</dd>
+</dl>
 <a NAME="MicroPythonDeviceInterface.handlePreferencesChanged" ID="MicroPythonDeviceInterface.handlePreferencesChanged"></a>
 <h4>MicroPythonDeviceInterface.handlePreferencesChanged</h4>
 <b>handlePreferencesChanged</b>(<i></i>)
--- a/src/eric7/Documentation/Source/eric7.MicroPython.MicroPythonSerialPort.html	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/Documentation/Source/eric7.MicroPython.MicroPythonSerialPort.html	Sat Feb 25 19:47:23 2023 +0100
@@ -177,7 +177,7 @@
 </dl>
 <a NAME="MicroPythonSerialPort.readUntil" ID="MicroPythonSerialPort.readUntil"></a>
 <h4>MicroPythonSerialPort.readUntil</h4>
-<b>readUntil</b>(<i>expected=b"\n", size=None</i>)
+<b>readUntil</b>(<i>expected=b"\n", size=None, timeout=0</i>)
 
 <p>
         Public method to read data until an expected sequence is found
@@ -189,9 +189,14 @@
 <dd>
 expected bytes sequence
 </dd>
-<dt><i>size</i> (int)</dt>
+<dt><i>size</i> (int (optional))</dt>
 <dd>
-maximum data to be read
+maximum data to be read (defaults to None)
+</dd>
+<dt><i>timeout</i> (int (optional))</dt>
+<dd>
+timeout in milliseconds (0 for configured default)
+            (defaults to 0)
 </dd>
 </dl>
 <dl>
--- a/src/eric7/Documentation/Source/eric7.MicroPython.MicroPythonWidget.html	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/Documentation/Source/eric7.MicroPython.MicroPythonWidget.html	Sat Feb 25 19:47:23 2023 +0100
@@ -188,10 +188,6 @@
 <td>Private slot to open the documentation URL for the selected device.</td>
 </tr>
 <tr>
-<td><a href="#MicroPythonWidget.__showError">__showError</a></td>
-<td>Private method to show some error message.</td>
-</tr>
-<tr>
 <td><a href="#MicroPythonWidget.__showImplementation">__showImplementation</a></td>
 <td>Private slot to show some implementation related information.</td>
 </tr>
@@ -232,6 +228,10 @@
 <td>Public method to determine the port path of the selected device.</td>
 </tr>
 <tr>
+<td><a href="#MicroPythonWidget.getDevice">getDevice</a></td>
+<td>Public method to get a reference to the current device.</td>
+</tr>
+<tr>
 <td><a href="#MicroPythonWidget.getDeviceWorkspace">getDeviceWorkspace</a></td>
 <td>Public method to get the workspace directory of the device.</td>
 </tr>
@@ -283,6 +283,10 @@
 <td><a href="#MicroPythonWidget.setActionButtons">setActionButtons</a></td>
 <td>Public method to set the enabled state of the various action buttons.</td>
 </tr>
+<tr>
+<td><a href="#MicroPythonWidget.showError">showError</a></td>
+<td>Public method to show some error message.</td>
+</tr>
 </table>
 <h3>Static Methods</h3>
 
@@ -686,24 +690,6 @@
 <p>
         Private slot to open the documentation URL for the selected device.
 </p>
-<a NAME="MicroPythonWidget.__showError" ID="MicroPythonWidget.__showError"></a>
-<h4>MicroPythonWidget.__showError</h4>
-<b>__showError</b>(<i>method, error</i>)
-
-<p>
-        Private method to show some error message.
-</p>
-<dl>
-
-<dt><i>method</i> (str)</dt>
-<dd>
-name of the method the error occured in
-</dd>
-<dt><i>error</i> (str)</dt>
-<dd>
-error message
-</dd>
-</dl>
 <a NAME="MicroPythonWidget.__showImplementation" ID="MicroPythonWidget.__showImplementation"></a>
 <h4>MicroPythonWidget.__showImplementation</h4>
 <b>__showImplementation</b>(<i></i>)
@@ -854,6 +840,25 @@
 str
 </dd>
 </dl>
+<a NAME="MicroPythonWidget.getDevice" ID="MicroPythonWidget.getDevice"></a>
+<h4>MicroPythonWidget.getDevice</h4>
+<b>getDevice</b>(<i></i>)
+
+<p>
+        Public method to get a reference to the current device.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+reference to the current device
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+BaseDevice
+</dd>
+</dl>
 <a NAME="MicroPythonWidget.getDeviceWorkspace" ID="MicroPythonWidget.getDeviceWorkspace"></a>
 <h4>MicroPythonWidget.getDeviceWorkspace</h4>
 <b>getDeviceWorkspace</b>(<i></i>)
@@ -1041,6 +1046,24 @@
             are 'run', 'repl', 'files', 'chart', 'open', 'save'
 </dd>
 </dl>
+<a NAME="MicroPythonWidget.showError" ID="MicroPythonWidget.showError"></a>
+<h4>MicroPythonWidget.showError</h4>
+<b>showError</b>(<i>method, error</i>)
+
+<p>
+        Public method to show some error message.
+</p>
+<dl>
+
+<dt><i>method</i> (str)</dt>
+<dd>
+name of the method the error occured in
+</dd>
+<dt><i>error</i> (str)</dt>
+<dd>
+error message
+</dd>
+</dl>
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 </body></html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.MicroPython.WifiDialogs.WifiApConfigDialog.html	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.MicroPython.WifiDialogs.WifiApConfigDialog</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.MicroPython.WifiDialogs.WifiApConfigDialog</h1>
+
+<p>
+Module implementing a dialog to configure the Access Point interface.
+</p>
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+
+<tr>
+<td><a href="#WifiApConfigDialog">WifiApConfigDialog</a></td>
+<td>Class implementing a dialog to configure the Access Point interface.</td>
+</tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<hr />
+<hr />
+<a NAME="WifiApConfigDialog" ID="WifiApConfigDialog"></a>
+<h2>WifiApConfigDialog</h2>
+
+<p>
+    Class implementing a dialog to configure the Access Point interface.
+</p>
+<h3>Derived from</h3>
+QDialog, Ui_WifiApConfigDialog
+<h3>Class Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Class Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#WifiApConfigDialog.__init__">WifiApConfigDialog</a></td>
+<td>Constructor</td>
+</tr>
+<tr>
+<td><a href="#WifiApConfigDialog.__updateOk">__updateOk</a></td>
+<td>Private method to update the enabled state of the OK button.</td>
+</tr>
+<tr>
+<td><a href="#WifiApConfigDialog.getApConfig">getApConfig</a></td>
+<td>Public method to get the entered access point configuration data.</td>
+</tr>
+<tr>
+<td><a href="#WifiApConfigDialog.on_apShowPasswordButton_clicked">on_apShowPasswordButton_clicked</a></td>
+<td>Private slot to show or hide the WiFi Access Point password.</td>
+</tr>
+</table>
+<h3>Static Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+
+<a NAME="WifiApConfigDialog.__init__" ID="WifiApConfigDialog.__init__"></a>
+<h4>WifiApConfigDialog (Constructor)</h4>
+<b>WifiApConfigDialog</b>(<i>withIP, parent=None</i>)
+
+<p>
+        Constructor
+</p>
+<dl>
+
+<dt><i>withIP</i> (bool)</dt>
+<dd>
+flag indicating to ask the user for an IP configuration
+</dd>
+<dt><i>parent</i> (QWidget (optional))</dt>
+<dd>
+reference to the parent widget (defaults to None)
+</dd>
+</dl>
+<a NAME="WifiApConfigDialog.__updateOk" ID="WifiApConfigDialog.__updateOk"></a>
+<h4>WifiApConfigDialog.__updateOk</h4>
+<b>__updateOk</b>(<i></i>)
+
+<p>
+        Private method to update the enabled state of the OK button.
+</p>
+<a NAME="WifiApConfigDialog.getApConfig" ID="WifiApConfigDialog.getApConfig"></a>
+<h4>WifiApConfigDialog.getApConfig</h4>
+<b>getApConfig</b>(<i></i>)
+
+<p>
+        Public method to get the entered access point configuration data.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing the SSID, the password, the selected security mode
+            and a flag indicating to save the parameters to the settings
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (str, str, int, bool)
+</dd>
+</dl>
+<a NAME="WifiApConfigDialog.on_apShowPasswordButton_clicked" ID="WifiApConfigDialog.on_apShowPasswordButton_clicked"></a>
+<h4>WifiApConfigDialog.on_apShowPasswordButton_clicked</h4>
+<b>on_apShowPasswordButton_clicked</b>(<i>checked</i>)
+
+<p>
+        Private slot to show or hide the WiFi Access Point password.
+</p>
+<dl>
+
+<dt><i>checked</i> (bool)</dt>
+<dd>
+state of the button
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.MicroPython.WifiDialogs.WifiApStationsDialog.html	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.MicroPython.WifiDialogs.WifiApStationsDialog</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.MicroPython.WifiDialogs.WifiApStationsDialog</h1>
+
+<p>
+Module implementing a dialog showing the currently connected stations (clients).
+</p>
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+
+<tr>
+<td><a href="#WifiApStationsDialog">WifiApStationsDialog</a></td>
+<td>Class documentation goes here.</td>
+</tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<hr />
+<hr />
+<a NAME="WifiApStationsDialog" ID="WifiApStationsDialog"></a>
+<h2>WifiApStationsDialog</h2>
+
+<p>
+    Class documentation goes here.
+</p>
+<h3>Derived from</h3>
+QDialog, Ui_WifiApStationsDialog
+<h3>Class Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Class Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#WifiApStationsDialog.__init__">WifiApStationsDialog</a></td>
+<td>Constructor</td>
+</tr>
+</table>
+<h3>Static Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+
+<a NAME="WifiApStationsDialog.__init__" ID="WifiApStationsDialog.__init__"></a>
+<h4>WifiApStationsDialog (Constructor)</h4>
+<b>WifiApStationsDialog</b>(<i>stations, parent=None</i>)
+
+<p>
+        Constructor
+</p>
+<dl>
+
+<dt><i>stations</i></dt>
+<dd>
+list of connected stations. Each entry is a tuple containing the
+            station's MAC-Address and the RSSI (if supported and available)
+</dd>
+<dt><i>parent</i> (QWidget (optional))</dt>
+<dd>
+reference to the parent widget (defaults to None)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.MicroPython.WifiDialogs.WifiConnectionDialog.html	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,146 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.MicroPython.WifiDialogs.WifiConnectionDialog</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.MicroPython.WifiDialogs.WifiConnectionDialog</h1>
+
+<p>
+Module implementing a dialog to enter the parameters needed to connect to a WiFi
+network.
+</p>
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+
+<tr>
+<td><a href="#WifiConnectionDialog">WifiConnectionDialog</a></td>
+<td>Class implementing a dialog to enter the parameters needed to connect to a WiFi network.</td>
+</tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<hr />
+<hr />
+<a NAME="WifiConnectionDialog" ID="WifiConnectionDialog"></a>
+<h2>WifiConnectionDialog</h2>
+
+<p>
+    Class implementing a dialog to enter the parameters needed to connect to a WiFi
+    network.
+</p>
+<h3>Derived from</h3>
+QDialog, Ui_WifiConnectionDialog
+<h3>Class Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Class Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#WifiConnectionDialog.__init__">WifiConnectionDialog</a></td>
+<td>Constructor</td>
+</tr>
+<tr>
+<td><a href="#WifiConnectionDialog.getConnectionParameters">getConnectionParameters</a></td>
+<td>Public method to get the entered connection parameters.</td>
+</tr>
+<tr>
+<td><a href="#WifiConnectionDialog.on_showPasswordButton_clicked">on_showPasswordButton_clicked</a></td>
+<td>Private slot to show or hide the password.</td>
+</tr>
+<tr>
+<td><a href="#WifiConnectionDialog.on_ssidEdit_textChanged">on_ssidEdit_textChanged</a></td>
+<td>Private slot handling a change of the SSID.</td>
+</tr>
+</table>
+<h3>Static Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+
+<a NAME="WifiConnectionDialog.__init__" ID="WifiConnectionDialog.__init__"></a>
+<h4>WifiConnectionDialog (Constructor)</h4>
+<b>WifiConnectionDialog</b>(<i>parent=None</i>)
+
+<p>
+        Constructor
+</p>
+<dl>
+
+<dt><i>parent</i> (QWidget (optional))</dt>
+<dd>
+reference to the parent widget (defaults to None)
+</dd>
+</dl>
+<a NAME="WifiConnectionDialog.getConnectionParameters" ID="WifiConnectionDialog.getConnectionParameters"></a>
+<h4>WifiConnectionDialog.getConnectionParameters</h4>
+<b>getConnectionParameters</b>(<i></i>)
+
+<p>
+        Public method to get the entered connection parameters.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing the SSID, password and a flag indicating, if the
+            parameters shall be saved to the preferences
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (str, str, bool)
+</dd>
+</dl>
+<a NAME="WifiConnectionDialog.on_showPasswordButton_clicked" ID="WifiConnectionDialog.on_showPasswordButton_clicked"></a>
+<h4>WifiConnectionDialog.on_showPasswordButton_clicked</h4>
+<b>on_showPasswordButton_clicked</b>(<i>checked</i>)
+
+<p>
+        Private slot to show or hide the password.
+</p>
+<dl>
+
+<dt><i>checked</i> (bool)</dt>
+<dd>
+state of the button
+</dd>
+</dl>
+<a NAME="WifiConnectionDialog.on_ssidEdit_textChanged" ID="WifiConnectionDialog.on_ssidEdit_textChanged"></a>
+<h4>WifiConnectionDialog.on_ssidEdit_textChanged</h4>
+<b>on_ssidEdit_textChanged</b>(<i>ssid</i>)
+
+<p>
+        Private slot handling a change of the SSID.
+</p>
+<dl>
+
+<dt><i>ssid</i> (str)</dt>
+<dd>
+entered SSID
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.MicroPython.WifiDialogs.WifiController.html	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,274 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.MicroPython.WifiDialogs.WifiController</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.MicroPython.WifiDialogs.WifiController</h1>
+
+<p>
+Module implementing the WiFi related functionality.
+</p>
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+
+<tr>
+<td><a href="#WifiController">WifiController</a></td>
+<td>Class implementing the WiFi related functionality.</td>
+</tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<hr />
+<hr />
+<a NAME="WifiController" ID="WifiController"></a>
+<h2>WifiController</h2>
+
+<p>
+    Class implementing the WiFi related functionality.
+</p>
+<h3>Derived from</h3>
+QObject
+<h3>Class Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Class Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#WifiController.__init__">WifiController</a></td>
+<td>Constructor</td>
+</tr>
+<tr>
+<td><a href="#WifiController.__checkInternet">__checkInternet</a></td>
+<td>Private slot to check the availability of an internet connection.</td>
+</tr>
+<tr>
+<td><a href="#WifiController.__connectWifi">__connectWifi</a></td>
+<td>Private slot to connect the current device to a WiFi network.</td>
+</tr>
+<tr>
+<td><a href="#WifiController.__deactivateInterface">__deactivateInterface</a></td>
+<td>Private method to deactivate a given WiFi interface of the connected device.</td>
+</tr>
+<tr>
+<td><a href="#WifiController.__disconnectWifi">__disconnectWifi</a></td>
+<td>Private slot to disconnect the current device from the WiFi network.</td>
+</tr>
+<tr>
+<td><a href="#WifiController.__removeCredentials">__removeCredentials</a></td>
+<td>Private slot to remove the saved WiFi credentials from the connected device.</td>
+</tr>
+<tr>
+<td><a href="#WifiController.__scanNetwork">__scanNetwork</a></td>
+<td>Private slot to scan for visible WiFi networks.</td>
+</tr>
+<tr>
+<td><a href="#WifiController.__showConnectedClients">__showConnectedClients</a></td>
+<td>Private slot to show a list of WiFi clients connected to the Access Point interface.</td>
+</tr>
+<tr>
+<td><a href="#WifiController.__showWifiStatus">__showWifiStatus</a></td>
+<td>Private slot to show a dialog with the WiFi status of the current device.</td>
+</tr>
+<tr>
+<td><a href="#WifiController.__startAccessPoint">__startAccessPoint</a></td>
+<td>Private slot to start the Access Point interface of the connected device.</td>
+</tr>
+<tr>
+<td><a href="#WifiController.__startAccessPointIP">__startAccessPointIP</a></td>
+<td>Private slot to start the Access Point interface of the connected device with given IP parameters.</td>
+</tr>
+<tr>
+<td><a href="#WifiController.__stopAccessPoint">__stopAccessPoint</a></td>
+<td>Private slot to stop the Access Point interface of the connected device.</td>
+</tr>
+<tr>
+<td><a href="#WifiController.__writeCredentials">__writeCredentials</a></td>
+<td>Private slot to save the WiFi login credentials to the connected device.</td>
+</tr>
+<tr>
+<td><a href="#WifiController.createMenu">createMenu</a></td>
+<td>Public method to create the WiFi submenu.</td>
+</tr>
+</table>
+<h3>Static Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+
+<a NAME="WifiController.__init__" ID="WifiController.__init__"></a>
+<h4>WifiController (Constructor)</h4>
+<b>WifiController</b>(<i>microPython, parent=None</i>)
+
+<p>
+        Constructor
+</p>
+<dl>
+
+<dt><i>microPython</i> (MicroPythonWidgep)</dt>
+<dd>
+reference to the MicroPython widget
+</dd>
+<dt><i>parent</i> (QObject (optional))</dt>
+<dd>
+reference to the parent object (defaults to None)
+</dd>
+</dl>
+<a NAME="WifiController.__checkInternet" ID="WifiController.__checkInternet"></a>
+<h4>WifiController.__checkInternet</h4>
+<b>__checkInternet</b>(<i></i>)
+
+<p>
+        Private slot to check the availability of an internet connection.
+</p>
+<a NAME="WifiController.__connectWifi" ID="WifiController.__connectWifi"></a>
+<h4>WifiController.__connectWifi</h4>
+<b>__connectWifi</b>(<i></i>)
+
+<p>
+        Private slot to connect the current device to a WiFi network.
+</p>
+<a NAME="WifiController.__deactivateInterface" ID="WifiController.__deactivateInterface"></a>
+<h4>WifiController.__deactivateInterface</h4>
+<b>__deactivateInterface</b>(<i>interface</i>)
+
+<p>
+        Private method to deactivate a given WiFi interface of the connected device.
+</p>
+<dl>
+
+<dt><i>interface</i> (str)</dt>
+<dd>
+designation of the interface to be deactivated (one of 'AP'
+            or 'STA')
+</dd>
+</dl>
+<a NAME="WifiController.__disconnectWifi" ID="WifiController.__disconnectWifi"></a>
+<h4>WifiController.__disconnectWifi</h4>
+<b>__disconnectWifi</b>(<i></i>)
+
+<p>
+        Private slot to disconnect the current device from the WiFi network.
+</p>
+<a NAME="WifiController.__removeCredentials" ID="WifiController.__removeCredentials"></a>
+<h4>WifiController.__removeCredentials</h4>
+<b>__removeCredentials</b>(<i></i>)
+
+<p>
+        Private slot to remove the saved WiFi credentials from the connected device.
+</p>
+<p>
+        This will not remove the auto-connect part of the boot script. This needs to be
+        done manually if desired.
+</p>
+<a NAME="WifiController.__scanNetwork" ID="WifiController.__scanNetwork"></a>
+<h4>WifiController.__scanNetwork</h4>
+<b>__scanNetwork</b>(<i></i>)
+
+<p>
+        Private slot to scan for visible WiFi networks.
+</p>
+<a NAME="WifiController.__showConnectedClients" ID="WifiController.__showConnectedClients"></a>
+<h4>WifiController.__showConnectedClients</h4>
+<b>__showConnectedClients</b>(<i></i>)
+
+<p>
+        Private slot to show a list of WiFi clients connected to the Access Point
+        interface.
+</p>
+<a NAME="WifiController.__showWifiStatus" ID="WifiController.__showWifiStatus"></a>
+<h4>WifiController.__showWifiStatus</h4>
+<b>__showWifiStatus</b>(<i></i>)
+
+<p>
+        Private slot to show a dialog with the WiFi status of the current device.
+</p>
+<a NAME="WifiController.__startAccessPoint" ID="WifiController.__startAccessPoint"></a>
+<h4>WifiController.__startAccessPoint</h4>
+<b>__startAccessPoint</b>(<i>withIP=False</i>)
+
+<p>
+        Private slot to start the Access Point interface of the connected device.
+</p>
+<dl>
+
+<dt><i>withIP</i> (bool)</dt>
+<dd>
+flag indicating to start the access point with an IP configuration
+</dd>
+</dl>
+<a NAME="WifiController.__startAccessPointIP" ID="WifiController.__startAccessPointIP"></a>
+<h4>WifiController.__startAccessPointIP</h4>
+<b>__startAccessPointIP</b>(<i></i>)
+
+<p>
+        Private slot to start the Access Point interface of the connected device
+        with given IP parameters.
+</p>
+<a NAME="WifiController.__stopAccessPoint" ID="WifiController.__stopAccessPoint"></a>
+<h4>WifiController.__stopAccessPoint</h4>
+<b>__stopAccessPoint</b>(<i></i>)
+
+<p>
+        Private slot to stop the Access Point interface of the connected device.
+</p>
+<a NAME="WifiController.__writeCredentials" ID="WifiController.__writeCredentials"></a>
+<h4>WifiController.__writeCredentials</h4>
+<b>__writeCredentials</b>(<i></i>)
+
+<p>
+        Private slot to save the WiFi login credentials to the connected device.
+</p>
+<p>
+        This will also modify the boot script to perform an automatic WiFi connection.
+</p>
+<a NAME="WifiController.createMenu" ID="WifiController.createMenu"></a>
+<h4>WifiController.createMenu</h4>
+<b>createMenu</b>(<i>menu</i>)
+
+<p>
+        Public method to create the WiFi submenu.
+</p>
+<dl>
+
+<dt><i>menu</i> (QMenu)</dt>
+<dd>
+reference to the parent menu
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+reference to the created menu
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+QMenu
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.MicroPython.WifiDialogs.WifiCountryDialog.html	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,126 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.MicroPython.WifiDialogs.WifiCountryDialog</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.MicroPython.WifiDialogs.WifiCountryDialog</h1>
+
+<p>
+Module implementing a dialog to enter the country code for the WiFi interface.
+</p>
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+
+<tr>
+<td><a href="#WifiCountryDialog">WifiCountryDialog</a></td>
+<td>Class implementing a dialog to enter the country code for the WiFi interface.</td>
+</tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<hr />
+<hr />
+<a NAME="WifiCountryDialog" ID="WifiCountryDialog"></a>
+<h2>WifiCountryDialog</h2>
+
+<p>
+    Class implementing a dialog to enter the country code for the WiFi interface.
+</p>
+<h3>Derived from</h3>
+QDialog, Ui_WifiCountryDialog
+<h3>Class Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Class Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#WifiCountryDialog.__init__">WifiCountryDialog</a></td>
+<td>Constructor</td>
+</tr>
+<tr>
+<td><a href="#WifiCountryDialog.getCountry">getCountry</a></td>
+<td>Public method to get the entered country code.</td>
+</tr>
+<tr>
+<td><a href="#WifiCountryDialog.on_countryEdit_textChanged">on_countryEdit_textChanged</a></td>
+<td>Private slot handling a change of the country.</td>
+</tr>
+</table>
+<h3>Static Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+
+<a NAME="WifiCountryDialog.__init__" ID="WifiCountryDialog.__init__"></a>
+<h4>WifiCountryDialog (Constructor)</h4>
+<b>WifiCountryDialog</b>(<i>parent=None</i>)
+
+<p>
+        Constructor
+</p>
+<dl>
+
+<dt><i>parent</i> (QWidget (optional))</dt>
+<dd>
+reference to the parent widget (defaults to None)
+</dd>
+</dl>
+<a NAME="WifiCountryDialog.getCountry" ID="WifiCountryDialog.getCountry"></a>
+<h4>WifiCountryDialog.getCountry</h4>
+<b>getCountry</b>(<i></i>)
+
+<p>
+        Public method to get the entered country code.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing the country code and a flag indicating to save it to
+            the settings
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (str, bool)
+</dd>
+</dl>
+<a NAME="WifiCountryDialog.on_countryEdit_textChanged" ID="WifiCountryDialog.on_countryEdit_textChanged"></a>
+<h4>WifiCountryDialog.on_countryEdit_textChanged</h4>
+<b>on_countryEdit_textChanged</b>(<i>country</i>)
+
+<p>
+        Private slot handling a change of the country.
+</p>
+<dl>
+
+<dt><i>country</i> (str)</dt>
+<dd>
+entered country code
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.MicroPython.WifiDialogs.WifiNetworksWindow.html	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,175 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.MicroPython.WifiDialogs.WifiNetworksWindow</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.MicroPython.WifiDialogs.WifiNetworksWindow</h1>
+
+<p>
+Module implementing a dialog showing the available WiFi networks.
+</p>
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+
+<tr>
+<td><a href="#WifiNetworksWindow">WifiNetworksWindow</a></td>
+<td>Class implementing a dialog showing the available WiFi networks.</td>
+</tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<hr />
+<hr />
+<a NAME="WifiNetworksWindow" ID="WifiNetworksWindow"></a>
+<h2>WifiNetworksWindow</h2>
+
+<p>
+    Class implementing a dialog showing the available WiFi networks.
+</p>
+<h3>Derived from</h3>
+QWidget, Ui_WifiNetworksWindow
+<h3>Class Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Class Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#WifiNetworksWindow.__init__">WifiNetworksWindow</a></td>
+<td>Constructor</td>
+</tr>
+<tr>
+<td><a href="#WifiNetworksWindow.__resizeColumns">__resizeColumns</a></td>
+<td>Private method to resize the columns of the result list.</td>
+</tr>
+<tr>
+<td><a href="#WifiNetworksWindow.__resort">__resort</a></td>
+<td>Private method to resort the networks list.</td>
+</tr>
+<tr>
+<td><a href="#WifiNetworksWindow.closeEvent">closeEvent</a></td>
+<td>Protected method to handle a window close event.</td>
+</tr>
+<tr>
+<td><a href="#WifiNetworksWindow.on_intervalSpinBox_valueChanged">on_intervalSpinBox_valueChanged</a></td>
+<td>Private slot handling a change of the periodic scan interval.</td>
+</tr>
+<tr>
+<td><a href="#WifiNetworksWindow.on_periodicCheckBox_toggled">on_periodicCheckBox_toggled</a></td>
+<td>Private slot handling the selection of a periodic scan.</td>
+</tr>
+<tr>
+<td><a href="#WifiNetworksWindow.scanNetworks">scanNetworks</a></td>
+<td>Public method to ask the device for a network scan and display the result.</td>
+</tr>
+</table>
+<h3>Static Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+
+<a NAME="WifiNetworksWindow.__init__" ID="WifiNetworksWindow.__init__"></a>
+<h4>WifiNetworksWindow (Constructor)</h4>
+<b>WifiNetworksWindow</b>(<i>device, parent=None</i>)
+
+<p>
+        Constructor
+</p>
+<dl>
+
+<dt><i>device</i> (BaseDevice)</dt>
+<dd>
+reference to the connected device
+</dd>
+<dt><i>parent</i> (QWidget (optional))</dt>
+<dd>
+reference to the parent widget (defaults to None)
+</dd>
+</dl>
+<a NAME="WifiNetworksWindow.__resizeColumns" ID="WifiNetworksWindow.__resizeColumns"></a>
+<h4>WifiNetworksWindow.__resizeColumns</h4>
+<b>__resizeColumns</b>(<i></i>)
+
+<p>
+        Private method to resize the columns of the result list.
+</p>
+<a NAME="WifiNetworksWindow.__resort" ID="WifiNetworksWindow.__resort"></a>
+<h4>WifiNetworksWindow.__resort</h4>
+<b>__resort</b>(<i></i>)
+
+<p>
+        Private method to resort the networks list.
+</p>
+<a NAME="WifiNetworksWindow.closeEvent" ID="WifiNetworksWindow.closeEvent"></a>
+<h4>WifiNetworksWindow.closeEvent</h4>
+<b>closeEvent</b>(<i>evt</i>)
+
+<p>
+        Protected method to handle a window close event.
+</p>
+<dl>
+
+<dt><i>evt</i> (QCloseEvent)</dt>
+<dd>
+reference to the close event
+</dd>
+</dl>
+<a NAME="WifiNetworksWindow.on_intervalSpinBox_valueChanged" ID="WifiNetworksWindow.on_intervalSpinBox_valueChanged"></a>
+<h4>WifiNetworksWindow.on_intervalSpinBox_valueChanged</h4>
+<b>on_intervalSpinBox_valueChanged</b>(<i>interval</i>)
+
+<p>
+        Private slot handling a change of the periodic scan interval.
+</p>
+<dl>
+
+<dt><i>interval</i> (int)</dt>
+<dd>
+periodic scan interval
+</dd>
+</dl>
+<a NAME="WifiNetworksWindow.on_periodicCheckBox_toggled" ID="WifiNetworksWindow.on_periodicCheckBox_toggled"></a>
+<h4>WifiNetworksWindow.on_periodicCheckBox_toggled</h4>
+<b>on_periodicCheckBox_toggled</b>(<i>checked</i>)
+
+<p>
+        Private slot handling the selection of a periodic scan.
+</p>
+<dl>
+
+<dt><i>checked</i> (bool)</dt>
+<dd>
+flag indicating a periodic scan
+</dd>
+</dl>
+<a NAME="WifiNetworksWindow.scanNetworks" ID="WifiNetworksWindow.scanNetworks"></a>
+<h4>WifiNetworksWindow.scanNetworks</h4>
+<b>scanNetworks</b>(<i></i>)
+
+<p>
+        Public method to ask the device for a network scan and display the result.
+</p>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.MicroPython.WifiDialogs.WifiStatusDialog.html	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.MicroPython.WifiDialogs.WifiStatusDialog</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.MicroPython.WifiDialogs.WifiStatusDialog</h1>
+
+<p>
+Module implementing a dialog to show the WiFi status of the connected device.
+</p>
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+
+<tr>
+<td><a href="#WifiStatusDialog">WifiStatusDialog</a></td>
+<td>Class implementing a dialog to show the WiFi status of the connected device.</td>
+</tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<hr />
+<hr />
+<a NAME="WifiStatusDialog" ID="WifiStatusDialog"></a>
+<h2>WifiStatusDialog</h2>
+
+<p>
+    Class implementing a dialog to show the WiFi status of the connected device.
+</p>
+<h3>Derived from</h3>
+QDialog, Ui_WifiStatusDialog
+<h3>Class Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Class Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#WifiStatusDialog.__init__">WifiStatusDialog</a></td>
+<td>Constructor</td>
+</tr>
+<tr>
+<td><a href="#WifiStatusDialog.__createHeader">__createHeader</a></td>
+<td>Private method to create a header item.</td>
+</tr>
+</table>
+<h3>Static Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+
+<a NAME="WifiStatusDialog.__init__" ID="WifiStatusDialog.__init__"></a>
+<h4>WifiStatusDialog (Constructor)</h4>
+<b>WifiStatusDialog</b>(<i>clientStatus, apStatus, overallStatus, parent=None</i>)
+
+<p>
+        Constructor
+</p>
+<dl>
+
+<dt><i>clientStatus</i> (dict)</dt>
+<dd>
+dictionary containing the WiFi status data of the
+            client interface
+</dd>
+<dt><i>apStatus</i> (dict)</dt>
+<dd>
+dictionary containing the WiFi status data of the
+            access point interface
+</dd>
+<dt><i>overallStatus</i> (dict)</dt>
+<dd>
+dictionary containing the overall WiFi status data
+</dd>
+<dt><i>parent</i> (QWidget (optional))</dt>
+<dd>
+reference to the parent widget (defaults to None)
+</dd>
+</dl>
+<a NAME="WifiStatusDialog.__createHeader" ID="WifiStatusDialog.__createHeader"></a>
+<h4>WifiStatusDialog.__createHeader</h4>
+<b>__createHeader</b>(<i>headerText</i>)
+
+<p>
+        Private method to create a header item.
+</p>
+<dl>
+
+<dt><i>headerText</i> (str)</dt>
+<dd>
+text for the header item
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+reference to the created header item
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+QTreeWidgetItem
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
--- a/src/eric7/Documentation/Source/eric7.Preferences.ConfigurationPages.MicroPythonPage.html	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/Documentation/Source/eric7.Preferences.ConfigurationPages.MicroPythonPage.html	Sat Feb 25 19:47:23 2023 +0100
@@ -63,6 +63,14 @@
 <td>Constructor</td>
 </tr>
 <tr>
+<td><a href="#MicroPythonPage.on_apShowPasswordButton_clicked">on_apShowPasswordButton_clicked</a></td>
+<td>Private slot to show or hide the WiFi Access Point password.</td>
+</tr>
+<tr>
+<td><a href="#MicroPythonPage.on_showPasswordButton_clicked">on_showPasswordButton_clicked</a></td>
+<td>Private slot to show or hide the WiFi client password.</td>
+</tr>
+<tr>
 <td><a href="#MicroPythonPage.save">save</a></td>
 <td>Public slot to save the MicroPython configuration.</td>
 </tr>
@@ -87,6 +95,34 @@
 reference to the parent widget
 </dd>
 </dl>
+<a NAME="MicroPythonPage.on_apShowPasswordButton_clicked" ID="MicroPythonPage.on_apShowPasswordButton_clicked"></a>
+<h4>MicroPythonPage.on_apShowPasswordButton_clicked</h4>
+<b>on_apShowPasswordButton_clicked</b>(<i>checked</i>)
+
+<p>
+        Private slot to show or hide the WiFi Access Point password.
+</p>
+<dl>
+
+<dt><i>checked</i> (bool)</dt>
+<dd>
+state of the button
+</dd>
+</dl>
+<a NAME="MicroPythonPage.on_showPasswordButton_clicked" ID="MicroPythonPage.on_showPasswordButton_clicked"></a>
+<h4>MicroPythonPage.on_showPasswordButton_clicked</h4>
+<b>on_showPasswordButton_clicked</b>(<i>checked</i>)
+
+<p>
+        Private slot to show or hide the WiFi client password.
+</p>
+<dl>
+
+<dt><i>checked</i> (bool)</dt>
+<dd>
+state of the button
+</dd>
+</dl>
 <a NAME="MicroPythonPage.save" ID="MicroPythonPage.save"></a>
 <h4>MicroPythonPage.save</h4>
 <b>save</b>(<i></i>)
--- a/src/eric7/Documentation/Source/index-eric7.EricNetwork.html	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/Documentation/Source/index-eric7.EricNetwork.html	Sat Feb 25 19:47:23 2023 +0100
@@ -36,6 +36,10 @@
 <td>Module implementing some helpers for Google mail.</td>
 </tr>
 <tr>
+<td><a href="eric7.EricNetwork.EricIPv4InputWidget.html">EricIPv4InputWidget</a></td>
+<td>Module implementing a widget to enter an IPv4 address.</td>
+</tr>
+<tr>
 <td><a href="eric7.EricNetwork.EricJsonClient.html">EricJsonClient</a></td>
 <td>Module implementing the JSON based client base class.</td>
 </tr>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/index-eric7.MicroPython.Devices.MCUScripts.html	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.MicroPython.Devices.MCUScripts</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<h1>eric7.MicroPython.Devices.MCUScripts</h1>
+
+<p>
+Package containing scripts for copying to the micro controller board.
+</p>
+
+
+<h3>Modules</h3>
+<table>
+
+<tr>
+<td><a href="eric7.MicroPython.Devices.MCUScripts.esp32WiFiConnect.html">esp32WiFiConnect</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="eric7.MicroPython.Devices.MCUScripts.picowWiFiConnect.html">picowWiFiConnect</a></td>
+<td></td>
+</tr>
+</table>
+</body></html>
\ No newline at end of file
--- a/src/eric7/Documentation/Source/index-eric7.MicroPython.Devices.html	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/Documentation/Source/index-eric7.MicroPython.Devices.html	Sat Feb 25 19:47:23 2023 +0100
@@ -22,6 +22,10 @@
 <td><a href="index-eric7.MicroPython.Devices.EspDialogs.html">EspDialogs</a></td>
 <td>Package implementing dialogs used by the EspDevices module.</td>
 </tr>
+<tr>
+<td><a href="index-eric7.MicroPython.Devices.MCUScripts.html">MCUScripts</a></td>
+<td>Package containing scripts for copying to the micro controller board.</td>
+</tr>
 </table>
 
 <h3>Modules</h3>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/index-eric7.MicroPython.WifiDialogs.html	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.MicroPython.WifiDialogs</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<h1>eric7.MicroPython.WifiDialogs</h1>
+
+<p>
+Package implementing WiFi related dialogs.
+</p>
+
+
+<h3>Modules</h3>
+<table>
+
+<tr>
+<td><a href="eric7.MicroPython.WifiDialogs.WifiApConfigDialog.html">WifiApConfigDialog</a></td>
+<td>Module implementing a dialog to configure the Access Point interface.</td>
+</tr>
+<tr>
+<td><a href="eric7.MicroPython.WifiDialogs.WifiApStationsDialog.html">WifiApStationsDialog</a></td>
+<td>Module implementing a dialog showing the currently connected stations (clients).</td>
+</tr>
+<tr>
+<td><a href="eric7.MicroPython.WifiDialogs.WifiConnectionDialog.html">WifiConnectionDialog</a></td>
+<td>Module implementing a dialog to enter the parameters needed to connect to a WiFi network.</td>
+</tr>
+<tr>
+<td><a href="eric7.MicroPython.WifiDialogs.WifiController.html">WifiController</a></td>
+<td>Module implementing the WiFi related functionality.</td>
+</tr>
+<tr>
+<td><a href="eric7.MicroPython.WifiDialogs.WifiCountryDialog.html">WifiCountryDialog</a></td>
+<td>Module implementing a dialog to enter the country code for the WiFi interface.</td>
+</tr>
+<tr>
+<td><a href="eric7.MicroPython.WifiDialogs.WifiNetworksWindow.html">WifiNetworksWindow</a></td>
+<td>Module implementing a dialog showing the available WiFi networks.</td>
+</tr>
+<tr>
+<td><a href="eric7.MicroPython.WifiDialogs.WifiStatusDialog.html">WifiStatusDialog</a></td>
+<td>Module implementing a dialog to show the WiFi status of the connected device.</td>
+</tr>
+</table>
+</body></html>
\ No newline at end of file
--- a/src/eric7/Documentation/Source/index-eric7.MicroPython.html	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/Documentation/Source/index-eric7.MicroPython.html	Sat Feb 25 19:47:23 2023 +0100
@@ -18,6 +18,10 @@
 <td><a href="index-eric7.MicroPython.Devices.html">Devices</a></td>
 <td>Package containing the device interface modules and device specific dialogs.</td>
 </tr>
+<tr>
+<td><a href="index-eric7.MicroPython.WifiDialogs.html">WifiDialogs</a></td>
+<td>Package implementing WiFi related dialogs.</td>
+</tr>
 </table>
 
 <h3>Modules</h3>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/EricNetwork/EricIPv4InputWidget.py	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,186 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a widget to enter an IPv4 address.
+"""
+
+import ipaddress
+
+from PyQt6.QtCore import pyqtSignal, pyqtSlot, QRegularExpression, QEvent, Qt
+from PyQt6.QtGui import QRegularExpressionValidator
+from PyQt6.QtWidgets import QWidget
+
+from eric7.EricGui import EricPixmapCache
+
+from .Ui_EricIPv4InputWidget import Ui_EricIPv4InputWidget
+
+
+class EricIPv4InputWidget(QWidget, Ui_EricIPv4InputWidget):
+    """
+    Class implementing a widget to enter an IPv4 address.
+
+    @signal addressChanged() emitted to indicate a change of the entered IPv4 address
+    """
+    addressChanged = pyqtSignal()
+
+    def __init__(self, parent=None):
+        """
+        Constructor
+
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+        self.setupUi(self)
+
+        self.clearButton.setIcon(EricPixmapCache.getIcon("clearLeft"))
+        self.clearButton.clicked.connect(self.__clear)
+
+        ipRange = r"(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])"
+
+        self.ip1Edit.setValidator(
+            QRegularExpressionValidator(QRegularExpression(ipRange))
+        )
+        self.ip2Edit.setValidator(
+            QRegularExpressionValidator(QRegularExpression(ipRange))
+        )
+        self.ip3Edit.setValidator(
+            QRegularExpressionValidator(QRegularExpression(ipRange))
+        )
+        self.ip4Edit.setValidator(
+            QRegularExpressionValidator(QRegularExpression(ipRange))
+        )
+
+        self.ip1Edit.installEventFilter(self)
+        self.ip2Edit.installEventFilter(self)
+        self.ip3Edit.installEventFilter(self)
+
+        self.ip1Edit.textChanged.connect(self.addressChanged)
+        self.ip2Edit.textChanged.connect(self.addressChanged)
+        self.ip3Edit.textChanged.connect(self.addressChanged)
+        self.ip4Edit.textChanged.connect(self.addressChanged)
+
+    def eventFilter(self, obj, evt):
+        """
+        Public method to filter pressing '.' to give focus to the next input field.
+
+        @param obj reference to the object
+        @type QObject
+        @param evt reference to the event object
+        @type QEvent
+        """
+        if evt.type() == QEvent.Type.KeyPress:
+            if evt.text() == '.':
+                if obj is self.ip1Edit:
+                    nextWidget = self.ip2Edit
+                elif obj is self.ip2Edit:
+                    nextWidget = self.ip3Edit
+                elif obj is self.ip3Edit:
+                    nextWidget = self.ip4Edit
+                else:
+                    nextWidget = None
+                if nextWidget:
+                    nextWidget.setFocus(Qt.FocusReason.TabFocusReason)
+                    return True
+
+        return super().eventFilter(obj, evt)
+
+    def hasAcceptableInput(self):
+        """
+        Public method to check, if the input is acceptable.
+
+        @return flag indicating acceptable input
+        @rtype bool
+        """
+        try:
+            ipaddress.IPv4Address(self.text())
+        except ipaddress.AddressValueError:
+            # leading zeros are not allowed
+            return False
+
+        return (
+            self.ip1Edit.hasAcceptableInput()
+            and self.ip2Edit.hasAcceptableInput()
+            and self.ip3Edit.hasAcceptableInput()
+            and self.ip4Edit.hasAcceptableInput()
+        )
+
+    def text(self):
+        """
+        Public method to get the IPv4 address as a string.
+
+        @return IPv4 address
+        @rtype str
+        """
+        return "{0}.{1}.{2}.{3}".format(
+            self.ip1Edit.text(),
+            self.ip2Edit.text(),
+            self.ip3Edit.text(),
+            self.ip4Edit.text(),
+        )
+
+    def setText(self, address):
+        """
+        Public method to set the IPv4 address given a string.
+
+        @param address IPv4 address
+        @type str
+        """
+        if address:
+            try:
+                ipaddress.IPv4Address(address)
+            except ipaddress.AddressValueError as err:
+                raise ValueError(str(err))
+
+            addressParts = address.split(".")
+            self.ip1Edit.setText(addressParts[0])
+            self.ip2Edit.setText(addressParts[1])
+            self.ip3Edit.setText(addressParts[2])
+            self.ip4Edit.setText(addressParts[3])
+        else:
+            self.clear()
+
+    def address(self):
+        """
+        Public method to get the IPv4 address as an ipaddress.IPv4Address object.
+
+        @return IPv4 address
+        @rtype ipaddress.IPv4Address
+        """
+        try:
+            return ipaddress.IPv4Address(self.text())
+        except ipaddress.AddressValueError as err:
+            raise ValueError(str(err))
+
+    def setAddress(self, address):
+        """
+        Public method to set the IPv4 address given an ipaddress.IPv4Address object.
+
+        @param address IPv4 address
+        @type ipaddress.IPv4Address
+        """
+        if address:
+            self.setText(str(address))
+        else:
+            self.clear()
+
+    @pyqtSlot()
+    def clear(self):
+        """
+        Public slot to clear the input fields.
+        """
+        self.ip1Edit.clear()
+        self.ip2Edit.clear()
+        self.ip3Edit.clear()
+        self.ip4Edit.clear()
+
+    @pyqtSlot()
+    def __clear(self):
+        """
+        Private slot to handle the clear button press.
+        """
+        self.clear()
+        self.ip1Edit.setFocus(Qt.FocusReason.OtherFocusReason)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/EricNetwork/EricIPv4InputWidget.ui	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>EricIPv4InputWidget</class>
+ <widget class="QWidget" name="EricIPv4InputWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>283</width>
+    <height>26</height>
+   </rect>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout">
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
+   <item>
+    <widget class="QLineEdit" name="ip1Edit">
+     <property name="maximumSize">
+      <size>
+       <width>50</width>
+       <height>16777215</height>
+      </size>
+     </property>
+     <property name="maxLength">
+      <number>3</number>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignCenter</set>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string> . </string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLineEdit" name="ip2Edit">
+     <property name="maximumSize">
+      <size>
+       <width>50</width>
+       <height>16777215</height>
+      </size>
+     </property>
+     <property name="maxLength">
+      <number>3</number>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignCenter</set>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLabel" name="label_2">
+     <property name="text">
+      <string> . </string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLineEdit" name="ip3Edit">
+     <property name="maximumSize">
+      <size>
+       <width>50</width>
+       <height>16777215</height>
+      </size>
+     </property>
+     <property name="maxLength">
+      <number>3</number>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignCenter</set>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLabel" name="label_3">
+     <property name="text">
+      <string> . </string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLineEdit" name="ip4Edit">
+     <property name="maximumSize">
+      <size>
+       <width>50</width>
+       <height>16777215</height>
+      </size>
+     </property>
+     <property name="maxLength">
+      <number>3</number>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignCenter</set>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QToolButton" name="clearButton">
+     <property name="toolTip">
+      <string>Press to clear the entered IPv4 address</string>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
--- a/src/eric7/MicroPython/Devices/CircuitPythonDevices.py	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/MicroPython/Devices/CircuitPythonDevices.py	Sat Feb 25 19:47:23 2023 +0100
@@ -50,6 +50,8 @@
         """
         super().__init__(microPythonWidget, deviceType, parent)
 
+        self.submitMode = "paste"  # use 'paste' mode to avoid loosing state
+
         self.__boardName = boardName
         self.__workspace = self.__findWorkspace()
 
--- a/src/eric7/MicroPython/Devices/DeviceBase.py	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/MicroPython/Devices/DeviceBase.py	Sat Feb 25 19:47:23 2023 +0100
@@ -33,19 +33,19 @@
     the time on the board and getting board related data. Supported file system
     commands are:
     <ul>
-    <li>ls: directory listing</li>
+    <li>cd: change directory</li>
+    <li>fileSystemInfo: get information about the file system
+    <li>get: get a file from the connected device</li>
+    <li>getData: read data of a file of the connected device</li>
     <li>lls: directory listing with meta data</li>
-    <li>cd: change directory</li>
-    <li>pwd: get the current directory</li>
+    <li>ls: directory listing</li>
+    <li>mkdir: create a new directory</li>
     <li>put: copy a file to the connected device</li>
     <li>putData: write data to a file of the connected device</li>
-    <li>get: get a file from the connected device</li>
-    <li>getData: read data of a file of the connected device</li>
+    <li>pwd: get the current directory</li>
     <li>rm: remove a file from the connected device</li>
+    <li>rmdir: remove an empty directory</li>
     <li>rmrf: remove a file/directory recursively (like 'rm -rf' in bash)
-    <li>mkdir: create a new directory</li>
-    <li>rmdir: remove an empty directory</li>
-    <li>fileSystemInfo: get information about the file system
     </ul>
 
     Supported non file system commands are:
@@ -55,8 +55,25 @@
         information</li>
     <li>getModules: get a list of built-in modules</li>
     <li>getTime: get the current time</li>
+    <li>showTime: show the current time of the connected device</li>
     <li>syncTime: synchronize the time of the connected device</li>
-    <li>showTime: show the current time of the connected device</li>
+    </ul>
+
+    Supported WiFi commands are:
+    <ul>
+    <li>hasWifi: check, if the board has WiFi functionality</li>
+    <li>getWifiData: get WiFi status data</li>
+    <li>connectWifi: connect to a WiFi network</li>
+    <li>disconnectWifi: disconnect from a WiFi network</li>
+    <li>writeCredentials: save the WiFi credentials to the board and create
+        functionality to auto-connect at boot time</li>
+    <li>removeCredentials: remove the saved credentials</li>
+    <li>checkInternet: check, if internet access is possible</li>
+    <li>scanNetworks: scan for available WiFi networks</li>
+    <li>deactivateInterface: deactivate a WiFi interface</li>
+    <li>startAccessPoint: start an access point</li>
+    <li>stopAccessPoint: stop the access point</li>
+    <li>getConnectedClients: get a list of connected WiFi clients</li>
     </ul>
     """
 
@@ -78,6 +95,8 @@
         self.microPython = microPythonWidget
         self._deviceData = {}  # dictionary with essential device data
 
+        self.submitMode = "raw"  # default is 'raw' mode to submit commands
+
     def setConnected(self, connected):
         """
         Public method to set the connection state.
@@ -93,6 +112,9 @@
         if connected:
             with contextlib.suppress(OSError):
                 self._deviceData = self.__getDeviceData()
+                self._deviceData["wifi"], self._deviceData["wifi_type"] = self.hasWifi()
+                self._deviceData["bluetooth"] = self.hasBluetooth()
+                self._deviceData["ethernet"] = self.hasEthernet()
 
     def getDeviceType(self):
         """
@@ -103,14 +125,19 @@
         """
         return self._deviceType
 
-    def getDeviceData(self):
+    def getDeviceData(self, key=None):
         """
         Public method to get a copy of the determined device data.
 
+        @param key name of the data to get (None to get all data) (defaults to None)
+        @type str (optional)
         @return dictionary containing the essential device data
         @rtype dict
         """
-        return copy.deepcopy(self._deviceData)
+        if key is None:
+            return copy.deepcopy(self._deviceData)
+        else:
+            return self._deviceData[key]
 
     def checkDeviceData(self):
         """
@@ -294,6 +321,7 @@
             # user cancelled
             return ""
 
+    # TODO: add sending in 'paste' mode
     def sendCommands(self, commandsList):
         """
         Public method to send a list of commands to the device.
@@ -301,21 +329,25 @@
         @param commandsList list of commands to be sent to the device
         @type list of str
         """
-        rawOn = [  # sequence of commands to enter raw mode
-            b"\x02",  # Ctrl-B: exit raw repl (just in case)
-            b"\r\x03\x03\x03",  # Ctrl-C three times: interrupt any running
-            # program
-            b"\r\x01",  # Ctrl-A: enter raw REPL
-        ]
-        newLine = [
-            b'print("\\n")\r',
-        ]
-        commands = [c.encode("utf-8)") + b"\r" for c in commandsList]
-        commands.append(b"\r")
-        commands.append(b"\x04")
-        rawOff = [b"\x02", b"\x02"]
-        commandSequence = rawOn + newLine + commands + rawOff
-        self._interface.executeAsync(commandSequence)
+        if self.submitMode == "raw":
+            rawOn = [  # sequence of commands to enter raw mode
+                b"\x02",  # Ctrl-B: exit raw repl (just in case)
+                b"\r\x03\x03\x03",  # Ctrl-C three times: interrupt any running program
+                b"\r\x01",  # Ctrl-A: enter raw REPL
+            ]
+            newLine = [
+                b'print("\\n")\r',
+            ]
+            commands = [c.encode("utf-8)") + b"\r" for c in commandsList]
+            commands.append(b"\r")
+            commands.append(b"\x04")
+            rawOff = [b"\x02", b"\x02"]
+            commandSequence = rawOn + newLine + commands + rawOff
+            self._interface.executeAsync(commandSequence)
+        elif self.submitMode == "paste":
+            commands = b"\n".join([c.encode("utf-8)") for c in commandsList])
+            commandSequence = ["@PasteOn@", commands]
+            self._interface.executeAsyncPaste(commandSequence)
 
     @pyqtSlot()
     def handleDataFlood(self):
@@ -409,10 +441,6 @@
         """
         return []
 
-    ##################################################################
-    ## Methods below implement the file system commands
-    ##################################################################
-
     def _shortError(self, error):
         """
         Protected method to create a shortened error message.
@@ -431,6 +459,10 @@
 
         return self.tr("Detected an error without indications.")
 
+    ##################################################################
+    ## Methods below implement the file system commands
+    ##################################################################
+
     def ls(self, dirname=""):
         """
         Public method to get a directory listing of the connected device.
@@ -448,7 +480,7 @@
 """.format(
             dirname
         )
-        out, err = self._interface.execute(command)
+        out, err = self._interface.execute(command, mode=self.submitMode)
         if err:
             raise OSError(self._shortError(err))
         return ast.literal_eval(out.decode("utf-8"))
@@ -500,7 +532,7 @@
 """.format(
             dirname, showHidden
         )
-        out, err = self._interface.execute(command)
+        out, err = self._interface.execute(command, mode=self.submitMode)
         if err:
             raise OSError(self._shortError(err))
         fileslist = ast.literal_eval(out.decode("utf-8"))
@@ -528,7 +560,7 @@
 """.format(
                 dirname
             )
-            out, err = self._interface.execute(command)
+            out, err = self._interface.execute(command, mode=self.submitMode)
             if err:
                 raise OSError(self._shortError(err))
 
@@ -545,7 +577,7 @@
 print(__os_.getcwd())
 del __os_
 """
-        out, err = self._interface.execute(command)
+        out, err = self._interface.execute(command, mode=self.submitMode)
         if err:
             raise OSError(self._shortError(err))
         return out.decode("utf-8").strip()
@@ -561,12 +593,16 @@
         if filename:
             command = """
 import os as __os_
-__os_.remove('{0}')
+try:
+    __os_.remove('{0}')
+except OSError as err:
+    if err.errno != 2:
+        raise err
 del __os_
 """.format(
                 filename
             )
-            out, err = self._interface.execute(command)
+            out, err = self._interface.execute(command, mode=self.submitMode)
             if err:
                 raise OSError(self._shortError(err))
 
@@ -613,7 +649,7 @@
 """.format(
                 name, recursive, force
             )
-            out, err = self._interface.execute(command)
+            out, err = self._interface.execute(command, mode=self.submitMode)
             if err:
                 raise OSError(self._shortError(err))
             return ast.literal_eval(out.decode("utf-8"))
@@ -636,7 +672,7 @@
 """.format(
                 dirname
             )
-            out, err = self._interface.execute(command)
+            out, err = self._interface.execute(command, mode=self.submitMode)
             if err:
                 raise OSError(self._shortError(err))
 
@@ -663,7 +699,7 @@
 """.format(
                 dirname
             )
-            out, err = self._interface.execute(command)
+            out, err = self._interface.execute(command, mode=self.submitMode)
             if err:
                 raise OSError(self._shortError(err))
 
@@ -725,7 +761,7 @@
         )
         command = "\n".join(commands)
 
-        out, err = self._interface.execute(command)
+        out, err = self._interface.execute(command, mode=self.submitMode)
         if err:
             raise OSError(self._shortError(err))
         return True
@@ -794,7 +830,7 @@
 """.format(
             deviceFileName
         )
-        out, err = self._interface.execute(command)
+        out, err = self._interface.execute(command, mode=self.submitMode)
         if err:
             raise OSError(self._shortError(err))
 
@@ -833,7 +869,7 @@
 print(fsinfo())
 del __os_, fsinfo
 """
-        out, err = self._interface.execute(command)
+        out, err = self._interface.execute(command, mode=self.submitMode)
         if err:
             raise OSError(self._shortError(err))
         infolist = ast.literal_eval(out.decode("utf-8"))
@@ -906,7 +942,7 @@
 print(res)
 del res, uname, __os_, __sys_
 """
-        out, err = self._interface.execute(command)
+        out, err = self._interface.execute(command, mode=self.submitMode)
         if err:
             raise OSError(self._shortError(err))
         return ast.literal_eval(out.decode("utf-8"))
@@ -1013,9 +1049,9 @@
     res['ulab'] = None
 
 print(res)
-del res, __os_, __sys_
+del res, __os_, __sys_, uname
 """
-        out, err = self._interface.execute(command)
+        out, err = self._interface.execute(command, mode=self.submitMode)
         if err:
             raise OSError(self._shortError(err))
         return ast.literal_eval(out.decode("utf-8"))
@@ -1029,7 +1065,7 @@
         @exception OSError raised to indicate an issue with the device
         """
         commands = ["help('modules')"]
-        out, err = self._interface.execute(commands)
+        out, err = self._interface.execute(commands, mode=self.submitMode)
         if err:
             raise OSError(self._shortError(err))
 
@@ -1071,7 +1107,7 @@
         del tm
     del __time_
 """
-        out, err = self._interface.execute(command)
+        out, err = self._interface.execute(command, mode=self.submitMode)
         if err:
             if b"NotImplementedError" in err:
                 return "&lt;unsupported&gt; &lt;unsupported&gt;"
@@ -1143,10 +1179,182 @@
                     now.tm_isdst,
                 ),
             )
-            out, err = self._interface.execute(command)
+            out, err = self._interface.execute(command, mode=self.submitMode)
             if err:
                 raise OSError(self._shortError(err))
 
+    ##################################################################
+    ## Methods below implement WiFi related methods
+    ##################################################################
+
+    def hasWifi(self):
+        """
+        Public method to check the availability of WiFi.
+
+        @return tuple containing a flag indicating the availability of WiFi
+            and the WiFi type (picow or pimoroni)
+        @rtype tuple of (bool, str)
+        """
+        return False, ""
+
+    def addDeviceWifiEntries(self, menu):
+        """
+        Public method to add device specific entries to the given menu.
+
+        @param menu reference to the context menu
+        @type QMenu
+        """
+        pass
+
+    def getWifiData(self):
+        """
+        Public method to get data related to the current WiFi status.
+
+        @return tuple of three dictionaries containing the WiFi status data
+            for the WiFi client, access point and overall data
+        @rtype tuple of (dict, dict, dict)
+        """
+        return {}, {}, {}
+
+    def connectWifi(self, ssid, password):
+        """
+        Public method to connect a device to a WiFi network.
+
+        @param ssid name (SSID) of the WiFi network
+        @type str
+        @param password password needed to connect
+        @type str
+        @return tuple containing the connection status and an error string
+        @rtype tuple of (bool, str)
+        """
+        return False, self.tr("Operation not supported.")
+
+    def disconnectWifi(self):
+        """
+        Public method to disconnect a device from the WiFi network.
+
+        @return tuple containing a flag indicating success and an error string
+        @rtype tuple of (bool, str)
+        """
+        return True, ""
+
+    def writeCredentials(self, ssid, password):
+        """
+        Public method to write the given credentials to the connected device and modify
+        the start script to connect automatically.
+
+        @param ssid SSID of the network to connect to
+        @type str
+        @param password password needed to authenticate
+        @type str
+        @return tuple containing a flag indicating success and an error message
+        @rtype tuple of (bool, str)
+        """
+        return False, ""
+
+    def removeCredentials(self):
+        """
+        Public method to remove the saved credentials from the connected device.
+
+        @return tuple containing a flag indicating success and an error message
+        @rtype tuple of (bool, str)
+        """
+        return False, ""
+
+    def checkInternet(self):
+        """
+        Public method to check, if the internet can be reached.
+
+        @return tuple containing a flag indicating reachability and an error string
+        @rtype tuple of (bool, str)
+        """
+        return False, ""
+
+    def scanNetworks(self):
+        """
+        Public method to scan for available WiFi networks.
+
+        @return tuple containing the list of available networks as a tuple of 'Name',
+            'MAC-Address', 'channel', 'RSSI' and 'security' and an error string
+        @rtype tuple of (list of tuple of (str, str, int, int, str), str)
+        """
+        return [], ""
+
+    def deactivateInterface(self, interface):
+        """
+        Public method to deactivate a given WiFi interface of the connected device.
+
+        @param interface designation of the interface to be deactivated (one of 'AP'
+            or 'STA')
+        @type str
+        @return tuple containg a flag indicating success and an error message
+        @rtype tuple of (bool, str)
+        """
+        return True, ""
+
+    def startAccessPoint(self, ssid, security=None, password=None, ifconfig=None):
+        """
+        Public method to start the access point interface.
+
+        @param ssid SSID of the access point
+        @type str
+        @param security security method (defaults to None)
+        @type int (optional)
+        @param password password (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)
+        @return tuple containing a flag indicating success and an error message
+        @rtype tuple of (bool, str)
+        """
+        return False, ""
+
+    def stopAccessPoint(self):
+        """
+        Public method to stop the access point interface.
+
+        @return tuple containg a flag indicating success and an error message
+        @rtype tuple of (bool, str)
+        """
+        return True, ""
+
+    def getConnectedClients(self):
+        """
+        Public method to get a list of connected clients.
+
+        @return a tuple containing a list of tuples containing the client MAC-Address
+            and the RSSI (if supported and available) and an error message
+        @rtype tuple of ([(bytes, int)], str)
+        """
+        return [], ""
+
+    ##################################################################
+    ## Methods below implement Ethernet related methods
+    ##################################################################
+
+    def hasEthernet(self):
+        """
+        Public method to check the availability of Ethernet.
+
+        @return flag indicating the availability of Ethernet
+        @rtype bool
+        """
+        return False
+
+    ##################################################################
+    ## Methods below implement Bluetooth related methods
+    ##################################################################
+
+    def hasBluetooth(self):
+        """
+        Public method to check the availability of Bluetooth.
+
+        @return flag indicating the availability of Bluetooth
+        @rtype bool
+        """
+        return False
+
 
 #
 # eflag: noqa = M613
--- a/src/eric7/MicroPython/Devices/EspDevices.py	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/MicroPython/Devices/EspDevices.py	Sat Feb 25 19:47:23 2023 +0100
@@ -8,11 +8,17 @@
 boards.
 """
 
+import ast
+import binascii
+import json
+import os
+
 from PyQt6.QtCore import QProcess, QUrl, pyqtSlot
 from PyQt6.QtNetwork import QNetworkRequest
 from PyQt6.QtWidgets import QDialog, QMenu
 
 from eric7 import Globals, Preferences
+from eric7.EricGui.EricOverrideCursor import EricOverrideCursor
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 from eric7.EricWidgets.EricProcessDialog import EricProcessDialog
@@ -43,6 +49,27 @@
 
         self.__createEsp32Submenu()
 
+        self.__statusTranslations = {
+            200: self.tr("beacon timeout"),
+            201: self.tr("no matching access point found"),
+            202: self.tr("authentication failed"),
+            203: self.tr("association failed"),
+            204: self.tr("handshake timeout"),
+            1000: self.tr("idle"),
+            1001: self.tr("connecting"),
+            1010: self.tr("connected"),
+        }
+        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",
+        }
+
     def setButtons(self):
         """
         Public method to enable the supported action buttons.
@@ -619,6 +646,473 @@
         rtc.init(clock_time)
 """
 
+    ##################################################################
+    ## Methods below implement WiFi related methods
+    ##################################################################
+
+    def hasWifi(self):
+        """
+        Public method to check the availability of WiFi.
+
+        @return tuple containing a flag indicating the availability of WiFi
+            and the WiFi type (esp32)
+        @rtype tuple of (bool, str)
+        """
+        # TODO: check if ESP8266 is different
+        return True, "esp32"
+
+    def getWifiData(self):
+        """
+        Public method to get data related to the current WiFi status.
+
+        @return tuple of three dictionaries containing the WiFi status data
+            for the WiFi client, access point and overall data
+        @rtype tuple of (dict, dict, dict)
+        @exception OSError raised to indicate an issue with the device
+        """
+        command = """
+def wifi_status():
+    import ubinascii
+    import ujson
+    import network
+
+    wifi = network.WLAN(network.STA_IF)
+    station = {
+        'active': wifi.active(),
+        'connected': wifi.isconnected(),
+        'status': wifi.status(),
+        'ifconfig': wifi.ifconfig(),
+        'mac': ubinascii.hexlify(wifi.config('mac'), ':').decode(),
+    }
+    if wifi.active():
+        try:
+            station['txpower'] = wifi.config('txpower')
+        except ValueError:
+            pass
+    print(ujson.dumps(station))
+
+    wifi = network.WLAN(network.AP_IF)
+    ap = {
+        'active': wifi.active(),
+        'connected': wifi.isconnected(),
+        'status': wifi.status(),
+        'ifconfig': wifi.ifconfig(),
+        'mac': ubinascii.hexlify(wifi.config('mac'), ':').decode(),
+        'channel': wifi.config('channel'),
+        'essid': wifi.config('essid'),
+    }
+    if wifi.active():
+        try:
+            ap['txpower'] = wifi.config('txpower')
+        except ValueError:
+            pass
+    print(ujson.dumps(ap))
+
+    overall = {
+        'active': station['active'] or ap['active']
+    }
+    print(ujson.dumps(overall))
+
+wifi_status()
+del wifi_status
+"""
+
+        out, err = self._interface.execute(command, mode=self.submitMode)
+        if err:
+            raise OSError(self._shortError(err))
+
+        stationStr, apStr, overallStr = out.decode("utf-8").splitlines()
+        station = json.loads(stationStr)
+        ap = json.loads(apStr)
+        overall = json.loads(overallStr)
+        try:
+            station["status"] = self.__statusTranslations[station["status"]]
+        except KeyError:
+            station["status"] = str(station["status"])
+        try:
+            ap["status"] = self.__statusTranslations[ap["status"]]
+        except KeyError:
+            ap["status"] = str(ap["status"])
+        return station, ap, overall
+
+    def connectWifi(self, ssid, password):
+        """
+        Public method to connect a device to a WiFi network.
+
+        @param ssid name (SSID) of the WiFi network
+        @type str
+        @param password password needed to connect
+        @type str
+        @return tuple containing the connection status and an error string
+        @rtype tuple of (bool, str)
+        """
+        command = """
+def connect_wifi(ssid, password):
+    import network
+    import ujson
+    from time import sleep
+
+    wifi = network.WLAN(network.STA_IF)
+    wifi.active(False)
+    wifi.active(True)
+    wifi.connect(ssid, password)
+    max_wait = 140
+    while max_wait and wifi.status() == network.STAT_CONNECTING:
+        max_wait -= 1
+        sleep(0.1)
+    status = wifi.status()
+    print(ujson.dumps({{'connected': wifi.isconnected(), 'status': status}}))
+
+connect_wifi({0}, {1})
+del connect_wifi
+""".format(
+            repr(ssid),
+            repr(password if password else ""),
+        )
+
+        with EricOverrideCursor():
+            out, err = self._interface.execute(
+                command, mode=self.submitMode, timeout=15000
+            )
+        if err:
+            return False, err
+
+        result = json.loads(out.decode("utf-8").strip())
+        if result["connected"]:
+            error = ""
+        else:
+            try:
+                error = self.__statusTranslations[result["status"]]
+            except KeyError:
+                error = str(result["status"])
+
+        return result["connected"], error
+
+    def disconnectWifi(self):
+        """
+        Public method to disconnect a device from the WiFi network.
+
+        @return tuple containing a flag indicating success and an error string
+        @rtype tuple of (bool, str)
+        """
+        command = """
+def disconnect_wifi():
+    import network
+    from time import sleep
+
+    wifi = network.WLAN(network.STA_IF)
+    wifi.disconnect()
+    wifi.active(False)
+    sleep(0.1)
+    print(not wifi.isconnected())
+
+disconnect_wifi()
+del disconnect_wifi
+"""
+
+        out, err = self._interface.execute(command, mode=self.submitMode)
+        if err:
+            return False, err
+
+        return out.decode("utf-8").strip() == "True", ""
+
+    def writeCredentials(self, ssid, password):
+        """
+        Public method to write the given credentials to the connected device and modify
+        the start script to connect automatically.
+
+        @param ssid SSID of the network to connect to
+        @type str
+        @param password password needed to authenticate
+        @type str
+        @return tuple containing a flag indicating success and an error message
+        @rtype tuple of (bool, str)
+        """
+        nvsCommand = """
+def save_wifi_creds(ssid, password):
+    import esp32
+
+    nvs = esp32.NVS('wifi_creds')
+    nvs.set_blob('ssid', ssid)
+    nvs.set_blob('password', password)
+    nvs.commit()
+
+save_wifi_creds({0}, {1})
+del save_wifi_creds
+""".format(
+            repr(ssid), repr(password) if password else "''"
+        )
+        bootCommand = """
+def modify_boot():
+    add = True
+    try:
+        with open('/boot.py', 'r') as f:
+            for ln in f.readlines():
+                if 'wifi_connect' in ln:
+                    add = False
+                    break
+    except:
+        pass
+    if add:
+        with open('/boot.py', 'a') as f:
+            f.write('\\nimport wifi_connect\\n')
+    print(True)
+
+modify_boot()
+del modify_boot
+"""
+
+        out, err = self._interface.execute(nvsCommand, mode=self.submitMode)
+        if err:
+            return False, self.tr("Error saving credentials: {0}").format(err)
+
+        try:
+            # copy auto-connect file
+            self.put(
+                os.path.join(
+                    os.path.dirname(__file__), "MCUScripts", "esp32WiFiConnect.py"
+                ),
+                "/wifi_connect.py",
+            )
+        except OSError as err:
+            return False, self.tr("Error saving auto-connect script: {0}").format(err)
+
+        out, err = self._interface.execute(bootCommand, mode=self.submitMode)
+        if err:
+            return False, self.tr("Error modifying 'boot.py': {0}").format(err)
+
+        return True, ""
+
+    def removeCredentials(self):
+        """
+        Public method to remove the saved credentials from the connected device.
+
+        @return tuple containing a flag indicating success and an error message
+        @rtype tuple of (bool, str)
+        """
+        nvsCommand = """
+def delete_wifi_creds():
+    import esp32
+
+    nvs = esp32.NVS('wifi_creds')
+    try:
+        nvs.erase_key('ssid')
+        nvs.erase_key('password')
+        nvs.commit()
+    except OSError:
+        pass
+
+delete_wifi_creds()
+del delete_wifi_creds
+"""
+
+        out, err = self._interface.execute(nvsCommand, mode=self.submitMode)
+        if err:
+            return False, self.tr("Error deleting credentials: {0}").format(err)
+
+        return True, ""
+
+    def checkInternet(self):
+        """
+        Public method to check, if the internet can be reached.
+
+        @return tuple containing a flag indicating reachability and an error string
+        @rtype tuple of (bool, str)
+        """
+        command = """
+def check_internet():
+    import network
+    import socket
+
+    wifi = network.WLAN(network.STA_IF)
+    if wifi.isconnected():
+        s = socket.socket()
+        try:
+            s.connect(socket.getaddrinfo('google.com', 80)[0][-1])
+            s.close()
+            print(True)
+        except:
+            print(False)
+    else:
+        print(False)
+
+check_internet()
+del check_internet
+"""
+
+        out, err = self._interface.execute(command, mode=self.submitMode)
+        if err:
+            return False, err
+
+        return out.decode("utf-8").strip() == "True", ""
+
+    def scanNetworks(self):
+        """
+        Public method to scan for available WiFi networks.
+
+        @return tuple containing the list of available networks as a tuple of 'Name',
+            'MAC-Address', 'channel', 'RSSI' and 'security' and an error string
+        @rtype tuple of (list of tuple of (str, str, int, int, str), str)
+        """
+        command = """
+def scan_networks():
+    import network
+
+    wifi = network.WLAN(network.STA_IF)
+    active = wifi.active()
+    if not active:
+        wifi.active(True)
+    network_list = wifi.scan()
+    if not active:
+        wifi.active(False)
+    print(network_list)
+
+scan_networks()
+del scan_networks
+"""
+
+        out, err = self._interface.execute(command, mode=self.submitMode, timeout=15000)
+        if err:
+            return [], err
+
+        networksList = ast.literal_eval(out.decode("utf-8"))
+        networks = []
+        for network in networksList:
+            if network[0]:
+                ssid = network[0].decode("utf-8")
+                mac = binascii.hexlify(network[1], ":").decode("utf-8")
+                channel = network[2]
+                rssi = network[3]
+                try:
+                    security = self.__securityTranslations[network[4]]
+                except KeyError:
+                    security = self.tr("unknown ({0})").format(network[4])
+                networks.append((ssid, mac, channel, rssi, security))
+
+        return networks, ""
+
+    def deactivateInterface(self, interface):
+        """
+        Public method to deactivate a given WiFi interface of the connected device.
+
+        @param interface designation of the interface to be deactivated (one of 'AP'
+            or 'STA')
+        @type str
+        @return tuple containg a flag indicating success and an error message
+        @rtype tuple of (bool, str)
+        @exception ValueError raised to indicate a wrong value for the interface type
+        """
+        if interface not in ("STA", "AP"):
+            raise ValueError(
+                "interface must be 'AP' or 'STA', got '{0}'".format(interface)
+            )
+
+        command = """
+def deactivate():
+    import network
+    from time import sleep
+
+    wifi = network.WLAN(network.{0}_IF)
+    wifi.active(False)
+    sleep(0.1)
+    print(not wifi.active())
+
+deactivate()
+del deactivate
+""".format(
+            interface
+        )
+
+        out, err = self._interface.execute(command, mode=self.submitMode)
+        if err:
+            return False, err
+        else:
+            return out.decode("utf-8").strip() == "True", ""
+
+    def startAccessPoint(self, ssid, security=None, password=None, ifconfig=None):
+        """
+        Public method to start the access point interface.
+
+        @param ssid SSID of the access point
+        @type str
+        @param security security method (defaults to None)
+        @type int (optional)
+        @param password password (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)
+        @return tuple containing a flag indicating success and an error message
+        @rtype tuple of (bool, str)
+        """
+        if security is None or password is None:
+            security = 0
+            password = ""
+        if security > 4:
+            security = 4  # security >4 cause an error thrown by the ESP32
+
+        command = """
+def start_ap(ssid, authmode, password, ifconfig):
+    import network
+
+    ap = network.WLAN(network.AP_IF)
+    ap.active(False)
+    if ifconfig:
+        ap.ifconfig(ifconfig)
+    ap.active(True)
+    try:
+        ap.config(ssid=ssid, authmode=authmode, password=password)
+    except:
+        ap.config(essid=ssid, authmode=authmode, password=password)
+
+start_ap({0}, {1}, {2}, {3})
+del start_ap
+""".format(
+            repr(ssid), security, repr(password), ifconfig
+        )
+
+        out, err = self._interface.execute(command, mode=self.submitMode, timeout=15000)
+        if err:
+            return False, err
+        else:
+            return True, ""
+
+    def stopAccessPoint(self):
+        """
+        Public method to stop the access point interface.
+
+        @return tuple containg a flag indicating success and an error message
+        @rtype tuple of (bool, str)
+        """
+        return self.deactivateInterface("AP")
+
+    def getConnectedClients(self):
+        """
+        Public method to get a list of connected clients.
+
+        @return a tuple containing a list of tuples containing the client MAC-Address
+            and the RSSI (if supported and available) and an error message
+        @rtype tuple of ([(bytes, int)], str)
+        """
+        command = """
+def get_stations():
+    import network
+
+    ap = network.WLAN(network.AP_IF)
+    stations = ap.status('stations')
+    print(stations)
+
+get_stations()
+del get_stations
+"""
+
+        out, err = self._interface.execute(command, mode=self.submitMode, timeout=10000)
+        if err:
+            return [], err
+
+        clientsList = ast.literal_eval(out.decode("utf-8"))
+        return clientsList, ""
+
 
 def createDevice(microPythonWidget, deviceType, vid, pid, boardName, serialNumber):
     """
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/Devices/MCUScripts/__init__.py	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Package containing scripts for copying to the micro controller board.
+"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/Devices/MCUScripts/esp32WiFiConnect.py	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,27 @@
+def connectWiFi():
+    import esp32
+    import network
+    from time import sleep
+
+    try:
+        nvs = esp32.NVS("wifi_creds")
+        buf = bytearray(1024)
+        size = nvs.get_blob("ssid", buf)
+        ssid = buf[:size].decode()
+        size = nvs.get_blob("password", buf)
+        password = buf[:size].decode()
+
+        wifi = network.WLAN(network.STA_IF)
+        wifi.active(False)
+        wifi.active(True)
+        wifi.connect(ssid, password)
+        max_wait = 140
+        print("Connecting WiFi to '{0}'...".format(ssid))
+        while max_wait and wifi.status() == network.STAT_CONNECTING:
+            max_wait -= 1
+            sleep(0.1)
+        print("Connection status:", wifi.isconnected())
+    except:
+        pass
+
+connectWiFi()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/Devices/MCUScripts/picowWiFiConnect.py	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,30 @@
+try:
+    import secrets
+
+    def connectWiFi():
+        import network
+        import rp2
+        from time import sleep
+
+        country = secrets.WIFI_COUNTRY
+        if country:
+            rp2.country(country)
+
+        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:
+    pass
--- a/src/eric7/MicroPython/Devices/MicrobitDevices.py	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/MicroPython/Devices/MicrobitDevices.py	Sat Feb 25 19:47:23 2023 +0100
@@ -601,7 +601,7 @@
 print(__os_.listdir())
 del __os_
 """
-            out, err = self._interface.execute(command)
+            out, err = self._interface.execute(command, mode=self.submitMode)
             if err:
                 raise OSError(self._shortError(err))
             return ast.literal_eval(out.decode("utf-8"))
@@ -649,7 +649,7 @@
 """.format(
                 showHidden
             )
-            out, err = self._interface.execute(command)
+            out, err = self._interface.execute(command, mode=self.submitMode)
             if err:
                 raise OSError(self._shortError(err))
             fileslist = ast.literal_eval(out.decode("utf-8"))
--- a/src/eric7/MicroPython/Devices/RP2040Devices.py	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/MicroPython/Devices/RP2040Devices.py	Sat Feb 25 19:47:23 2023 +0100
@@ -8,11 +8,17 @@
 (e.g. Raspberry Pi Pico).
 """
 
+import ast
+import binascii
+import json
+import os
+
 from PyQt6.QtCore import QUrl, pyqtSlot
 from PyQt6.QtNetwork import QNetworkRequest
-from PyQt6.QtWidgets import QMenu
+from PyQt6.QtWidgets import QDialog, QMenu
 
 from eric7 import Globals, Preferences
+from eric7.EricGui.EricOverrideCursor import EricOverrideCursor
 from eric7.EricWidgets import EricMessageBox
 from eric7.EricWidgets.EricApplication import ericApp
 
@@ -41,6 +47,31 @@
 
         self.__createRP2040Menu()
 
+        self.__statusTranslations = {
+            "picow": {
+                -3: self.tr("authentication failed"),
+                -2: self.tr("no matching access point found"),
+                -1: self.tr("connection failed"),
+                0: self.tr("idle"),
+                1: self.tr("connecting"),
+                2: self.tr("connected, waiting for IP address"),
+                3: self.tr("connected"),
+            },
+            "pimoroni": {
+                # TODO: not yet implemented
+            },
+        }
+        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",
+        }
+
     def setButtons(self):
         """
         Public method to enable the supported action buttons.
@@ -339,6 +370,596 @@
     rtc.datetime(rtc_time[:7] + (0,))
 """
 
+    ##################################################################
+    ## 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
+        """
+        menu.addSeparator()
+        menu.addAction(self.tr("Set Country"), self.__setCountry).setEnabled(
+            self._deviceData["wifi_type"] == "picow"
+        )
+
+    def hasWifi(self):
+        """
+        Public method to check the availability of WiFi.
+
+        @return tuple containing a flag indicating the availability of WiFi
+            and the WiFi type (picow or pimoroni)
+        @rtype tuple of (bool, str)
+        @exception OSError raised to indicate an issue with the device
+        """
+        command = """
+def has_wifi():
+    try:
+        import network
+        if hasattr(network, 'WLAN'):
+            return True, 'picow'
+    except ImportError:
+        try:
+            import picowireless
+            if picowireless.get_fw_version() != '':
+                return True, 'pimoroni'
+        except ImportError:
+            pass
+
+    return False, ''
+
+print(has_wifi())
+del has_wifi
+"""
+        out, err = self._interface.execute(command, mode=self.submitMode, timeout=10000)
+        if err:
+            raise OSError(self._shortError(err))
+        return ast.literal_eval(out.decode("utf-8"))
+
+    def getWifiData(self):
+        """
+        Public method to get data related to the current WiFi status.
+
+        @return tuple of three dictionaries containing the WiFi status data
+            for the WiFi client, access point and overall data
+        @rtype tuple of (dict, dict, dict)
+        @exception OSError raised to indicate an issue with the device
+        """
+        if self._deviceData["wifi_type"] == "picow":
+            command = """
+def wifi_status():
+    import ubinascii
+    import ujson
+    import network
+    import rp2
+
+    wifi = network.WLAN(network.STA_IF)
+    station = {
+        'active': wifi.active(),
+        'connected': wifi.isconnected(),
+        'status': wifi.status(),
+        'ifconfig': wifi.ifconfig(),
+        'mac': ubinascii.hexlify(wifi.config('mac'), ':').decode(),
+        'channel': wifi.config('channel'),
+        'txpower': wifi.config('txpower'),
+        'country': rp2.country(),
+    }
+    print(ujson.dumps(station))
+
+    wifi = network.WLAN(network.AP_IF)
+    ap = {
+        'active': wifi.active(),
+        'connected': wifi.isconnected(),
+        'status': wifi.status(),
+        'ifconfig': wifi.ifconfig(),
+        'mac': ubinascii.hexlify(wifi.config('mac'), ':').decode(),
+        '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']
+    }
+    print(ujson.dumps(overall))
+
+wifi_status()
+del wifi_status
+"""
+        elif self._deviceData["wifi_type"] == "pimoroni":
+            # TODO: not yet implemented
+            pass
+        else:
+            return super().getWifiData()
+
+        out, err = self._interface.execute(command, mode=self.submitMode)
+        if err:
+            raise OSError(self._shortError(err))
+
+        stationStr, apStr, overallStr = out.decode("utf-8").splitlines()
+        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"])
+        return station, ap, overall
+
+    def connectWifi(self, ssid, password):
+        """
+        Public method to connect a device to a WiFi network.
+
+        @param ssid name (SSID) of the WiFi network
+        @type str
+        @param password password needed to connect
+        @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):
+    import network
+    import rp2
+    import ujson
+    from time import sleep
+
+    rp2.country(country)
+
+    wifi = network.WLAN(network.STA_IF)
+    wifi.active(False)
+    wifi.active(True)
+    wifi.connect(ssid, password)
+    max_wait = 140
+    while max_wait:
+        if wifi.status() < 0 or wifi.status() >= 3:
+            break
+        max_wait -= 1
+        sleep(0.1)
+    status = wifi.status()
+    print(ujson.dumps({{'connected': wifi.isconnected(), 'status': status}}))
+
+connect_wifi({0}, {1}, {2})
+del connect_wifi
+""".format(
+                repr(ssid),
+                repr(password if password else ""),
+                repr(country if country else "XX"),
+            )
+        elif self._deviceData["wifi_type"] == "pimoroni":
+            # TODO: not yet implemented
+            pass
+        else:
+            return super().connectWifi(ssid, password)
+
+        with EricOverrideCursor():
+            out, err = self._interface.execute(
+                command, mode=self.submitMode, timeout=15000
+            )
+        if err:
+            return False, err
+
+        result = json.loads(out.decode("utf-8").strip())
+        if result["connected"]:
+            error = ""
+        else:
+            try:
+                error = self.__statusTranslations[self._deviceData["wifi_type"]][
+                    result["status"]
+                ]
+            except KeyError:
+                error = str(result["status"])
+
+        return result["connected"], error
+
+    def disconnectWifi(self):
+        """
+        Public method to disconnect a device from the WiFi network.
+
+        @return tuple containing a flag indicating success and an error string
+        @rtype tuple of (bool, str)
+        """
+        if self._deviceData["wifi_type"] == "picow":
+            command = """
+def disconnect_wifi():
+    import network
+    from time import sleep
+
+    wifi = network.WLAN(network.STA_IF)
+    wifi.disconnect()
+    wifi.active(False)
+    sleep(0.1)
+    print(not wifi.isconnected())
+
+disconnect_wifi()
+del disconnect_wifi
+"""
+        elif self._deviceData["wifi_type"] == "pimoroni":
+            # TODO: not yet implemented
+            pass
+        else:
+            return super().disconnectWifi()
+
+        out, err = self._interface.execute(command, mode=self.submitMode)
+        if err:
+            return False, err
+
+        return out.decode("utf-8").strip() == "True", ""
+
+    def writeCredentials(self, ssid, password):
+        """
+        Public method to write the given credentials to the connected device and modify
+        the start script to connect automatically.
+
+        @param ssid SSID of the network to connect to
+        @type str
+        @param password password needed to authenticate
+        @type str
+        @return tuple containing a flag indicating success and an error message
+        @rtype tuple of (bool, str)
+        """
+        command = """
+def modify_boot():
+    add = True
+    try:
+        with open('/boot.py', 'r') as f:
+            for ln in f.readlines():
+                if 'wifi_connect' in ln:
+                    add = False
+                    break
+    except:
+        pass
+    if add:
+        with open('/boot.py', 'a') as f:
+            f.write('\\nimport wifi_connect\\n')
+    print(True)
+
+modify_boot()
+del modify_boot
+"""
+
+        if self._deviceData["wifi_type"] == "picow":
+            country = Preferences.getMicroPython("WifiCountry").upper()
+            secrets = "WIFI_SSID = {0}\nWIFI_KEY = {1}\nWIFI_COUNTRY={2}".format(
+                repr(ssid),
+                repr(password) if password else '""',
+                repr(country) if country else '""',
+            )
+            wifiConnectFile = "picowWiFiConnect.py"
+        else:
+            secrets = "WIFI_SSID = {0}\nWIFI_KEY = {1}\n".format(
+                repr(ssid),
+                repr(password) if password else '""',
+            )
+            wifiConnectFile = "mpyWiFiConnect.py"
+        try:
+            # write secrets file
+            self.putData("/secrets.py", secrets.encode("utf-8"))
+            # copy auto-connect file
+            self.put(
+                os.path.join(os.path.dirname(__file__), "MCUScripts", wifiConnectFile),
+                "/wifi_connect.py",
+            )
+        except OSError as err:
+            return False, str(err)
+
+        # modify boot.py
+        out, err = self._interface.execute(command, mode=self.submitMode)
+        if err:
+            return False, err
+
+        return out.decode("utf-8").strip() == "True", ""
+
+    def removeCredentials(self):
+        """
+        Public method to remove the saved credentials from the connected device.
+
+        @return tuple containing a flag indicating success and an error message
+        @rtype tuple of (bool, str)
+        """
+        try:
+            self.rm("/secrets.py")
+        except OSError as err:
+            return False, str(err)
+
+        return True, ""
+
+    def checkInternet(self):
+        """
+        Public method to check, if the internet can be reached.
+
+        @return tuple containing a flag indicating reachability and an error string
+        @rtype tuple of (bool, str)
+        """
+        if self._deviceData["wifi_type"] == "picow":
+            command = """
+def check_internet():
+    import network
+    import socket
+
+    wifi = network.WLAN(network.STA_IF)
+    if wifi.isconnected():
+        s = socket.socket()
+        try:
+            s.connect(socket.getaddrinfo('google.com', 80)[0][-1])
+            s.close()
+            print(True)
+        except:
+            print(False)
+    else:
+        print(False)
+
+check_internet()
+del check_internet
+"""
+        elif self._deviceData["wifi_type"] == "pimoroni":
+            # TODO: not yet implemented
+            pass
+        else:
+            return super().checkInternet()
+
+        out, err = self._interface.execute(command, mode=self.submitMode)
+        if err:
+            return False, err
+
+        return out.decode("utf-8").strip() == "True", ""
+
+    def scanNetworks(self):
+        """
+        Public method to scan for available WiFi networks.
+
+        @return tuple containing the list of available networks as a tuple of 'Name',
+            'MAC-Address', 'channel', 'RSSI' and 'security' and an error string
+        @rtype tuple of (list of tuple of (str, str, int, int, str), str)
+        """
+        if self._deviceData["wifi_type"] == "picow":
+            country = Preferences.getMicroPython("WifiCountry").upper()
+            command = """
+def scan_networks():
+    import network
+    import rp2
+
+    rp2.country({0})
+
+    wifi = network.WLAN(network.STA_IF)
+    active = wifi.active()
+    if not active:
+        wifi.active(True)
+    network_list = wifi.scan()
+    if not active:
+        wifi.active(False)
+    print(network_list)
+
+scan_networks()
+del scan_networks
+""".format(
+                repr(country if country else "XX")
+            )
+
+        elif self._deviceData["wifi_type"] == "pimoroni":
+            # TODO: not yet implemented
+            pass
+        else:
+            return super().scanNetworks()
+
+        out, err = self._interface.execute(command, mode=self.submitMode, timeout=15000)
+        if err:
+            return [], err
+
+        networksList = ast.literal_eval(out.decode("utf-8"))
+        networks = []
+        for network in networksList:
+            if network[0]:
+                ssid = network[0].decode("utf-8")
+                mac = binascii.hexlify(network[1], ":").decode("utf-8")
+                channel = network[2]
+                rssi = network[3]
+                try:
+                    security = self.__securityTranslations[network[4]]
+                except KeyError:
+                    security = self.tr("unknown ({0})").format(network[4])
+                networks.append((ssid, mac, channel, rssi, security))
+
+        return networks, ""
+
+    def deactivateInterface(self, interface):
+        """
+        Public method to deactivate a given WiFi interface of the connected device.
+
+        @param interface designation of the interface to be deactivated (one of 'AP'
+            or 'STA')
+        @type str
+        @return tuple containg a flag indicating success and an error message
+        @rtype tuple of (bool, str)
+        @exception ValueError raised to indicate a wrong value for the interface type
+        """
+        if interface not in ("STA", "AP"):
+            raise ValueError(
+                "interface must be 'AP' or 'STA', got '{0}'".format(interface)
+            )
+
+        if self._deviceData["wifi_type"] == "picow":
+            command = """
+def deactivate():
+    import network
+    from time import sleep
+
+    wifi = network.WLAN(network.{0}_IF)
+    wifi.active(False)
+    sleep(0.1)
+    print(not wifi.active())
+
+deactivate()
+del deactivate
+""".format(
+                interface
+            )
+        elif self._deviceData["wifi_type"] == "pimoroni":
+            # TODO: not yet implemented
+            pass
+        else:
+            return super().deactivateInterface(interface)
+
+        out, err = self._interface.execute(command, mode=self.submitMode)
+        if err:
+            return False, err
+        else:
+            return out.decode("utf-8").strip() == "True", ""
+
+    def startAccessPoint(self, ssid, security=None, password=None, ifconfig=None):
+        """
+        Public method to start the access point interface.
+
+        @param ssid SSID of the access point
+        @type str
+        @param security security method (defaults to None)
+        @type int (optional)
+        @param password password (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)
+        @return tuple containing a flag indicating success and an error message
+        @rtype tuple of (bool, str)
+        """
+        if security is None or password is None:
+            security = 0
+            password = ""
+
+        if self._deviceData["wifi_type"] == "picow":
+            country = Preferences.getMicroPython("WifiCountry").upper()
+            if security:
+                security = 4  # Pico W supports just WPA/WPA2
+            command = """
+def start_ap(ssid, security, password, ifconfig, country):
+    import network
+    import rp2
+    from time import sleep
+
+    rp2.country(country)
+
+    ap = network.WLAN(network.AP_IF)
+    ap.active(True)
+    if ifconfig:
+        ap.ifconfig(ifconfig)
+    ap.config(ssid=ssid, security=security, password=password)
+    sleep(0.1)
+    print(ap.isconnected())
+
+start_ap({0}, {1}, {2}, {3}, {4})
+del start_ap
+""".format(
+                repr(ssid),
+                security,
+                repr(password),
+                ifconfig,
+                repr(country if country else "XX"),
+            )
+        elif self._deviceData["wifi_type"] == "pimoroni":
+            # TODO: not yet implemented
+            pass
+        else:
+            return super().startAccessPoint(ssid, security=security, password=password)
+
+        out, err = self._interface.execute(command, mode=self.submitMode, timeout=15000)
+        if err:
+            return False, err
+        else:
+            return out.decode("utf-8").strip() == "True", ""
+
+    def stopAccessPoint(self):
+        """
+        Public method to stop the access point interface.
+
+        @return tuple containg a flag indicating success and an error message
+        @rtype tuple of (bool, str)
+        """
+        if self._deviceData["wifi_type"] == "picow":
+            return self.deactivateInterface("AP")
+        elif self._deviceData["wifi_type"] == "pimoroni":
+            # TODO: not yet implemented
+            pass
+        else:
+            return super().stopAccessPoint()
+
+    def getConnectedClients(self):
+        """
+        Public method to get a list of connected clients.
+
+        @return a tuple containing a list of tuples containing the client MAC-Address
+            and the RSSI (if supported and available) and an error message
+        @rtype tuple of ([(bytes, int)], str)
+        """
+        if self._deviceData["wifi_type"] == "picow":
+            command = """
+def get_stations():
+    import network
+
+    ap = network.WLAN(network.AP_IF)
+    stations = ap.status('stations')
+    print(stations)
+
+get_stations()
+del get_stations
+"""
+        elif self._deviceData["wifi_type"] == "pimoroni":
+            # TODO: not yet implemented
+            pass
+        else:
+            return super().checkInternet()
+
+        out, err = self._interface.execute(command, mode=self.submitMode, timeout=10000)
+        if err:
+            return [], err
+
+        clientsList = ast.literal_eval(out.decode("utf-8"))
+        return clientsList, ""
+
+    ############################################################################
+    ## 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._interface.execute(command, mode=self.submitMode)
+            if err:
+                self.microPython.showError("rp2.country()", err)
+
 
 def createDevice(microPythonWidget, deviceType, vid, pid, boardName, serialNumber):
     """
--- a/src/eric7/MicroPython/MicroPythonDeviceInterface.py	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/MicroPython/MicroPythonDeviceInterface.py	Sat Feb 25 19:47:23 2023 +0100
@@ -35,6 +35,9 @@
     executeAsyncFinished = pyqtSignal()
     dataReceived = pyqtSignal(bytes)
 
+    PasteModePrompt = b"=== "
+    TracebackMarker = b"Traceback (most recent call last):"
+
     def __init__(self, parent=None):
         """
         Constructor
@@ -107,6 +110,56 @@
         """
         self.__serial.isConnected() and self.__serial.write(data)
 
+    def __pasteOn(self):
+        """
+        Private method to switch the connected device to 'paste' mode.
+
+        Note: switching to paste mode is done with synchronous writes.
+
+        @return flag indicating success
+        @rtype bool
+        """
+        if not self.__serial:
+            return False
+
+        pasteMessage = b"paste mode; Ctrl-C to cancel, Ctrl-D to finish\r\n=== "
+        self.__serial.write(b"\x02")  # end raw mode if required
+        written = self.__serial.waitForBytesWritten(500)
+        # time out after 500ms if device is not responding
+        if not written:
+            return False
+        for _i in range(3):
+            # CTRL-C three times to break out of loops
+            self.__serial.write(b"\r\x03")
+            written = self.__serial.waitForBytesWritten(500)
+            # time out after 500ms if device is not responding
+            if not written:
+                return False
+            QThread.msleep(10)
+        self.__serial.readAll()  # read all data and discard it
+        self.__serial.write(b"\r\x05")  # send CTRL-E to enter paste mode
+        self.__serial.readUntil(pasteMessage)
+
+        if self.__serial.hasTimedOut():
+            # it timed out; try it again and than fail
+            self.__serial.write(b"\r\x05")  # send CTRL-E again
+            self.__serial.readUntil(pasteMessage)
+            if self.__serial.hasTimedOut():
+                return False
+
+        QCoreApplication.processEvents(
+            QEventLoop.ProcessEventsFlag.ExcludeUserInputEvents
+        )
+        self.__serial.readAll()  # read all data and discard it
+        return True
+
+    def __pasteOff(self):
+        """
+        Private method to switch 'paste' mode off.
+        """
+        if self.__serial:
+            self.__serial.write(b"\x04")  # send CTRL-D to cancel paste mode
+
     def __rawOn(self):
         """
         Private method to switch the connected device to 'raw' mode.
@@ -114,7 +167,7 @@
         Note: switching to raw mode is done with synchronous writes.
 
         @return flag indicating success
-        @@rtype bool
+        @rtype bool
         """
         if not self.__serial:
             return False
@@ -189,7 +242,7 @@
 
         return True
 
-    def execute(self, commands):
+    def execute(self, commands, *, mode="raw", timeout=0):
         """
         Public method to send commands to the connected device and return the
         result.
@@ -198,6 +251,39 @@
 
         @param commands list of commands to be executed
         @type str or list of str
+        @keyparam mode submit mode to be used (one of 'raw' or 'paste') (defaults to
+            'raw')
+        @type str
+        @keyparam timeout per command timeout in milliseconds (0 for configured default)
+            (defaults to 0)
+        @type int (optional)
+        @return tuple containing stdout and stderr output of the device
+        @rtype tuple of (bytes, bytes)
+        @exception ValueError raised in case of an unsupported submit mode
+        """
+        if mode not in ("paste", "raw"):
+            raise ValueError("Unsupported submit mode given ('{0}').".format(mode))
+
+        if mode == "raw":
+            return self.__execute_raw(commands, timeout=timeout)
+        elif mode == "paste":
+            return self.__execute_paste(commands, timeout=timeout)
+        else:
+            # just in case
+            return b"", b""
+
+    def __execute_raw(self, commands, timeout=0):
+        """
+        Private method to send commands to the connected device using 'raw REPL' mode
+        and return the result.
+
+        If no serial connection is available, empty results will be returned.
+
+        @param commands list of commands to be executed
+        @type str or list of str
+        @param timeout per command timeout in milliseconds (0 for configured default)
+            (defaults to 0)
+        @type int (optional)
         @return tuple containing stdout and stderr output of the device
         @rtype tuple of (bytes, bytes)
         """
@@ -231,6 +317,7 @@
                 )
                 ok = self.__serial.readUntil(b"OK")
                 if ok != b"OK":
+                    self.__blockReadyRead = False
                     return (
                         b"",
                         "Expected 'OK', got '{0}', followed by '{1}'".format(
@@ -239,7 +326,7 @@
                     )
 
                 # read until prompt
-                response = self.__serial.readUntil(b"\x04>")
+                response = self.__serial.readUntil(b"\x04>", timeout=timeout)
                 if self.__serial.hasTimedOut():
                     self.__blockReadyRead = False
                     return b"", b"Timeout while processing commands."
@@ -260,6 +347,76 @@
 
         return bytes(result), err
 
+    def __execute_paste(self, commands, timeout=0):
+        """
+        Private method to send commands to the connected device using 'paste' mode
+        and return the result.
+
+        If no serial connection is available, empty results will be returned.
+
+        @param commands list of commands to be executed
+        @type str or list of str
+        @param timeout per command timeout in milliseconds (0 for configured default)
+            (defaults to 0)
+        @type int (optional)
+        @return tuple containing stdout and stderr output of the device
+        @rtype tuple of (bytes, bytes)
+        """
+        if not self.__serial:
+            return b"", b""
+
+        if not self.__serial.isConnected():
+            return b"", b"Device not connected or not switched on."
+
+        if isinstance(commands, list):
+            commands = "\n".join(commands)
+
+        # switch on raw mode
+        self.__blockReadyRead = True
+        ok = self.__pasteOn()
+        if not ok:
+            self.__blockReadyRead = False
+            return (b"", b"Could not switch to raw mode. Is the device switched on?")
+
+        # send commands
+        QThread.msleep(10)
+        for command in commands.splitlines(keepends=True):
+            # send the data as single lines
+            commandBytes = command.encode("utf-8")
+            self.__serial.write(commandBytes)
+            QCoreApplication.processEvents(
+                QEventLoop.ProcessEventsFlag.ExcludeUserInputEvents
+            )
+            QThread.msleep(10)
+            ok = self.__serial.readUntil(commandBytes)
+            if ok != commandBytes:
+                self.__blockReadyRead = False
+                return (
+                    b"",
+                    "Expected '{0}', got '{1}', followed by '{2}'".format(
+                        commandBytes, ok, self.__serial.readAll()
+                    ).encode("utf-8"),
+                )
+
+        # switch off paste mode causing the commands to be executed
+        self.__pasteOff()
+        QThread.msleep(10)
+        result = self.__serial.readUntil(b">>> ", timeout=timeout).replace(b">>> ", b"")
+        # read until Python prompt
+        if self.__serial.hasTimedOut():
+            self.__blockReadyRead = False
+            return b"", b"Timeout while processing commands."
+
+        if self.TracebackMarker in result:
+            errorIndex = result.find(self.TracebackMarker)
+            out, err = result[:errorIndex], result[errorIndex:]
+        else:
+            out = result.strip()
+            err = b""
+
+        self.__blockReadyRead = False
+        return out, err
+
     def executeAsync(self, commandsList):
         """
         Public method to execute a series of commands over a period of time
@@ -274,3 +431,25 @@
             QTimer.singleShot(2, lambda: self.executeAsync(commandsList))
         else:
             self.executeAsyncFinished.emit()
+
+    def executeAsyncPaste(self, commandsList):
+        """
+        Public method to execute a series of commands over a period of time
+        without returning any result (asynchronous execution).
+
+        @param commandsList list of commands to be execute on the device
+        @type list of bytes
+        """
+        if commandsList:
+            self.__blockReadyRead = True
+            command = commandsList.pop(0)
+            if command == "@PasteOn@":
+                self.__pasteOn()
+            else:
+                self.__serial.write(command)
+                self.__serial.readUntil(command)
+            QTimer.singleShot(2, lambda: self.executeAsyncPaste(commandsList))
+        else:
+            self.__blockReadyRead = False
+            self.__pasteOff()
+            self.executeAsyncFinished.emit()
--- a/src/eric7/MicroPython/MicroPythonSerialPort.py	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/MicroPython/MicroPythonSerialPort.py	Sat Feb 25 19:47:23 2023 +0100
@@ -92,21 +92,27 @@
         """
         return self.__timedOut
 
-    def readUntil(self, expected=b"\n", size=None):
+    def readUntil(self, expected=b"\n", size=None, timeout=0):
         r"""
         Public method to read data until an expected sequence is found
         (default: \n) or a specific size is exceeded.
 
         @param expected expected bytes sequence
         @type bytes
-        @param size maximum data to be read
-        @type int
+        @param size maximum data to be read (defaults to None)
+        @type int (optional)
+        @param timeout timeout in milliseconds (0 for configured default)
+            (defaults to 0)
+        @type int (optional)
         @return bytes read from the device including the expected sequence
         @rtype bytes
         """
         data = bytearray()
         self.__timedOut = False
 
+        if timeout == 0:
+            timeout = self.__timeout
+
         t = QTime.currentTime()
         while True:
             QCoreApplication.processEvents(
@@ -119,7 +125,7 @@
                     break
                 if size is not None and len(data) >= size:
                     break
-            if t.msecsTo(QTime.currentTime()) > self.__timeout:
+            if t.msecsTo(QTime.currentTime()) > timeout:
                 self.__timedOut = True
                 break
 
--- a/src/eric7/MicroPython/MicroPythonWidget.py	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/MicroPython/MicroPythonWidget.py	Sat Feb 25 19:47:23 2023 +0100
@@ -41,6 +41,7 @@
 from . import Devices, UF2FlashDialog
 from .MicroPythonFileManagerWidget import MicroPythonFileManagerWidget
 from .Ui_MicroPythonWidget import Ui_MicroPythonWidget
+from .WifiDialogs.WifiController import WifiController
 
 try:
     from .MicroPythonGraphWidget import MicroPythonGraphWidget
@@ -223,6 +224,9 @@
 
         self.__ui = parent
 
+        self.__wifiController = WifiController(self, self)
+        self.__wifiMenu = None
+
         self.__superMenu = QMenu(self)
         self.__superMenu.aboutToShow.connect(self.__aboutToShowSuperMenu)
 
@@ -617,6 +621,9 @@
                 self.tr("Press to connect the selected device")
             )
 
+        if not connected and self.__wifiMenu and self.__wifiMenu.isTearOffMenuVisible():
+            self.__wifiMenu.hideTearOffMenu()
+
     def isConnected(self):
         """
         Public method to get the MicroPython device connection state.
@@ -743,9 +750,10 @@
             if pasteText:
                 pasteText = pasteText.replace("\n\r", "\r")
                 pasteText = pasteText.replace("\n", "\r")
-                self.__interface.isConnected() and self.__interface.write(
-                    pasteText.encode("utf-8")
-                )
+                if self.__interface.isConnected():
+                    self.__interface.write(b"\x05")
+                    self.__interface.write(pasteText.encode("utf-8"))
+                    self.__interface.write(b"\x04")
 
     def eventFilter(self, obj, evt):
         """
@@ -1115,6 +1123,15 @@
         boardName = self.deviceTypeComboBox.currentData(self.DeviceBoardRole)
         return boardName
 
+    def getDevice(self):
+        """
+        Public method to get a reference to the current device.
+
+        @return reference to the current device
+        @rtype BaseDevice
+        """
+        return self.__device
+
     def getDeviceWorkspace(self):
         """
         Public method to get the workspace directory of the device.
@@ -1436,6 +1453,14 @@
             else:
                 downloadMenu = None
 
+        # prepare the WiFi menu
+        if self.__device and self.__connected and self.__device.getDeviceData("wifi"):
+            if self.__wifiMenu is not None:
+                self.__wifiMenu.deleteLater()
+            self.__wifiMenu = self.__wifiController.createMenu(self.__superMenu)
+        else:
+            self.__wifiMenu = None
+
         # populate the super menu
         hasTime = self.__device.hasTimeCommands() if self.__device else False
 
@@ -1479,6 +1504,9 @@
         if self.__device:
             self.__device.addDeviceMenuEntries(self.__superMenu)
             self.__superMenu.addSeparator()
+            if self.__wifiMenu is not None:
+                self.__superMenu.addMenu(self.__wifiMenu)
+                self.__superMenu.addSeparator()
             if downloadMenu is None:
                 # generic download action
                 self.__superMenu.addAction(
@@ -1586,7 +1614,7 @@
             dlg = BoardDataDialog(boardInfo)
             dlg.exec()
         except Exception as exc:
-            self.__showError("getBoardInformation()", str(exc))
+            self.showError("getBoardInformation()", str(exc))
 
     @pyqtSlot()
     def __synchronizeTime(self, quiet=False):
@@ -1616,7 +1644,7 @@
                             + self.__getDeviceTime(),
                         )
             except Exception as exc:
-                self.__showError("syncTime()", str(exc))
+                self.showError("syncTime()", str(exc))
 
     def __getDeviceTime(self):
         """
@@ -1643,7 +1671,7 @@
                         dateTimeString.strip()
                     )
             except Exception as exc:
-                self.__showError("getTime()", str(exc))
+                self.showError("getTime()", str(exc))
                 return ""
         else:
             return ""
@@ -1720,11 +1748,11 @@
                     ).format(localdate, localtime, deviceDateTimeString.strip()),
                 )
         except Exception as exc:
-            self.__showError("getTime()", str(exc))
+            self.showError("getTime()", str(exc))
 
-    def __showError(self, method, error):
+    def showError(self, method, error):
         """
-        Private method to show some error message.
+        Public method to show some error message.
 
         @param method name of the method the error occured in
         @type str
@@ -1987,4 +2015,4 @@
                 )
                 dlg.show()
             except Exception as exc:
-                self.__showError("getModules()", str(exc))
+                self.showError("getModules()", str(exc))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/WifiDialogs/WifiApConfigDialog.py	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,147 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog to configure the Access Point interface.
+"""
+
+from PyQt6.QtCore import pyqtSlot
+from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QLineEdit
+
+from eric7 import Preferences
+from eric7.EricGui import EricPixmapCache
+
+from .Ui_WifiApConfigDialog import Ui_WifiApConfigDialog
+
+
+class WifiApConfigDialog(QDialog, Ui_WifiApConfigDialog):
+    """
+    Class implementing a dialog to configure the Access Point interface.
+    """
+
+    def __init__(self, withIP, parent=None):
+        """
+        Constructor
+
+        @param withIP flag indicating to ask the user for an IP configuration
+        @type bool
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+        self.setupUi(self)
+
+        self.apShowPasswordButton.setIcon(EricPixmapCache.getIcon("showPassword"))
+
+        # populate the WiFi security mode combo box
+        self.apSecurityComboBox.addItem(self.tr("open"), 0)
+        self.apSecurityComboBox.addItem("WEP", 1)
+        self.apSecurityComboBox.addItem("WPA", 2)
+        self.apSecurityComboBox.addItem("WPA2", 3)
+        self.apSecurityComboBox.addItem("WPA/WPA2", 4)
+        self.apSecurityComboBox.addItem("WPA2 (CCMP)", 5)
+        self.apSecurityComboBox.addItem("WPA3", 6)
+        self.apSecurityComboBox.addItem("WPA2/WPA3", 7)
+
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(False)
+
+        # populate the WiFi fields with data saved to the preferences
+        self.apSsidEdit.setText(Preferences.getMicroPython("WifiApName"))
+        self.apPasswordEdit.setText(Preferences.getMicroPython("WifiApPassword"))
+        index = self.apSecurityComboBox.findData(
+            Preferences.getMicroPython("WifiApAuthMode")
+        )
+        if index == -1:
+            index = 5  # default it to WPA/WPA2 in case of an issue
+        self.apSecurityComboBox.setCurrentIndex(index)
+
+        self.__withIP = withIP
+
+        self.ipv4GroupBox.setVisible(withIP)
+        if withIP:
+            # populate the IPv4 configuration with data saved to the preferences
+            self.addressEdit.setText(Preferences.getMicroPython("WifiApAddress"))
+            self.netmaskEdit.setText(Preferences.getMicroPython("WifiApNetmask"))
+            self.gatewayEdit.setText(Preferences.getMicroPython("WifiApGateway"))
+            self.dnsEdit.setText(Preferences.getMicroPython("WifiApDNS"))
+
+            # connect the IPv4 fields
+            self.addressEdit.addressChanged.connect(self.__updateOk)
+            self.netmaskEdit.addressChanged.connect(self.__updateOk)
+            self.gatewayEdit.addressChanged.connect(self.__updateOk)
+            self.dnsEdit.addressChanged.connect(self.__updateOk)
+
+        # connect the WiFi fields
+        self.apSsidEdit.textChanged.connect(self.__updateOk)
+        self.apPasswordEdit.textChanged.connect(self.__updateOk)
+        self.apSecurityComboBox.currentIndexChanged.connect(self.__updateOk)
+
+        self.__updateOk()
+
+        msh = self.minimumSizeHint()
+        self.resize(max(self.width(), msh.width()), msh.height())
+
+    @pyqtSlot()
+    def __updateOk(self):
+        """
+        Private method to update the enabled state of the OK button.
+        """
+        enable = bool(self.apSsidEdit.text())
+        if self.apSecurityComboBox.currentData() != 0:
+            # security needs a password
+            enable &= bool(self.apPasswordEdit.text())
+        if self.__withIP:
+            enable &= (
+                self.addressEdit.hasAcceptableInput()
+                and self.netmaskEdit.hasAcceptableInput()
+                and self.gatewayEdit.hasAcceptableInput()
+                and self.dnsEdit.hasAcceptableInput()
+            )
+
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(enable)
+
+    @pyqtSlot(bool)
+    def on_apShowPasswordButton_clicked(self, checked):
+        """
+        Private slot to show or hide the WiFi Access Point password.
+
+        @param checked state of the button
+        @type bool
+        """
+        if checked:
+            self.apPasswordEdit.setEchoMode(QLineEdit.EchoMode.Normal)
+            self.apShowPasswordButton.setIcon(EricPixmapCache.getIcon("hidePassword"))
+            self.apShowPasswordButton.setToolTip(self.tr("Press to hide the password"))
+        else:
+            self.apPasswordEdit.setEchoMode(QLineEdit.EchoMode.Password)
+            self.apShowPasswordButton.setIcon(EricPixmapCache.getIcon("showPassword"))
+            self.apShowPasswordButton.setToolTip(self.tr("Press to show the password"))
+
+    def getApConfig(self):
+        """
+        Public method to get the entered access point configuration data.
+
+        @return tuple containing the SSID, the password, the selected security mode
+            and a flag indicating to save the parameters to the settings
+        @rtype tuple of (str, str, int, bool)
+        """
+        ifconfig = (
+            (
+                self.addressEdit.text(),
+                self.netmaskEdit.text(),
+                self.gatewayEdit.text(),
+                self.dnsEdit.text(),
+            )
+            if self.__withIP
+            else ("", "", "", "")
+        )
+
+        return (
+            self.apSsidEdit.text(),
+            self.apPasswordEdit.text(),
+            self.apSecurityComboBox.currentData(),
+            self.rememberCheckBox.isChecked(),
+            ifconfig,
+        )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/WifiDialogs/WifiApConfigDialog.ui	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,256 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>WifiApConfigDialog</class>
+ <widget class="QDialog" name="WifiApConfigDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>315</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Access Point Configuration</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QGridLayout" name="gridLayout_2">
+   <item row="0" column="0">
+    <widget class="QLabel" name="label_10">
+     <property name="text">
+      <string>Name:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1" colspan="2">
+    <widget class="QLineEdit" name="apSsidEdit">
+     <property name="toolTip">
+      <string>Enter the network name (SSID) to publish</string>
+     </property>
+     <property name="clearButtonEnabled">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="label_12">
+     <property name="text">
+      <string>Password:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <widget class="QLineEdit" name="apPasswordEdit">
+     <property name="toolTip">
+      <string>Enter the network password</string>
+     </property>
+     <property name="echoMode">
+      <enum>QLineEdit::Password</enum>
+     </property>
+     <property name="clearButtonEnabled">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="2">
+    <widget class="QToolButton" name="apShowPasswordButton">
+     <property name="toolTip">
+      <string>Press to show the password</string>
+     </property>
+     <property name="checkable">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QLabel" name="label_23">
+     <property name="text">
+      <string>Security:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="1" colspan="2">
+    <layout class="QHBoxLayout" name="horizontalLayout_6">
+     <item>
+      <widget class="QComboBox" name="apSecurityComboBox">
+       <property name="toolTip">
+        <string>Select the security mode</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_3">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item row="3" column="0" colspan="3">
+    <widget class="QGroupBox" name="ipv4GroupBox">
+     <property name="title">
+      <string>IPv4 Configuration</string>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <layout class="QGridLayout" name="gridLayout">
+        <item row="0" column="0">
+         <widget class="QLabel" name="label">
+          <property name="text">
+           <string>Address:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="1">
+         <widget class="EricIPv4InputWidget" name="addressEdit" native="true">
+          <property name="focusPolicy">
+           <enum>Qt::NoFocus</enum>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="0">
+         <widget class="QLabel" name="label_2">
+          <property name="text">
+           <string>Netmask:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="1">
+         <widget class="EricIPv4InputWidget" name="netmaskEdit" native="true">
+          <property name="focusPolicy">
+           <enum>Qt::NoFocus</enum>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="0">
+         <widget class="QLabel" name="label_3">
+          <property name="text">
+           <string>Gateway:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="1">
+         <widget class="EricIPv4InputWidget" name="gatewayEdit" native="true">
+          <property name="focusPolicy">
+           <enum>Qt::NoFocus</enum>
+          </property>
+         </widget>
+        </item>
+        <item row="3" column="0">
+         <widget class="QLabel" name="label_4">
+          <property name="text">
+           <string>DNS:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="3" column="1">
+         <widget class="EricIPv4InputWidget" name="dnsEdit" native="true">
+          <property name="focusPolicy">
+           <enum>Qt::NoFocus</enum>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>273</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="4" column="0" colspan="3">
+    <widget class="QCheckBox" name="rememberCheckBox">
+     <property name="toolTip">
+      <string>Select to remember the entered connection parameters</string>
+     </property>
+     <property name="text">
+      <string>Remember Parameters</string>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="0" colspan="3">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>EricIPv4InputWidget</class>
+   <extends>QWidget</extends>
+   <header>eric7/EricNetwork/EricIPv4InputWidget.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <tabstops>
+  <tabstop>apSsidEdit</tabstop>
+  <tabstop>apPasswordEdit</tabstop>
+  <tabstop>apShowPasswordButton</tabstop>
+  <tabstop>apSecurityComboBox</tabstop>
+  <tabstop>addressEdit</tabstop>
+  <tabstop>netmaskEdit</tabstop>
+  <tabstop>gatewayEdit</tabstop>
+  <tabstop>dnsEdit</tabstop>
+  <tabstop>rememberCheckBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>WifiApConfigDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>WifiApConfigDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/WifiDialogs/WifiApStationsDialog.py	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog showing the currently connected stations (clients).
+"""
+
+import binascii
+
+from PyQt6.QtCore import Qt
+from PyQt6.QtWidgets import QDialog, QTreeWidgetItem
+
+from .Ui_WifiApStationsDialog import Ui_WifiApStationsDialog
+
+
+class WifiApStationsDialog(QDialog, Ui_WifiApStationsDialog):
+    """
+    Class documentation goes here.
+    """
+
+    def __init__(self, stations, parent=None):
+        """
+        Constructor
+
+        @param stations list of connected stations. Each entry is a tuple containing the
+            station's MAC-Address and the RSSI (if supported and available)
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+        self.setupUi(self)
+
+        rssiFound = False
+
+        for station in stations:
+            mac = binascii.hexlify(station[0], ":").decode("utf-8")
+            if len(station) > 1:
+                rssiFound = True
+                rssi = str(station[1])
+            else:
+                rssi = ""
+            QTreeWidgetItem(self.stationsList, [mac, rssi, ""])
+
+        self.stationsList.sortItems(0, Qt.SortOrder.AscendingOrder)
+        self.stationsList.resizeColumnToContents(0)
+        self.stationsList.resizeColumnToContents(1)
+        self.stationsList.setColumnHidden(1, not rssiFound)
+        self.stationsList.header().setStretchLastSection(True)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/WifiDialogs/WifiApStationsDialog.ui	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>WifiApStationsDialog</class>
+ <widget class="QDialog" name="WifiApStationsDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>511</width>
+    <height>509</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Connected WiFi Clients</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QTreeWidget" name="stationsList">
+     <property name="alternatingRowColors">
+      <bool>true</bool>
+     </property>
+     <property name="selectionMode">
+      <enum>QAbstractItemView::NoSelection</enum>
+     </property>
+     <property name="rootIsDecorated">
+      <bool>false</bool>
+     </property>
+     <property name="itemsExpandable">
+      <bool>false</bool>
+     </property>
+     <property name="sortingEnabled">
+      <bool>true</bool>
+     </property>
+     <column>
+      <property name="text">
+       <string>Name</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>RSSI [dBm]</string>
+      </property>
+     </column>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Close</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>WifiApStationsDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>WifiApStationsDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/WifiDialogs/WifiConnectionDialog.py	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,86 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog to enter the parameters needed to connect to a WiFi
+network.
+"""
+
+from PyQt6.QtCore import pyqtSlot
+from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QLineEdit
+
+from eric7 import Preferences
+from eric7.EricGui import EricPixmapCache
+
+from .Ui_WifiConnectionDialog import Ui_WifiConnectionDialog
+
+
+class WifiConnectionDialog(QDialog, Ui_WifiConnectionDialog):
+    """
+    Class implementing a dialog to enter the parameters needed to connect to a WiFi
+    network.
+    """
+
+    def __init__(self, parent=None):
+        """
+        Constructor
+
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+        self.setupUi(self)
+
+        self.showPasswordButton.setIcon(EricPixmapCache.getIcon("showPassword"))
+
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(False)
+
+        # populate the field with data saved to the preferences
+        self.ssidEdit.setText(Preferences.getMicroPython("WifiName"))
+        self.passwordEdit.setText(Preferences.getMicroPython("WifiPassword"))
+
+        msh = self.minimumSizeHint()
+        self.resize(max(self.width(), msh.width()), msh.height())
+
+    @pyqtSlot(str)
+    def on_ssidEdit_textChanged(self, ssid):
+        """
+        Private slot handling a change of the SSID.
+
+        @param ssid entered SSID
+        @type str
+        """
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(bool(ssid))
+
+    @pyqtSlot(bool)
+    def on_showPasswordButton_clicked(self, checked):
+        """
+        Private slot to show or hide the password.
+
+        @param checked state of the button
+        @type bool
+        """
+        if checked:
+            self.passwordEdit.setEchoMode(QLineEdit.EchoMode.Normal)
+            self.showPasswordButton.setIcon(EricPixmapCache.getIcon("hidePassword"))
+            self.showPasswordButton.setToolTip(self.tr("Press to hide the password"))
+        else:
+            self.passwordEdit.setEchoMode(QLineEdit.EchoMode.Password)
+            self.showPasswordButton.setIcon(EricPixmapCache.getIcon("showPassword"))
+            self.showPasswordButton.setToolTip(self.tr("Press to show the password"))
+
+    def getConnectionParameters(self):
+        """
+        Public method to get the entered connection parameters.
+
+        @return tuple containing the SSID, password and a flag indicating, if the
+            parameters shall be saved to the preferences
+        @rtype tuple of (str, str, bool)
+        """
+        return (
+            self.ssidEdit.text(),
+            self.passwordEdit.text(),
+            self.rememberCheckBox.isChecked(),
+        )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/WifiDialogs/WifiConnectionDialog.ui	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>WifiConnectionDialog</class>
+ <widget class="QDialog" name="WifiConnectionDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>138</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>WiFi Connection Parameters</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Name:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1" colspan="2">
+    <widget class="QLineEdit" name="ssidEdit">
+     <property name="toolTip">
+      <string>Enter the network name (SSID) to connect to</string>
+     </property>
+     <property name="clearButtonEnabled">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="label_2">
+     <property name="text">
+      <string>Password:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <widget class="QLineEdit" name="passwordEdit">
+     <property name="toolTip">
+      <string>Enter the network password</string>
+     </property>
+     <property name="echoMode">
+      <enum>QLineEdit::Password</enum>
+     </property>
+     <property name="clearButtonEnabled">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="2">
+    <widget class="QToolButton" name="showPasswordButton">
+     <property name="toolTip">
+      <string>Press to show the password</string>
+     </property>
+     <property name="checkable">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0" colspan="3">
+    <widget class="QCheckBox" name="rememberCheckBox">
+     <property name="toolTip">
+      <string>Select to remember the entered connection parameters</string>
+     </property>
+     <property name="text">
+      <string>Remember Parameters</string>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="0" colspan="3">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <tabstops>
+  <tabstop>ssidEdit</tabstop>
+  <tabstop>passwordEdit</tabstop>
+  <tabstop>showPasswordButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>WifiConnectionDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>WifiConnectionDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/WifiDialogs/WifiController.py	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,386 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the WiFi related functionality.
+"""
+
+from PyQt6.QtCore import QObject, pyqtSlot
+from PyQt6.QtWidgets import QDialog, QMenu
+
+from eric7 import Preferences
+from eric7.EricGui.EricOverrideCursor import EricOverrideCursor
+from eric7.EricWidgets import EricMessageBox
+
+
+class WifiController(QObject):
+    """
+    Class implementing the WiFi related functionality.
+    """
+
+    def __init__(self, microPython, parent=None):
+        """
+        Constructor
+
+        @param microPython reference to the MicroPython widget
+        @type MicroPythonWidgep
+        @param parent reference to the parent object (defaults to None)
+        @type QObject (optional)
+        """
+        super().__init__(parent)
+
+        self.__mpy = microPython
+
+    def createMenu(self, menu):
+        """
+        Public method to create the WiFi submenu.
+
+        @param menu reference to the parent menu
+        @type QMenu
+        @return reference to the created menu
+        @rtype QMenu
+        """
+        wifiMenu = QMenu(self.tr("WiFi Functions"), menu)
+        wifiMenu.setTearOffEnabled(True)
+        wifiMenu.addAction(self.tr("Show WiFi Status"), self.__showWifiStatus)
+        wifiMenu.addSeparator()
+        wifiMenu.addAction(self.tr("Connect WiFi"), self.__connectWifi)
+        wifiMenu.addAction(self.tr("Check Internet Connection"), self.__checkInternet)
+        wifiMenu.addAction(self.tr("Disconnect WiFi"), self.__disconnectWifi)
+        wifiMenu.addSeparator()
+        wifiMenu.addAction(self.tr("Scan Networks"), self.__scanNetwork)
+        wifiMenu.addSeparator()
+        wifiMenu.addAction(self.tr("Write WiFi Credentials"), self.__writeCredentials)
+        wifiMenu.addAction(self.tr("Remove WiFi Credentials"), self.__removeCredentials)
+        wifiMenu.addSeparator()
+        wifiMenu.addAction(self.tr("Start WiFi Access Point"), self.__startAccessPoint)
+        wifiMenu.addAction(
+            self.tr("Start WiFi Access Point with IP"), self.__startAccessPointIP
+        )
+        wifiMenu.addAction(
+            self.tr("Show Connected Clients"), self.__showConnectedClients
+        )
+        wifiMenu.addAction(self.tr("Stop WiFi Access Point"), self.__stopAccessPoint)
+        wifiMenu.addSeparator()
+        wifiMenu.addAction(
+            self.tr("Deactivate Client Interface"),
+            lambda: self.__deactivateInterface("STA"),
+        )
+        wifiMenu.addAction(
+            self.tr("Deactivate Access Point Interface"),
+            lambda: self.__deactivateInterface("AP"),
+        )
+
+        # add device specific entries (if there are any)
+        self.__mpy.getDevice().addDeviceWifiEntries(wifiMenu)
+
+        return wifiMenu
+
+    @pyqtSlot()
+    def __showWifiStatus(self):
+        """
+        Private slot to show a dialog with the WiFi status of the current device.
+        """
+        from .WifiStatusDialog import WifiStatusDialog
+
+        try:
+            clientStatus, apStatus, overallStatus = self.__mpy.getDevice().getWifiData()
+
+            dlg = WifiStatusDialog(clientStatus, apStatus, overallStatus)
+            dlg.exec()
+        except Exception as exc:
+            self.__mpy.showError("getWifiData()", str(exc))
+
+    @pyqtSlot()
+    def __connectWifi(self):
+        """
+        Private slot to connect the current device to a WiFi network.
+        """
+        from .WifiConnectionDialog import WifiConnectionDialog
+
+        dlg = WifiConnectionDialog()
+        if dlg.exec() == QDialog.DialogCode.Accepted:
+            ssid, password, remember = dlg.getConnectionParameters()
+            if remember:
+                # save the parameters to the preferences
+                Preferences.setMicroPython("WifiName", ssid)
+                Preferences.setMicroPython("WifiPassword", password)
+            success, error = self.__mpy.getDevice().connectWifi(ssid, password)
+            if success:
+                EricMessageBox.information(
+                    None,
+                    self.tr("Connect WiFi"),
+                    self.tr(
+                        "<p>The device was connected to <b>{0}</b> successfully.</p>"
+                    ).format(ssid),
+                )
+            else:
+                EricMessageBox.critical(
+                    None,
+                    self.tr("Connect WiFi"),
+                    self.tr(
+                        "<p>The device could not connect to <b>{0}</b>.</p>"
+                        "<p>Reason: {1}</p>"
+                    ).format(ssid, error if error else self.tr("unknown")),
+                )
+
+    @pyqtSlot()
+    def __disconnectWifi(self):
+        """
+        Private slot to disconnect the current device from the WiFi network.
+        """
+        success, error = self.__mpy.getDevice().disconnectWifi()
+        if success:
+            EricMessageBox.information(
+                None,
+                self.tr("Disconnect WiFi"),
+                self.tr("<p>The device was disconnected from the WiFi network.</p>"),
+            )
+        else:
+            EricMessageBox.critical(
+                None,
+                self.tr("Disconnect WiFi"),
+                self.tr(
+                    "<p>The device could not be disconnected.</p><p>Reason: {0}</p>"
+                ).format(error if error else self.tr("unknown")),
+            )
+
+    @pyqtSlot()
+    def __checkInternet(self):
+        """
+        Private slot to check the availability of an internet connection.
+        """
+        success, error = self.__mpy.getDevice().checkInternet()
+        if not error:
+            msg = (
+                self.tr("<p>The internet connection is <b>available</b>.</p>")
+                if success
+                else self.tr("<p>The internet connection is <b>not available</b>.</p>")
+            )
+            EricMessageBox.information(
+                None,
+                self.tr("Check Internet Connection"),
+                msg,
+            )
+        else:
+            EricMessageBox.critical(
+                None,
+                self.tr("Check Internet Connection"),
+                self.tr(
+                    "<p>The internet is not available.</p><p>Reason: {0}</p>"
+                ).format(error if error else self.tr("unknown")),
+            )
+
+    @pyqtSlot()
+    def __scanNetwork(self):
+        """
+        Private slot to scan for visible WiFi networks.
+        """
+        from .WifiNetworksWindow import WifiNetworksWindow
+
+        win = WifiNetworksWindow(self.__mpy.getDevice(), self.__mpy)
+        win.show()
+        win.scanNetworks()
+
+    @pyqtSlot()
+    def __writeCredentials(self):
+        """
+        Private slot to save the WiFi login credentials to the connected device.
+
+        This will also modify the boot script to perform an automatic WiFi connection.
+        """
+        from .WifiConnectionDialog import WifiConnectionDialog
+
+        dlg = WifiConnectionDialog()
+        if dlg.exec() == QDialog.DialogCode.Accepted:
+            ssid, password, remember = dlg.getConnectionParameters()
+            if remember:
+                # save the parameters to the preferences
+                Preferences.setMicroPython("WifiName", ssid)
+                Preferences.setMicroPython("WifiPassword", password)
+            success, error = self.__mpy.getDevice().writeCredentials(ssid, password)
+            if success:
+                EricMessageBox.information(
+                    None,
+                    self.tr("Write WiFi Credentials"),
+                    self.tr(
+                        "<p>The WiFi credentials were saved on the device. The device"
+                        " will connect to the WiFi network at boot time.</p>"
+                    ),
+                )
+            else:
+                EricMessageBox.critical(
+                    None,
+                    self.tr("Write WiFi Credentials"),
+                    self.tr(
+                        "<p>The WiFi credentials could not be saved on the device.</p>"
+                        "<p>Reason: {0}</p>"
+                    ).format(error if error else self.tr("unknown")),
+                )
+
+    @pyqtSlot()
+    def __removeCredentials(self):
+        """
+        Private slot to remove the saved WiFi credentials from the connected device.
+
+        This will not remove the auto-connect part of the boot script. This needs to be
+        done manually if desired.
+        """
+        ok = EricMessageBox.yesNo(
+            None,
+            self.tr("Remove WiFi Credentials"),
+            self.tr(
+                "Shall the saved WiFi credentials really be removed from the connected"
+                " device?"
+            ),
+        )
+        if ok:
+            success, error = self.__mpy.getDevice().removeCredentials()
+            if success:
+                EricMessageBox.information(
+                    None,
+                    self.tr("Remove WiFi Credentials"),
+                    self.tr(
+                        "<p>The WiFi credentials were removed from the device. The"
+                        " device will not connect to the WiFi network at boot time"
+                        " anymore.</p>"
+                    ),
+                )
+            else:
+                EricMessageBox.critical(
+                    None,
+                    self.tr("Remove WiFi Credentials"),
+                    self.tr(
+                        "<p>The WiFi credentials could not be removed from the device."
+                        "</p><p>Reason: {0}</p>"
+                    ).format(error if error else self.tr("unknown")),
+                )
+
+    @pyqtSlot()
+    def __startAccessPoint(self, withIP=False):
+        """
+        Private slot to start the Access Point interface of the connected device.
+
+        @param withIP flag indicating to start the access point with an IP configuration
+        @type bool
+        """
+        from .WifiApConfigDialog import WifiApConfigDialog
+
+        dlg = WifiApConfigDialog(withIP=withIP)
+        if dlg.exec() == QDialog.DialogCode.Accepted:
+            ssid, password, security, remember, ifconfig = dlg.getApConfig()
+
+            if remember:
+                Preferences.setMicroPython("WifiApName", ssid)
+                Preferences.setMicroPython("WifiApPassword", password)
+                Preferences.setMicroPython("WifiApAuthMode", security)
+                if withIP:
+                    Preferences.setMicroPython("WifiApAddress", ifconfig[0])
+                    Preferences.setMicroPython("WifiApNetmask", ifconfig[1])
+                    Preferences.setMicroPython("WifiApGateway", ifconfig[2])
+                    Preferences.setMicroPython("WifiApDNS", ifconfig[3])
+
+            ok, err = self.__mpy.getDevice().startAccessPoint(
+                ssid,
+                security=security,
+                password=password,
+                ifconfig=ifconfig if withIP else None,
+            )
+            if ok:
+                EricMessageBox.information(
+                    None,
+                    self.tr("Start WiFi Access Point"),
+                    self.tr(
+                        "The WiFi Access Point interface was started successfully."
+                    ),
+                )
+            else:
+                msg = self.tr("<p>The WiFi Access Point could not be started.</p>")
+                if err:
+                    msg += self.tr("<p>Reason: {0}").format(err)
+                EricMessageBox.critical(
+                    None,
+                    self.tr("Start WiFi Access Point"),
+                    msg,
+                )
+
+    @pyqtSlot()
+    def __startAccessPointIP(self):
+        """
+        Private slot to start the Access Point interface of the connected device
+        with given IP parameters.
+        """
+        self.__startAccessPoint(withIP=True)
+
+    @pyqtSlot()
+    def __stopAccessPoint(self):
+        """
+        Private slot to stop the Access Point interface of the connected device.
+        """
+        ok, err = self.__mpy.getDevice().stopAccessPoint()
+        if ok:
+            EricMessageBox.information(
+                None,
+                self.tr("Stop WiFi Access Point"),
+                self.tr("The WiFi Access Point interface was stopped successfully."),
+            )
+        else:
+            msg = self.tr("<p>The WiFi Access Point could not be stopped.</p>")
+            if err:
+                msg += self.tr("<p>Reason: {0}").format(err)
+            EricMessageBox.critical(
+                None,
+                self.tr("Stop WiFi Access Point"),
+                msg,
+            )
+
+    @pyqtSlot()
+    def __showConnectedClients(self):
+        """
+        Private slot to show a list of WiFi clients connected to the Access Point
+        interface.
+        """
+        from .WifiApStationsDialog import WifiApStationsDialog
+
+        with EricOverrideCursor():
+            stations, err = self.__mpy.getDevice().getConnectedClients()
+
+        if err:
+            self.__mpy.showError("getConnectedClients()", err)
+        else:
+            if stations:
+                dlg = WifiApStationsDialog(stations)
+                dlg.exec()
+            else:
+                EricMessageBox.information(
+                    None,
+                    self.tr("Show Connected Clients"),
+                    self.tr("No clients are connected to the access point."),
+                )
+
+    def __deactivateInterface(self, interface):
+        """
+        Private method to deactivate a given WiFi interface of the connected device.
+
+        @param interface designation of the interface to be deactivated (one of 'AP'
+            or 'STA')
+        @type str
+        """
+        ok, err = self.__mpy.getDevice().deactivateInterface(interface)
+        if ok:
+            EricMessageBox.information(
+                None,
+                self.tr("Deactivate WiFi Interface"),
+                self.tr("The WiFi interface was deactivated successfully."),
+            )
+        else:
+            msg = self.tr("<p>The WiFi interface could not be deactivated.</p>")
+            if err:
+                msg += self.tr("<p>Reason: {0}").format(err)
+            EricMessageBox.critical(
+                None,
+                self.tr("Deactivate WiFi Interface"),
+                msg,
+            )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/WifiDialogs/WifiCountryDialog.py	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+
+"""
+Module implementing a dialog to enter the country code for the WiFi interface.
+"""
+
+from PyQt6.QtCore import pyqtSlot
+from PyQt6.QtWidgets import QDialog, QDialogButtonBox
+
+from eric7 import Preferences
+
+from .Ui_WifiCountryDialog import Ui_WifiCountryDialog
+
+
+class WifiCountryDialog(QDialog, Ui_WifiCountryDialog):
+    """
+    Class implementing a dialog to enter the country code for the WiFi interface.
+    """
+
+    def __init__(self, parent=None):
+        """
+        Constructor
+
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+        self.setupUi(self)
+
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(False)
+
+        self.countryEdit.setText(Preferences.getMicroPython("WifiCountry").upper())
+
+        msh = self.minimumSizeHint()
+        self.resize(max(self.width(), msh.width()), msh.height())
+
+    @pyqtSlot(str)
+    def on_countryEdit_textChanged(self, country):
+        """
+        Private slot handling a change of the country.
+
+        @param country entered country code
+        @type str
+        """
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
+            bool(country)
+        )
+
+    def getCountry(self):
+        """
+        Public method to get the entered country code.
+
+        @return tuple containing the country code and a flag indicating to save it to
+            the settings
+        @rtype tuple of (str, bool)
+        """
+        return self.countryEdit.text().upper(), self.rememberCheckBox.isChecked()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/WifiDialogs/WifiCountryDialog.ui	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>WifiCountryDialog</class>
+ <widget class="QDialog" name="WifiCountryDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>250</width>
+    <height>106</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>WiFi Country Code</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="label_13">
+     <property name="text">
+      <string>Country:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1">
+    <widget class="QLineEdit" name="countryEdit">
+     <property name="toolTip">
+      <string>Enter the country code for the WiFi interface</string>
+     </property>
+     <property name="maxLength">
+      <number>3</number>
+     </property>
+     <property name="clearButtonEnabled">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0" colspan="3">
+    <widget class="QCheckBox" name="rememberCheckBox">
+     <property name="toolTip">
+      <string>Select to remember the entered connection parameters</string>
+     </property>
+     <property name="text">
+      <string>Remember Parameters</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0" colspan="3">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <tabstops>
+  <tabstop>countryEdit</tabstop>
+  <tabstop>rememberCheckBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>WifiCountryDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>WifiCountryDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/WifiDialogs/WifiNetworksWindow.py	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,149 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog showing the available WiFi networks.
+"""
+
+from PyQt6.QtCore import Qt, QTimer, pyqtSlot
+from PyQt6.QtWidgets import QHeaderView, QTreeWidgetItem, QWidget
+
+from eric7.EricGui.EricOverrideCursor import EricOverrideCursor
+from eric7.EricWidgets import EricMessageBox
+
+from .Ui_WifiNetworksWindow import Ui_WifiNetworksWindow
+
+
+class WifiNetworksWindow(QWidget, Ui_WifiNetworksWindow):
+    """
+    Class implementing a dialog showing the available WiFi networks.
+    """
+
+    def __init__(self, device, parent=None):
+        """
+        Constructor
+
+        @param device reference to the connected device
+        @type BaseDevice
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+        self.setupUi(self)
+
+        windowFlags = self.windowFlags()
+        windowFlags |= Qt.WindowType.Window
+        windowFlags |= Qt.WindowType.WindowContextHelpButtonHint
+        self.setWindowFlags(windowFlags)
+
+        self.__device = device
+
+        self.__scanTimer = QTimer(self)
+        self.__scanTimer.timeout.connect(self.scanNetworks)
+
+        self.scanButton.clicked.connect(self.scanNetworks)
+
+        self.networkList.sortByColumn(0, Qt.SortOrder.AscendingOrder)
+
+    def scanNetworks(self):
+        """
+        Public method to ask the device for a network scan and display the result.
+        """
+        self.networkList.clear()
+        self.statusLabel.clear()
+
+        if not self.periodicCheckBox.isChecked():
+            self.scanButton.setEnabled(False)
+        with EricOverrideCursor():
+            networks, error = self.__device.scanNetworks()
+        if not self.periodicCheckBox.isChecked():
+            self.scanButton.setEnabled(True)
+
+        if error:
+            EricMessageBox.warning(
+                self,
+                self.tr("Scan WiFi Networks"),
+                self.tr(
+                    """<p>The scan for available WiFi networks failed.</p>"""
+                    """<p>Reason: {0}</p>"""
+                ),
+            )
+            if self.periodicCheckBox.isChecked():
+                self.periodicCheckBox.setChecked(False)
+
+        else:
+            self.statusLabel.setText(
+                self.tr("<p>Detected <b>%n</b> network(s).</p>", "", len(networks))
+            )
+            for network in networks:
+                itm = QTreeWidgetItem(
+                    self.networkList,
+                    [
+                        network[0],
+                        str(network[2]),
+                        network[1],
+                        str(network[3]),
+                        network[4],
+                    ],
+                )
+                itm.setTextAlignment(1, Qt.AlignmentFlag.AlignHCenter)
+                itm.setTextAlignment(2, Qt.AlignmentFlag.AlignHCenter)
+                itm.setTextAlignment(3, Qt.AlignmentFlag.AlignHCenter)
+
+            self.__resizeColumns()
+            self.__resort()
+
+    def __resort(self):
+        """
+        Private method to resort the networks list.
+        """
+        self.networkList.sortItems(
+            self.networkList.sortColumn(),
+            self.networkList.header().sortIndicatorOrder(),
+        )
+
+    def __resizeColumns(self):
+        """
+        Private method to resize the columns of the result list.
+        """
+        self.networkList.header().resizeSections(
+            QHeaderView.ResizeMode.ResizeToContents
+        )
+        self.networkList.header().setStretchLastSection(True)
+
+    def closeEvent(self, evt):
+        """
+        Protected method to handle a window close event.
+
+        @param evt reference to the close event
+        @type QCloseEvent
+        """
+        self.__scanTimer.stop()
+
+    @pyqtSlot(bool)
+    def on_periodicCheckBox_toggled(self, checked):
+        """
+        Private slot handling the selection of a periodic scan.
+
+        @param checked flag indicating a periodic scan
+        @type bool
+        """
+        self.scanButton.setEnabled(not checked)
+        if checked:
+            self.__scanTimer.setInterval(self.intervalSpinBox.value() * 1000)
+            self.__scanTimer.start()
+        else:
+            self.__scanTimer.stop()
+
+    @pyqtSlot(int)
+    def on_intervalSpinBox_valueChanged(self, interval):
+        """
+        Private slot handling a change of the periodic scan interval.
+
+        @param interval periodic scan interval
+        @type int
+        """
+        if self.periodicCheckBox.isChecked():
+            self.__scanTimer.setInterval(interval * 1000)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/WifiDialogs/WifiNetworksWindow.ui	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>WifiNetworksWindow</class>
+ <widget class="QWidget" name="WifiNetworksWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>650</width>
+    <height>600</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>WiFi Networks</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QTreeWidget" name="networkList">
+     <property name="alternatingRowColors">
+      <bool>true</bool>
+     </property>
+     <property name="selectionMode">
+      <enum>QAbstractItemView::NoSelection</enum>
+     </property>
+     <property name="rootIsDecorated">
+      <bool>false</bool>
+     </property>
+     <property name="itemsExpandable">
+      <bool>false</bool>
+     </property>
+     <property name="sortingEnabled">
+      <bool>true</bool>
+     </property>
+     <column>
+      <property name="text">
+       <string>Name</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>Channel</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>MAC-Address</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>RSSI [dBm]</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>Security</string>
+      </property>
+     </column>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLabel" name="statusLabel"/>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QPushButton" name="scanButton">
+       <property name="toolTip">
+        <string>Press to scan for available WiFi networks.</string>
+       </property>
+       <property name="text">
+        <string>Scan</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Scan Interval:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QSpinBox" name="intervalSpinBox">
+       <property name="alignment">
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+       <property name="suffix">
+        <string> s</string>
+       </property>
+       <property name="minimum">
+        <number>5</number>
+       </property>
+       <property name="maximum">
+        <number>120</number>
+       </property>
+       <property name="value">
+        <number>15</number>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QCheckBox" name="periodicCheckBox">
+       <property name="text">
+        <string>Periodic Scan</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Close</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <tabstops>
+  <tabstop>networkList</tabstop>
+  <tabstop>scanButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>WifiNetworksWindow</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>269</x>
+     <y>563</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>271</x>
+     <y>517</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/WifiDialogs/WifiStatusDialog.py	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,170 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog to show the WiFi status of the connected device.
+"""
+
+import contextlib
+
+from PyQt6.QtWidgets import QDialog, QTreeWidgetItem
+
+from .Ui_WifiStatusDialog import Ui_WifiStatusDialog
+
+
+class WifiStatusDialog(QDialog, Ui_WifiStatusDialog):
+    """
+    Class implementing a dialog to show the WiFi status of the connected device.
+    """
+
+    def __init__(self, clientStatus, apStatus, overallStatus, parent=None):
+        """
+        Constructor
+
+        @param clientStatus dictionary containing the WiFi status data of the
+            client interface
+        @type dict
+        @param apStatus dictionary containing the WiFi status data of the
+            access point interface
+        @type dict
+        @param overallStatus dictionary containing the overall WiFi status data
+        @type dict
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+        self.setupUi(self)
+
+        self.statusTree.setColumnCount(2)
+
+        # overall status
+        QTreeWidgetItem(
+            self.statusTree,
+            [
+                self.tr("Active"),
+                self.tr("Yes") if overallStatus["active"] else self.tr("No"),
+            ],
+        )
+
+        # client interface
+        if clientStatus:
+            header = self.__createHeader(self.tr("Client"))
+            QTreeWidgetItem(
+                header,
+                [
+                    self.tr("Active"),
+                    self.tr("Yes") if clientStatus["active"] else self.tr("No"),
+                ],
+            )
+            if clientStatus["active"]:
+                QTreeWidgetItem(
+                    header,
+                    [
+                        self.tr("Connected"),
+                        self.tr("Yes") if clientStatus["connected"] else self.tr("No"),
+                    ],
+                )
+                with contextlib.suppress(KeyError):
+                    QTreeWidgetItem(header, [self.tr("Status"), clientStatus["status"]])
+                with contextlib.suppress(KeyError):
+                    QTreeWidgetItem(
+                        header, [self.tr("Hostname"), clientStatus["hostname"]]
+                    )
+                QTreeWidgetItem(
+                    header, [self.tr("IPv4 Address"), clientStatus["ifconfig"][0]]
+                )
+                QTreeWidgetItem(
+                    header, [self.tr("Netmask"), clientStatus["ifconfig"][1]]
+                )
+                QTreeWidgetItem(
+                    header, [self.tr("Gateway"), clientStatus["ifconfig"][2]]
+                )
+                QTreeWidgetItem(header, [self.tr("DNS"), clientStatus["ifconfig"][3]])
+                QTreeWidgetItem(header, [self.tr("MAC-Address"), clientStatus["mac"]])
+                with contextlib.suppress(KeyError):
+                    QTreeWidgetItem(
+                        header, [self.tr("Channel"), str(clientStatus["channel"])]
+                    )
+                with contextlib.suppress(KeyError):
+                    QTreeWidgetItem(
+                        header, [self.tr("Country"), clientStatus["country"]]
+                    )
+                with contextlib.suppress(KeyError):
+                    QTreeWidgetItem(
+                        header,
+                        [
+                            self.tr("Tx-Power"),
+                            self.tr("{0} dBm").format(clientStatus["txpower"]),
+                        ],
+                    )
+
+        # access point interface
+        if apStatus:
+            header = self.__createHeader(self.tr("Access Point"))
+            QTreeWidgetItem(
+                header,
+                [
+                    self.tr("Active"),
+                    self.tr("Yes") if apStatus["active"] else self.tr("No"),
+                ],
+            )
+            if apStatus["active"]:
+                QTreeWidgetItem(
+                    header,
+                    [
+                        self.tr("Connected"),
+                        self.tr("Yes") if apStatus["connected"] else self.tr("No"),
+                    ],
+                )
+                with contextlib.suppress(KeyError):
+                    QTreeWidgetItem(header, [self.tr("Status"), apStatus["status"]])
+                with contextlib.suppress(KeyError):
+                    QTreeWidgetItem(header, [self.tr("Hostname"), apStatus["hostname"]])
+                QTreeWidgetItem(
+                    header, [self.tr("IPv4 Address"), apStatus["ifconfig"][0]]
+                )
+                QTreeWidgetItem(header, [self.tr("Netmask"), apStatus["ifconfig"][1]])
+                QTreeWidgetItem(header, [self.tr("Gateway"), apStatus["ifconfig"][2]])
+                QTreeWidgetItem(header, [self.tr("DNS"), apStatus["ifconfig"][3]])
+                with contextlib.suppress(KeyError):
+                    QTreeWidgetItem(header, [self.tr("SSID"), apStatus["essid"]])
+                QTreeWidgetItem(header, [self.tr("MAC-Address"), apStatus["mac"]])
+                with contextlib.suppress(KeyError):
+                    QTreeWidgetItem(
+                        header, [self.tr("Channel"), str(apStatus["channel"])]
+                    )
+                with contextlib.suppress(KeyError):
+                    QTreeWidgetItem(header, [self.tr("Country"), apStatus["country"]])
+                with contextlib.suppress(KeyError):
+                    QTreeWidgetItem(
+                        header,
+                        [
+                            self.tr("Tx-Power"),
+                            self.tr("{0} dBm").format(apStatus["txpower"]),
+                        ],
+                    )
+
+        for col in range(self.statusTree.columnCount()):
+            self.statusTree.resizeColumnToContents(col)
+
+    def __createHeader(self, headerText):
+        """
+        Private method to create a header item.
+
+        @param headerText text for the header item
+        @type str
+        @return reference to the created header item
+        @rtype QTreeWidgetItem
+        """
+        headerItem = QTreeWidgetItem(self.statusTree, [headerText])
+        headerItem.setExpanded(True)
+        headerItem.setFirstColumnSpanned(True)
+
+        font = headerItem.font(0)
+        font.setBold(True)
+
+        headerItem.setFont(0, font)
+
+        return headerItem
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/WifiDialogs/WifiStatusDialog.ui	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>WifiStatusDialog</class>
+ <widget class="QDialog" name="WifiStatusDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>600</width>
+    <height>650</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>WiFi Status</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QLabel" name="label">
+     <property name="font">
+      <font>
+       <pointsize>14</pointsize>
+       <bold>true</bold>
+      </font>
+     </property>
+     <property name="text">
+      <string>WiFi Status</string>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignCenter</set>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QTreeWidget" name="statusTree">
+     <property name="headerHidden">
+      <bool>true</bool>
+     </property>
+     <column>
+      <property name="text">
+       <string notr="true">1</string>
+      </property>
+     </column>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>WifiStatusDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>WifiStatusDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/WifiDialogs/__init__.py	Sat Feb 25 19:47:23 2023 +0100
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Package implementing WiFi related dialogs.
+"""
--- a/src/eric7/Preferences/ConfigurationPages/MicroPythonPage.py	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/Preferences/ConfigurationPages/MicroPythonPage.py	Sat Feb 25 19:47:23 2023 +0100
@@ -7,8 +7,11 @@
 Module implementing the MicroPython configuration page.
 """
 
+from PyQt6.QtCore import pyqtSlot
+from PyQt6.QtWidgets import QLineEdit
 
 from eric7 import Preferences
+from eric7.EricGui import EricPixmapCache
 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
 from eric7.MicroPython.MicroPythonWidget import AnsiColorSchemes
 from eric7.SystemUtilities import FileSystemUtilities, OSUtilities
@@ -38,6 +41,9 @@
         self.setupUi(self)
         self.setObjectName("MicroPythonPage")
 
+        self.showPasswordButton.setIcon(EricPixmapCache.getIcon("showPassword"))
+        self.apShowPasswordButton.setIcon(EricPixmapCache.getIcon("showPassword"))
+
         self.workspacePicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
 
         self.colorSchemeComboBox.addItems(sorted(AnsiColorSchemes.keys()))
@@ -78,6 +84,16 @@
         self.dfuUtilPathPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
         self.dfuUtilPathPicker.setFilters(self.tr("All Files (*)"))
 
+        # populate the WiFi security mode combo box
+        self.apSecurityComboBox.addItem(self.tr("open"), 0)
+        self.apSecurityComboBox.addItem("WEP", 1)
+        self.apSecurityComboBox.addItem("WPA", 2)
+        self.apSecurityComboBox.addItem("WPA2", 3)
+        self.apSecurityComboBox.addItem("WPA/WPA2", 4)
+        self.apSecurityComboBox.addItem("WPA2 (CCMP)", 5)
+        self.apSecurityComboBox.addItem("WPA3", 6)
+        self.apSecurityComboBox.addItem("WPA2/WPA3", 7)
+
         # set initial values
         # workspace
         self.workspacePicker.setText(
@@ -114,6 +130,23 @@
             index = 0
         self.chartThemeComboBox.setCurrentIndex(index)
 
+        # WiFi
+        self.countryEdit.setText(Preferences.getMicroPython("WifiCountry").upper())
+        self.ssidEdit.setText(Preferences.getMicroPython("WifiName"))
+        self.passwordEdit.setText(Preferences.getMicroPython("WifiPassword"))
+        self.apSsidEdit.setText(Preferences.getMicroPython("WifiApName"))
+        self.apPasswordEdit.setText(Preferences.getMicroPython("WifiApPassword"))
+        index = self.apSecurityComboBox.findData(
+            Preferences.getMicroPython("WifiApAuthMode")
+        )
+        if index == -1:
+            index = 5  # default it to WPA/WPA2 in case of an issue
+        self.apSecurityComboBox.setCurrentIndex(index)
+        self.apAddressEdit.setText(Preferences.getMicroPython("WifiApAddress"))
+        self.apNetmaskEdit.setText(Preferences.getMicroPython("WifiApNetmask"))
+        self.apGatewayEdit.setText(Preferences.getMicroPython("WifiApGateway"))
+        self.apDnsEdit.setText(Preferences.getMicroPython("WifiApDNS"))
+
         # MPY Cross Compiler
         self.mpyCrossPicker.setText(Preferences.getMicroPython("MpyCrossCompiler"))
 
@@ -194,6 +227,20 @@
             "ChartColorTheme", self.chartThemeComboBox.currentData()
         )
 
+        # WiFi
+        Preferences.setMicroPython("WifiCountry", self.countryEdit.text().upper())
+        Preferences.setMicroPython("WifiName", self.ssidEdit.text())
+        Preferences.setMicroPython("WifiPassword", self.passwordEdit.text())
+        Preferences.setMicroPython("WifiApName", self.apSsidEdit.text())
+        Preferences.setMicroPython("WifiApPassword", self.apPasswordEdit.text())
+        Preferences.setMicroPython(
+            "WifiApAuthMode", self.apSecurityComboBox.currentData()
+        )
+        Preferences.setMicroPython("WifiApAddress", self.apAddressEdit.text())
+        Preferences.setMicroPython("WifiApNetmask", self.apNetmaskEdit.text())
+        Preferences.setMicroPython("WifiApGateway", self.apGatewayEdit.text())
+        Preferences.setMicroPython("WifiApDNS", self.apDnsEdit.text())
+
         # MPY Cross Compiler
         Preferences.setMicroPython("MpyCrossCompiler", self.mpyCrossPicker.text())
 
@@ -244,6 +291,40 @@
             "CalliopeDocuUrl", self.calliopeDocuUrlLineEdit.text()
         )
 
+    @pyqtSlot(bool)
+    def on_showPasswordButton_clicked(self, checked):
+        """
+        Private slot to show or hide the WiFi client password.
+
+        @param checked state of the button
+        @type bool
+        """
+        if checked:
+            self.passwordEdit.setEchoMode(QLineEdit.EchoMode.Normal)
+            self.showPasswordButton.setIcon(EricPixmapCache.getIcon("hidePassword"))
+            self.showPasswordButton.setToolTip(self.tr("Press to hide the password"))
+        else:
+            self.passwordEdit.setEchoMode(QLineEdit.EchoMode.Password)
+            self.showPasswordButton.setIcon(EricPixmapCache.getIcon("showPassword"))
+            self.showPasswordButton.setToolTip(self.tr("Press to show the password"))
+
+    @pyqtSlot(bool)
+    def on_apShowPasswordButton_clicked(self, checked):
+        """
+        Private slot to show or hide the WiFi Access Point password.
+
+        @param checked state of the button
+        @type bool
+        """
+        if checked:
+            self.apPasswordEdit.setEchoMode(QLineEdit.EchoMode.Normal)
+            self.apShowPasswordButton.setIcon(EricPixmapCache.getIcon("hidePassword"))
+            self.apShowPasswordButton.setToolTip(self.tr("Press to hide the password"))
+        else:
+            self.apPasswordEdit.setEchoMode(QLineEdit.EchoMode.Password)
+            self.apShowPasswordButton.setIcon(EricPixmapCache.getIcon("showPassword"))
+            self.apShowPasswordButton.setToolTip(self.tr("Press to show the password"))
+
 
 def create(dlg):
     """
--- a/src/eric7/Preferences/ConfigurationPages/MicroPythonPage.ui	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/Preferences/ConfigurationPages/MicroPythonPage.ui	Sat Feb 25 19:47:23 2023 +0100
@@ -7,10 +7,10 @@
     <x>0</x>
     <y>0</y>
     <width>541</width>
-    <height>1293</height>
+    <height>1847</height>
    </rect>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout_2">
+  <layout class="QVBoxLayout" name="verticalLayout_3">
    <item>
     <widget class="QLabel" name="headerLabel">
      <property name="text">
@@ -208,6 +208,286 @@
     </widget>
    </item>
    <item>
+    <widget class="QGroupBox" name="groupBox_13">
+     <property name="title">
+      <string>WiFi</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_2">
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_5">
+        <item>
+         <widget class="QLabel" name="label_13">
+          <property name="text">
+           <string>Country:</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QLineEdit" name="countryEdit">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="toolTip">
+           <string>Enter the country code for the WiFi interface</string>
+          </property>
+          <property name="maxLength">
+           <number>3</number>
+          </property>
+          <property name="clearButtonEnabled">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <widget class="QGroupBox" name="groupBox_14">
+        <property name="title">
+         <string>Client</string>
+        </property>
+        <layout class="QGridLayout" name="gridLayout_8">
+         <item row="0" column="0">
+          <widget class="QLabel" name="label_8">
+           <property name="text">
+            <string>Name:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1" colspan="2">
+          <widget class="QLineEdit" name="ssidEdit">
+           <property name="toolTip">
+            <string>Enter the network name (SSID) to connect to</string>
+           </property>
+           <property name="clearButtonEnabled">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0">
+          <widget class="QLabel" name="label_9">
+           <property name="text">
+            <string>Password:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QLineEdit" name="passwordEdit">
+           <property name="toolTip">
+            <string>Enter the network password</string>
+           </property>
+           <property name="echoMode">
+            <enum>QLineEdit::Password</enum>
+           </property>
+           <property name="clearButtonEnabled">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="2">
+          <widget class="QToolButton" name="showPasswordButton">
+           <property name="toolTip">
+            <string>Press to show the password</string>
+           </property>
+           <property name="checkable">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </item>
+      <item>
+       <widget class="QGroupBox" name="groupBox_15">
+        <property name="title">
+         <string>Access Point</string>
+        </property>
+        <layout class="QGridLayout" name="gridLayout_10">
+         <item row="0" column="0">
+          <widget class="QLabel" name="label_10">
+           <property name="text">
+            <string>Name:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1" colspan="2">
+          <widget class="QLineEdit" name="apSsidEdit">
+           <property name="toolTip">
+            <string>Enter the network name (SSID) to publish</string>
+           </property>
+           <property name="clearButtonEnabled">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0">
+          <widget class="QLabel" name="label_12">
+           <property name="text">
+            <string>Password:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QLineEdit" name="apPasswordEdit">
+           <property name="toolTip">
+            <string>Enter the network password</string>
+           </property>
+           <property name="echoMode">
+            <enum>QLineEdit::Password</enum>
+           </property>
+           <property name="clearButtonEnabled">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="2">
+          <widget class="QToolButton" name="apShowPasswordButton">
+           <property name="toolTip">
+            <string>Press to show the password</string>
+           </property>
+           <property name="checkable">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="0">
+          <widget class="QLabel" name="label_23">
+           <property name="text">
+            <string>Security:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1" colspan="2">
+          <layout class="QHBoxLayout" name="horizontalLayout_6">
+           <item>
+            <widget class="QComboBox" name="apSecurityComboBox">
+             <property name="toolTip">
+              <string>Select the security mode</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <spacer name="horizontalSpacer_3">
+             <property name="orientation">
+              <enum>Qt::Horizontal</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>40</width>
+               <height>20</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+          </layout>
+         </item>
+         <item row="3" column="0" colspan="3">
+          <widget class="QGroupBox" name="ipv4GroupBox">
+           <property name="focusPolicy">
+            <enum>Qt::NoFocus</enum>
+           </property>
+           <property name="title">
+            <string>IPv4 Configuration</string>
+           </property>
+           <layout class="QHBoxLayout" name="horizontalLayout_7">
+            <item>
+             <layout class="QGridLayout" name="gridLayout_9">
+              <item row="0" column="0">
+               <widget class="QLabel" name="label_24">
+                <property name="text">
+                 <string>Address:</string>
+                </property>
+               </widget>
+              </item>
+              <item row="0" column="1">
+               <widget class="EricIPv4InputWidget" name="apAddressEdit" native="true">
+                <property name="focusPolicy">
+                 <enum>Qt::NoFocus</enum>
+                </property>
+               </widget>
+              </item>
+              <item row="1" column="0">
+               <widget class="QLabel" name="label_25">
+                <property name="text">
+                 <string>Netmask:</string>
+                </property>
+               </widget>
+              </item>
+              <item row="1" column="1">
+               <widget class="EricIPv4InputWidget" name="apNetmaskEdit" native="true">
+                <property name="focusPolicy">
+                 <enum>Qt::NoFocus</enum>
+                </property>
+               </widget>
+              </item>
+              <item row="2" column="0">
+               <widget class="QLabel" name="label_26">
+                <property name="text">
+                 <string>Gateway:</string>
+                </property>
+               </widget>
+              </item>
+              <item row="2" column="1">
+               <widget class="EricIPv4InputWidget" name="apGatewayEdit" native="true">
+                <property name="focusPolicy">
+                 <enum>Qt::NoFocus</enum>
+                </property>
+               </widget>
+              </item>
+              <item row="3" column="0">
+               <widget class="QLabel" name="label_27">
+                <property name="text">
+                 <string>DNS:</string>
+                </property>
+               </widget>
+              </item>
+              <item row="3" column="1">
+               <widget class="EricIPv4InputWidget" name="apDnsEdit" native="true">
+                <property name="focusPolicy">
+                 <enum>Qt::NoFocus</enum>
+                </property>
+               </widget>
+              </item>
+             </layout>
+            </item>
+            <item>
+             <spacer name="horizontalSpacer_4">
+              <property name="orientation">
+               <enum>Qt::Horizontal</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+               <size>
+                <width>273</width>
+                <height>20</height>
+               </size>
+              </property>
+             </spacer>
+            </item>
+           </layout>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
     <widget class="QGroupBox" name="groupBox_3">
      <property name="title">
       <string>MPY Cross Compiler</string>
@@ -545,6 +825,12 @@
    <header>eric7/EricWidgets/EricPathPicker.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>EricIPv4InputWidget</class>
+   <extends>QWidget</extends>
+   <header>eric7/EricNetwork/EricIPv4InputWidget.h</header>
+   <container>1</container>
+  </customwidget>
  </customwidgets>
  <tabstops>
   <tabstop>workspacePicker</tabstop>
@@ -554,6 +840,15 @@
   <tabstop>colorSchemeComboBox</tabstop>
   <tabstop>replWrapCheckBox</tabstop>
   <tabstop>chartThemeComboBox</tabstop>
+  <tabstop>countryEdit</tabstop>
+  <tabstop>ssidEdit</tabstop>
+  <tabstop>passwordEdit</tabstop>
+  <tabstop>showPasswordButton</tabstop>
+  <tabstop>apSsidEdit</tabstop>
+  <tabstop>apPasswordEdit</tabstop>
+  <tabstop>apShowPasswordButton</tabstop>
+  <tabstop>apSecurityComboBox</tabstop>
+  <tabstop>ipv4GroupBox</tabstop>
   <tabstop>mpyCrossPicker</tabstop>
   <tabstop>dfuUtilPathPicker</tabstop>
   <tabstop>micropythonFirmwareUrlLineEdit</tabstop>
--- a/src/eric7/Preferences/__init__.py	Sat Feb 25 19:43:06 2023 +0100
+++ b/src/eric7/Preferences/__init__.py	Sat Feb 25 19:47:23 2023 +0100
@@ -1576,6 +1576,16 @@
         "DfuUtilPath": "",  # path of the dfu-util flashing tool
         "IgnoredUnknownDevices": "[]",  # empty list encoded as JSON
         "ManualDevices": "[]",  # empty list encoded as JSON
+        "WifiName": "",
+        "WifiPassword": "",
+        "WifiApName": "",
+        "WifiApPassword": "",
+        "WifiApAuthMode": 4,  # WPA/WPA2
+        "WifiApAddress": "",
+        "WifiApNetmask": "",
+        "WifiApGateway": "",
+        "WifiApDNS": "",
+        "WifiCountry": "",
         # MicroPython URLs
         "MicroPythonDocuUrl": "https://docs.micropython.org/en/latest/",
         "MicroPythonFirmwareUrl": "http://micropython.org/download/",
@@ -3777,7 +3787,7 @@
     @param key the key of the value to get
     @return the requested MicroPython value
     """
-    if key in ("SerialTimeout", "ChartColorTheme"):
+    if key in ("SerialTimeout", "ChartColorTheme", "WifiApAuthMode"):
         return int(
             Prefs.settings.value("MicroPython/" + key, Prefs.microPythonDefaults[key])
         )
@@ -3799,6 +3809,11 @@
             return json.loads(jsonStr)
         else:
             return None
+    elif key in ("WifiPassword", "WifiApPassword"):
+        return pwConvert(
+            Prefs.settings.value("MicroPython/" + key, Prefs.microPythonDefaults[key]),
+            encode=False,
+        )
     else:
         return Prefs.settings.value(
             "MicroPython/" + key, Prefs.microPythonDefaults[key]
@@ -3814,6 +3829,8 @@
     """
     if key in ["IgnoredUnknownDevices", "ManualDevices"]:
         Prefs.settings.setValue("MicroPython/" + key, json.dumps(value))
+    elif key in ("WifiPassword", "WifiApPassword"):
+        Prefs.settings.setValue("MicroPython/" + key, pwConvert(value, encode=True))
     else:
         Prefs.settings.setValue("MicroPython/" + key, value)
 

eric ide

mercurial