diff -r 1a09700229e7 -r 9854647c8c5c src/eric7/MicroPython/Devices/GenericMicroPythonDevices.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/eric7/MicroPython/Devices/GenericMicroPythonDevices.py Mon Feb 13 17:49:52 2023 +0100 @@ -0,0 +1,227 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2021 - 2023 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing the device interface class for generic MicroPython devices +(i.e. those devices not specifically supported yet). +""" + +import os + +from eric7 import Preferences +from eric7.EricWidgets import EricMessageBox +from eric7.SystemUtilities import FileSystemUtilities + +from .DeviceBase import BaseDevice +from .MicroPythonWidget import HAS_QTCHART + + +class GenericMicroPythonDevice(BaseDevice): + """ + Class implementing the device interface for generic MicroPython boards. + """ + + def __init__(self, microPythonWidget, deviceType, vid, pid, parent=None): + """ + Constructor + + @param microPythonWidget reference to the main MicroPython widget + @type MicroPythonWidget + @param deviceType device type assigned to this device interface + @type str + @param vid vendor ID + @type int + @param pid product ID + @type int + @param parent reference to the parent object + @type QObject + """ + super().__init__(microPythonWidget, deviceType, parent) + + self.__directAccess = False + self.__deviceVolumeName = "" + self.__workspace = "" + self.__deviceName = "" + + for deviceData in Preferences.getMicroPython("ManualDevices"): + if deviceData["vid"] == vid and deviceData["pid"] == pid: + self.__deviceVolumeName = deviceData["data_volume"] + self.__directAccess = bool(deviceData["data_volume"]) + self.__deviceName = deviceData["description"] + + if self.__directAccess: + self.__workspace = self.__findWorkspace() + + def setButtons(self): + """ + Public method to enable the supported action buttons. + """ + super().setButtons() + self.microPython.setActionButtons( + run=True, repl=True, files=True, chart=HAS_QTCHART + ) + + if self.__directAccess and self.__deviceVolumeMounted(): + self.microPython.setActionButtons(open=True, save=True) + + def deviceName(self): + """ + Public method to get the name of the device. + + @return name of the device + @rtype str + """ + return self.__deviceName + + def canStartRepl(self): + """ + Public method to determine, if a REPL can be started. + + @return tuple containing a flag indicating it is safe to start a REPL + and a reason why it cannot. + @rtype tuple of (bool, str) + """ + return True, "" + + def canStartPlotter(self): + """ + Public method to determine, if a Plotter can be started. + + @return tuple containing a flag indicating it is safe to start a + Plotter and a reason why it cannot. + @rtype tuple of (bool, str) + """ + return True, "" + + def canRunScript(self): + """ + Public method to determine, if a script can be executed. + + @return tuple containing a flag indicating it is safe to start a + Plotter and a reason why it cannot. + @rtype tuple of (bool, str) + """ + return True, "" + + def runScript(self, script): + """ + Public method to run the given Python script. + + @param script script to be executed + @type str + """ + pythonScript = script.split("\n") + self.sendCommands(pythonScript) + + def canStartFileManager(self): + """ + Public method to determine, if a File Manager can be started. + + @return tuple containing a flag indicating it is safe to start a + File Manager and a reason why it cannot. + @rtype tuple of (bool, str) + """ + return True, "" + + def supportsLocalFileAccess(self): + """ + Public method to indicate file access via a local directory. + + @return flag indicating file access via local directory + @rtype bool + """ + return self.__deviceVolumeMounted() + + def __deviceVolumeMounted(self): + """ + Private method to check, if the device volume is mounted. + + @return flag indicated a mounted device + @rtype bool + """ + if self.__workspace and not os.path.exists(self.__workspace): + self.__workspace = "" # reset + + return self.__directAccess and self.__deviceVolumeName in self.getWorkspace( + silent=True + ) + + def getWorkspace(self, silent=False): + """ + Public method to get the workspace directory. + + @param silent flag indicating silent operations + @type bool + @return workspace directory used for saving files + @rtype str + """ + if self.__directAccess: + if self.__workspace: + # return cached entry + return self.__workspace + else: + self.__workspace = self.__findWorkspace(silent=silent) + return self.__workspace + else: + return super().getWorkspace() + + def __findWorkspace(self, silent=False): + """ + Private method to find the workspace directory. + + @param silent flag indicating silent operations + @type bool + @return workspace directory used for saving files + @rtype str + """ + # Attempts to find the path on the filesystem that represents the + # plugged in board. + deviceDirectories = FileSystemUtilities.findVolume( + self.__deviceVolumeName, findAll=True + ) + + if deviceDirectories: + if len(deviceDirectories) == 1: + return deviceDirectories[0] + else: + return self.selectDeviceDirectory(deviceDirectories) + else: + # return the default workspace and give the user a warning (unless + # silent mode is selected) + if not silent: + EricMessageBox.warning( + self.microPython, + self.tr("Workspace Directory"), + self.tr( + "Python files for this generic board can be" + " edited in place, if the device volume is locally" + " available. A volume named '{0}' was not found." + " In place editing will not be available." + ).format(self.__deviceVolumeName), + ) + + return super().getWorkspace() + + +def createDevice(microPythonWidget, deviceType, vid, pid, boardName, serialNumber): + """ + Function to instantiate a MicroPython device object. + + @param microPythonWidget reference to the main MicroPython widget + @type MicroPythonWidget + @param deviceType device type assigned to this device interface + @type str + @param vid vendor ID + @type int + @param pid product ID + @type int + @param boardName name of the board + @type str + @param serialNumber serial number of the board + @type str + @return reference to the instantiated device object + @rtype GenericMicroPythonDevice + """ + return GenericMicroPythonDevice(microPythonWidget, deviceType, vid, pid)