src/eric7/MicroPython/RP2040Devices.py

branch
eric7
changeset 9747
b7976868d5b0
parent 9738
4ae976ee5339
child 9748
df9520c864f2
diff -r 37d460e32843 -r b7976868d5b0 src/eric7/MicroPython/RP2040Devices.py
--- a/src/eric7/MicroPython/RP2040Devices.py	Tue Feb 07 11:01:29 2023 +0100
+++ b/src/eric7/MicroPython/RP2040Devices.py	Tue Feb 07 18:07:12 2023 +0100
@@ -8,11 +8,14 @@
 (e.g. Raspberry Pi Pico).
 """
 
-from PyQt6.QtCore import pyqtSlot
+from PyQt6.QtCore import QUrl, pyqtSlot
+from PyQt6.QtNetwork import QNetworkRequest
 
-from eric7 import Preferences
+from eric7 import Globals, Preferences
+from eric7.EricWidgets import EricMessageBox
+from eric7.EricWidgets.EricApplication import ericApp
 
-from .MicroPythonDevices import MicroPythonDevice
+from .MicroPythonDevices import FirmwareGithubUrls, MicroPythonDevice
 from .MicroPythonWidget import HAS_QTCHART
 
 
@@ -121,10 +124,15 @@
         """
         connected = self.microPython.isConnected()
 
-        act = menu.addAction(self.tr("Activate Bootloader"), self.__activateBootloader)
-        act.setEnabled(connected)
-        act = menu.addAction(self.tr("Flash Firmware"), self.__flashPython)
-        act.setEnabled(not connected)
+        menu.addAction(
+            self.tr("Show MicroPython Versions"), self.__showFirmwareVersions
+        ).setEnabled(connected)
+        menu.addAction(
+            self.tr("Activate Bootloader"), self.__activateBootloader
+        ).setEnabled(connected)
+        menu.addAction(
+            self.tr("Flash MicroPython Firmware"), self.__flashPython
+        ).setEnabled(not connected)
 
     def hasFlashMenuEntry(self):
         """
@@ -159,6 +167,91 @@
             # simulate pressing the disconnect button
             self.microPython.on_connectButton_clicked()
 
+    @pyqtSlot()
+    def __showFirmwareVersions(self):
+        """
+        Private slot to show the firmware version of the connected device and the
+        available firmware version.
+        """
+        if self.microPython.isConnected():
+            interface = self.microPython.commandsInterface()
+            if interface is not None:
+                impInfo = interface.getImplementation()
+                if impInfo["name"] != "micropython":
+                    EricMessageBox.critical(
+                        None,
+                        self.tr("Show MicroPython Versions"),
+                        self.tr(
+                            """The firmware of the connected device cannot be"""
+                            """ determined or the board does not run MicroPython."""
+                            """ Aborting..."""
+                        ),
+                    )
+                else:
+                    if impInfo["variant"] == "Pimoroni":
+                        # MicroPython with Pimoroni add-on libraries
+                        url = QUrl(FirmwareGithubUrls["pimoroni_pico"])
+                    else:
+                        url = QUrl(FirmwareGithubUrls["micropython"])
+                    ui = ericApp().getObject("UserInterface")
+                    request = QNetworkRequest(url)
+                    reply = ui.networkAccessManager().head(request)
+                    reply.finished.connect(
+                        lambda: self.__firmwareVersionResponse(
+                            reply, impInfo
+                        )
+                    )
+
+    def __firmwareVersionResponse(self, reply, implementation):
+        """
+        Private method handling the response of the latest version request.
+
+        @param reply reference to the reply object
+        @type QNetworkReply
+        @param implementation dictionary containing the implementation data of the
+            connected device
+        @type dict
+        """
+        latestUrl = reply.url().toString()
+        tag = latestUrl.rsplit("/", 1)[-1]
+        while tag and not tag[0].isdecimal():
+            # get rid of leading non-decimal characters
+            tag = tag[1:]
+        latestVersion = Globals.versionToTuple(tag)
+
+        if implementation["version"] == "unknown":
+            currentVersionStr = self.tr("unknown")
+            currentVersion = (0, 0, 0)
+        else:
+            currentVersionStr = implementation["version"]
+            currentVersion = Globals.versionToTuple(currentVersionStr)
+
+        msg = self.tr(
+            "<h4>MicroPython Version Information</h4>"
+            "<table>"
+            "<tr><td>Installed:</td><td>{0}</td><td></td></tr>"
+            "<tr><td>Available:</td><td>{1}</td><td></td>{2}</tr>"
+            "</table>"
+        ).format(
+            currentVersionStr,
+            tag,
+            self.tr("({0})").format(implementation["variant"])
+            if implementation["variant"]
+            else "",
+        )
+        if (
+            implementation["variant"] not in ["Pimoroni"]
+            and currentVersion < latestVersion
+        ):
+            # cannot derive that info for 'Pimoroni' variant
+            msg += self.tr("<p><b>Update available!</b></p>")
+
+        EricMessageBox.information(
+            None,
+            self.tr("MicroPython Version"),
+            msg,
+        )
+
     def getDocumentationUrl(self):
         """
         Public method to get the device documentation URL.
@@ -183,6 +276,10 @@
             ),
             ("<separator>", ""),
             (
+                self.tr("Pimoroni Pico Firmware"), FirmwareGithubUrls["pimoroni_pico"]
+            ), 
+            ("<separator>", ""),
+            (
                 self.tr("CircuitPython Firmware"),
                 Preferences.getMicroPython("CircuitPythonFirmwareUrl"),
             ),

eric ide

mercurial