src/eric7/MicroPython/EthernetDialogs/EthernetController.py

branch
mpy_network
changeset 9878
a82014a9e57b
child 9885
05cbf70e8f10
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/EthernetDialogs/EthernetController.py	Sun Mar 12 14:56:04 2023 +0100
@@ -0,0 +1,337 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the Ethernet related functionality.
+"""
+
+from PyQt6.QtCore import QObject, pyqtSlot
+from PyQt6.QtWidgets import QDialog, QMenu
+
+from eric7.EricGui.EricOverrideCursor import EricOverrideCursor
+from eric7.EricWidgets import EricMessageBox
+
+
+class EthernetController(QObject):
+    """
+    Class implementing the Ethernet 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 Ethernet submenu.
+
+        @param menu reference to the parent menu
+        @type QMenu
+        @return reference to the created menu
+        @rtype QMenu
+        """
+        ethernetMenu = QMenu(self.tr("Ethernet Functions"), menu)
+        ethernetMenu.setTearOffEnabled(True)
+        ethernetMenu.addAction(
+            self.tr("Show Ethernet Status"), self.__showEthernetStatus
+        )
+        ethernetMenu.addSeparator()
+        ethernetMenu.addAction(self.tr("Connect to LAN (DHCP)"), self.__connectLanDhcp)
+        ethernetMenu.addAction(
+            self.tr("Connect to LAN (fixed IP)"), self.__connectLanIp
+        )
+        ethernetMenu.addAction(
+            self.tr("Check Internet Connection"), self.__checkInternet
+        )
+        ethernetMenu.addAction(self.tr("Disconnect from LAN"), self.__disconnectLan)
+        ethernetMenu.addSeparator()
+        ethernetMenu.addAction(
+            self.tr("Write Auto-Connect Script"), self.__writeAutoConnect
+        )
+        ethernetMenu.addAction(
+            self.tr("Remove Auto-Connect Script"), self.__removeAutoConnect
+        )
+        ethernetMenu.addSeparator()
+        ethernetMenu.addAction(
+            self.tr("Deactivate Ethernet Interface"), self.__deactivateEthernet
+        )
+        ethernetMenu.addSeparator()
+        ethernetMenu.addAction(self.tr("Set Network Time"), self.__setNetworkTime)
+
+        # add device specific entries (if there are any)
+        self.__mpy.getDevice().addDeviceEthernetEntries(ethernetMenu)
+
+        return ethernetMenu
+
+    @pyqtSlot()
+    def __showEthernetStatus(self):
+        """
+        Private slot to show a dialog with the WiFi status of the current device.
+        """
+        from .EthernetStatusDialog import EthernetStatusDialog
+
+        try:
+            status = self.__mpy.getDevice().getEthernetStatus()
+            # status is a list of user labels and associated values
+
+            dlg = EthernetStatusDialog(status, self.__mpy)
+            dlg.exec()
+        except Exception as exc:
+            self.__mpy.showError("getEthernetStatus()", str(exc))
+
+    @pyqtSlot()
+    def __connectLanDhcp(self):
+        """
+        Private slot to connect to the LAN with a dynamic IPv4 address (DHCP mode).
+        """
+        self.__connectLan("dhcp")
+
+    @pyqtSlot()
+    def __connectLanIp(self):
+        """
+        Private slot to connect to the LAN with a fixed IPv4 address (fixed address
+        mode).
+        """
+        from .IPv4AddressDialog import IPv4AddressDialog
+
+        dlg = IPv4AddressDialog(withDhcp=False, parent=self.__mpy)
+        if dlg.exec() == QDialog.DialogCode.Accepted:
+            ifconfig = dlg.getIPv4Address()
+            self.__connectLan(ifconfig)
+
+    def __connectLan(self, config):
+        """
+        Private method to connect the connected device to the LAN.
+
+        @param config configuration for the connection (either the string 'dhcp'
+            for a dynamic address or a tuple of four strings with the IPv4 parameters.
+        @type str of tuple of (str, str, str, str)
+        """
+        success, error = self.__mpy.getDevice().connectToLan(config)
+        if success:
+            EricMessageBox.information(
+                None,
+                self.tr("Connect to LAN"),
+                self.tr("<p>The device was connected to the LAN successfully.</p>"),
+            )
+        else:
+            EricMessageBox.critical(
+                None,
+                self.tr("Connect to LAN"),
+                self.tr(
+                    "<p>The device could not connect to the LAN.</p><p>Reason: {0}</p>"
+                ).format(error if error else self.tr("unknown")),
+            )
+
+    @pyqtSlot()
+    def __disconnectLan(self):
+        """
+        Private slot to disconnect from the LAN.
+        """
+        success, error = self.__mpy.getDevice().disconnectFromLan()
+        if success:
+            EricMessageBox.information(
+                None,
+                self.tr("Disconnect from LAN"),
+                self.tr("<p>The device was disconnected from the LAN.</p>"),
+            )
+        else:
+            EricMessageBox.critical(
+                None,
+                self.tr("Disconnect from LAN"),
+                self.tr(
+                    "<p>The device could not be disconnected from the LAN.</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().checkInternetViaLan()
+        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 __writeAutoConnect(self):
+        """
+        Private slot to generate a script and associated configuration to connect the
+        device during boot time.
+
+        This will also modify the boot script to perform the automatic connection.
+        """
+        from .IPv4AddressDialog import IPv4AddressDialog
+
+        dlg = IPv4AddressDialog(withDhcp=True, parent=self.__mpy)
+        if dlg.exec() == QDialog.DialogCode.Accepted:
+            ifconfig = dlg.getIPv4Address()
+            ok, err = self.__mpy.getDevice().writeLanAutoConnect(ifconfig)
+            if ok:
+                EricMessageBox.information(
+                    None,
+                    self.tr("Write Auto-Connect Script"),
+                    self.tr(
+                        "<p>The auto-connect script and associated configuration was"
+                        " saved on the device. The device will connect to the LAN at"
+                        " boot time.</p>"
+                    ),
+                )
+            else:
+                EricMessageBox.critical(
+                    None,
+                    self.tr("Write Auto-Connect Script"),
+                    self.tr(
+                        "<p>The auto-connect script and associated configuration could"
+                        " not be saved on the device.</p><p>Reason: {0}</p>"
+                    ).format(err if err else self.tr("unknown")),
+                )
+
+    @pyqtSlot()
+    def __removeAutoConnect(self):
+        """
+        Private slot to remove the boot time connect capability.
+
+        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 Auto-Connect Script"),
+            self.tr(
+                "Shall the saved IPv4 parameters really be removed from the connected"
+                " device?"
+            ),
+        )
+        if ok:
+            ok, err = self.__mpy.getDevice().removeLanAutoConnect()
+            if ok:
+                EricMessageBox.information(
+                    None,
+                    self.tr("Remove Auto-Connect Script"),
+                    self.tr(
+                        "<p>The IPv4 parameters were removed from the device. The"
+                        " device will not connect to the LAN at boot time anymore.</p>"
+                    ),
+                )
+            else:
+                EricMessageBox.critical(
+                    None,
+                    self.tr("Remove Auto-Connect Script"),
+                    self.tr(
+                        "<p>The IPv4 parameters could not be removed from the device."
+                        "</p><p>Reason: {0}</p>"
+                    ).format(err if err else self.tr("unknown")),
+                )
+
+    @pyqtSlot()
+    def __deactivateEthernet(self):
+        """
+        Private slot to deactivate the Ethernet interface.
+        """
+        ok, err = self.__mpy.getDevice().deactivateEthernet()
+        if ok:
+            EricMessageBox.information(
+                None,
+                self.tr("Deactivate Ethernet Interface"),
+                self.tr("The Ethernet interface was deactivated successfully."),
+            )
+        else:
+            msg = self.tr("<p>The Ethernet interface could not be deactivated.</p>")
+            if err:
+                msg += self.tr("<p>Reason: {0}</p>").format(err)
+            EricMessageBox.critical(
+                None,
+                self.tr("Deactivate Ethernet Interface"),
+                msg,
+            )
+
+    @pyqtSlot()
+    def __setNetworkTime(self):
+        """
+        Private slot to synchronize the device clock to network time.
+        """
+        from ..NtpParametersDialog import NtpParametersDialog
+
+        device = self.__mpy.getDevice()
+        if not device.getDeviceData("ntp"):
+            if device.hasCircuitPython():
+                EricMessageBox.warning(
+                    None,
+                    self.tr("Set Network Time"),
+                    self.tr(
+                        "<p>The device does not support network time synchronization."
+                        " The module <b>adafruit_ntp</b> is not installed.</p>"
+                    ),
+                )
+            else:
+                EricMessageBox.critical(
+                    None,
+                    self.tr("Set Network Time"),
+                    self.tr(
+                        "<p>The device does not support network time synchronization."
+                        " The module <b>ntptime</b> is not available.</p>"
+                    ),
+                )
+            return
+
+        dlg = NtpParametersDialog(self.__mpy)
+        if dlg.exec() == QDialog.DialogCode.Accepted:
+            server, tzOffset, isDst, timeout = dlg.getParameters()
+            if isDst:
+                tzOffset += 1
+
+            ok, err = self.__mpy.getDevice().setNetworkTime(
+                server=server, tzOffset=tzOffset, timeout=timeout
+            )
+            if ok:
+                EricMessageBox.information(
+                    None,
+                    self.tr("Set Network Time"),
+                    self.tr("The device time was synchronized successfully."),
+                )
+            else:
+                if err:
+                    msg = self.tr(
+                        "<p>The device time could not be synchronized.</p>"
+                        "<p>Reason: {0}</p>"
+                    ).format(err)
+                else:
+                    msg = self.tr(
+                        "<p>The device time could not be synchronized. Is the device"
+                        " connected to a LAN?</p>"
+                    )
+                EricMessageBox.critical(
+                    None,
+                    self.tr("Set Network Time"),
+                    msg,
+                )

eric ide

mercurial