Fri, 28 Apr 2023 12:07:41 +0200
MicroPython
- Refactored the code by introducing a device interface base class and changed the interface instantiation logic to prepare the basis for developing the 'webrepl' interface.
--- a/Dictionaries/words.dic Thu Apr 27 17:59:09 2023 +0200 +++ b/Dictionaries/words.dic Fri Apr 28 12:07:41 2023 +0200 @@ -8,3 +8,4 @@ param keyparam rtype +instantiation
--- a/eric7.epj Thu Apr 27 17:59:09 2023 +0200 +++ b/eric7.epj Fri Apr 28 12:07:41 2023 +0200 @@ -1347,6 +1347,7 @@ "src/eric7/MicroPython/MicroPythonFileSystemUtilities.py", "src/eric7/MicroPython/MicroPythonGraphWidget.py", "src/eric7/MicroPython/MicroPythonProgressInfoDialog.py", + "src/eric7/MicroPython/MicroPythonSerialDeviceInterface.py", "src/eric7/MicroPython/MicroPythonSerialPort.py", "src/eric7/MicroPython/MicroPythonWidget.py", "src/eric7/MicroPython/MipLocalInstaller.py",
--- a/src/eric7/APIs/Python3/eric7.api Thu Apr 27 17:59:09 2023 +0200 +++ b/src/eric7/APIs/Python3/eric7.api Fri Apr 28 12:07:41 2023 +0200 @@ -2955,9 +2955,7 @@ eric7.MicroPython.EthernetDialogs.WiznetUtilities.mpyWiznetInit?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.connectToDevice?4(connection) eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.dataReceived?7 eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.disconnectFromDevice?4() eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.execute?4(commands, *, mode="raw", timeout=0) @@ -3037,6 +3035,17 @@ eric7.MicroPython.MicroPythonGraphWidget.MicroPythonGraphWidget?1(parent=None) eric7.MicroPython.MicroPythonProgressInfoDialog.MicroPythonProgressInfoDialog.addMessage?4(message) eric7.MicroPython.MicroPythonProgressInfoDialog.MicroPythonProgressInfoDialog?1(parent=None) +eric7.MicroPython.MicroPythonSerialDeviceInterface.MicroPythonSerialDeviceInterface.PasteModePrompt?7 +eric7.MicroPython.MicroPythonSerialDeviceInterface.MicroPythonSerialDeviceInterface.TracebackMarker?7 +eric7.MicroPython.MicroPythonSerialDeviceInterface.MicroPythonSerialDeviceInterface.connectToDevice?4(connection) +eric7.MicroPython.MicroPythonSerialDeviceInterface.MicroPythonSerialDeviceInterface.disconnectFromDevice?4() +eric7.MicroPython.MicroPythonSerialDeviceInterface.MicroPythonSerialDeviceInterface.execute?4(commands, *, mode="raw", timeout=0) +eric7.MicroPython.MicroPythonSerialDeviceInterface.MicroPythonSerialDeviceInterface.executeAsync?4(commandsList, submitMode) +eric7.MicroPython.MicroPythonSerialDeviceInterface.MicroPythonSerialDeviceInterface.handlePreferencesChanged?4() +eric7.MicroPython.MicroPythonSerialDeviceInterface.MicroPythonSerialDeviceInterface.isConnected?4() +eric7.MicroPython.MicroPythonSerialDeviceInterface.MicroPythonSerialDeviceInterface.probeDevice?4() +eric7.MicroPython.MicroPythonSerialDeviceInterface.MicroPythonSerialDeviceInterface.write?4(data) +eric7.MicroPython.MicroPythonSerialDeviceInterface.MicroPythonSerialDeviceInterface?1(parent=None) eric7.MicroPython.MicroPythonSerialPort.MicroPythonSerialPort.closeSerialLink?4() eric7.MicroPython.MicroPythonSerialPort.MicroPythonSerialPort.hasTimedOut?4() eric7.MicroPython.MicroPythonSerialPort.MicroPythonSerialPort.isConnected?4() @@ -3046,6 +3055,7 @@ eric7.MicroPython.MicroPythonSerialPort.MicroPythonSerialPort?1(timeout=10000, parent=None) eric7.MicroPython.MicroPythonWidget.AnsiColorSchemes?7 eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.DeviceBoardRole?7 +eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.DeviceInterfaceTypeRole?7 eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.DevicePidRole?7 eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.DevicePortRole?7 eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.DeviceSerNoRole?7 @@ -3058,7 +3068,6 @@ eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.deviceInterface?4() eric7.MicroPython.MicroPythonWidget.MicroPythonWidget.deviceSupportsLocalFileAccess?4() 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()
--- a/src/eric7/APIs/Python3/eric7.bas Thu Apr 27 17:59:09 2023 +0200 +++ b/src/eric7/APIs/Python3/eric7.bas Fri Apr 28 12:07:41 2023 +0200 @@ -664,6 +664,7 @@ MicroPythonGraphWidget QWidget MicroPythonPage ConfigurationPageBase Ui_MicroPythonPage MicroPythonProgressInfoDialog QDialog Ui_MicroPythonProgressInfoDialog +MicroPythonSerialDeviceInterface MicroPythonDeviceInterface MicroPythonSerialPort QSerialPort MicroPythonWidget QWidget Ui_MicroPythonWidget MicrobitDevice BaseDevice
--- a/src/eric7/Documentation/Help/source.qhp Thu Apr 27 17:59:09 2023 +0200 +++ b/src/eric7/Documentation/Help/source.qhp Fri Apr 28 12:07:41 2023 +0200 @@ -327,6 +327,7 @@ <section title="eric7.MicroPython.MicroPythonFileSystemUtilities" ref="eric7.MicroPython.MicroPythonFileSystemUtilities.html" /> <section title="eric7.MicroPython.MicroPythonGraphWidget" ref="eric7.MicroPython.MicroPythonGraphWidget.html" /> <section title="eric7.MicroPython.MicroPythonProgressInfoDialog" ref="eric7.MicroPython.MicroPythonProgressInfoDialog.html" /> + <section title="eric7.MicroPython.MicroPythonSerialDeviceInterface" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html" /> <section title="eric7.MicroPython.MicroPythonSerialPort" ref="eric7.MicroPython.MicroPythonSerialPort.html" /> <section title="eric7.MicroPython.MicroPythonWidget" ref="eric7.MicroPython.MicroPythonWidget.html" /> <section title="eric7.MicroPython.MipLocalInstaller" ref="eric7.MicroPython.MipLocalInstaller.html" /> @@ -10793,15 +10794,6 @@ <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.__executeAsyncPaste" id="MicroPythonDeviceInterface.__executeAsyncPaste" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.__executeAsyncPaste" /> - <keyword name="MicroPythonDeviceInterface.__executeAsyncRaw" id="MicroPythonDeviceInterface.__executeAsyncRaw" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.__executeAsyncRaw" /> - <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" /> <keyword name="MicroPythonDeviceInterface.connectToDevice" id="MicroPythonDeviceInterface.connectToDevice" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.connectToDevice" /> <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" /> @@ -10903,6 +10895,26 @@ <keyword name="MicroPythonProgressInfoDialog (Constructor)" id="MicroPythonProgressInfoDialog (Constructor)" ref="eric7.MicroPython.MicroPythonProgressInfoDialog.html#MicroPythonProgressInfoDialog.__init__" /> <keyword name="MicroPythonProgressInfoDialog (Module)" id="MicroPythonProgressInfoDialog (Module)" ref="eric7.MicroPython.MicroPythonProgressInfoDialog.html" /> <keyword name="MicroPythonProgressInfoDialog.addMessage" id="MicroPythonProgressInfoDialog.addMessage" ref="eric7.MicroPython.MicroPythonProgressInfoDialog.html#MicroPythonProgressInfoDialog.addMessage" /> + <keyword name="MicroPythonSerialDeviceInterface" id="MicroPythonSerialDeviceInterface" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface" /> + <keyword name="MicroPythonSerialDeviceInterface (Constructor)" id="MicroPythonSerialDeviceInterface (Constructor)" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.__init__" /> + <keyword name="MicroPythonSerialDeviceInterface (Module)" id="MicroPythonSerialDeviceInterface (Module)" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html" /> + <keyword name="MicroPythonSerialDeviceInterface.__executeAsyncPaste" id="MicroPythonSerialDeviceInterface.__executeAsyncPaste" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.__executeAsyncPaste" /> + <keyword name="MicroPythonSerialDeviceInterface.__executeAsyncRaw" id="MicroPythonSerialDeviceInterface.__executeAsyncRaw" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.__executeAsyncRaw" /> + <keyword name="MicroPythonSerialDeviceInterface.__execute_paste" id="MicroPythonSerialDeviceInterface.__execute_paste" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.__execute_paste" /> + <keyword name="MicroPythonSerialDeviceInterface.__execute_raw" id="MicroPythonSerialDeviceInterface.__execute_raw" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.__execute_raw" /> + <keyword name="MicroPythonSerialDeviceInterface.__pasteOff" id="MicroPythonSerialDeviceInterface.__pasteOff" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.__pasteOff" /> + <keyword name="MicroPythonSerialDeviceInterface.__pasteOn" id="MicroPythonSerialDeviceInterface.__pasteOn" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.__pasteOn" /> + <keyword name="MicroPythonSerialDeviceInterface.__rawOff" id="MicroPythonSerialDeviceInterface.__rawOff" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.__rawOff" /> + <keyword name="MicroPythonSerialDeviceInterface.__rawOn" id="MicroPythonSerialDeviceInterface.__rawOn" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.__rawOn" /> + <keyword name="MicroPythonSerialDeviceInterface.__readSerial" id="MicroPythonSerialDeviceInterface.__readSerial" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.__readSerial" /> + <keyword name="MicroPythonSerialDeviceInterface.connectToDevice" id="MicroPythonSerialDeviceInterface.connectToDevice" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.connectToDevice" /> + <keyword name="MicroPythonSerialDeviceInterface.disconnectFromDevice" id="MicroPythonSerialDeviceInterface.disconnectFromDevice" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.disconnectFromDevice" /> + <keyword name="MicroPythonSerialDeviceInterface.execute" id="MicroPythonSerialDeviceInterface.execute" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.execute" /> + <keyword name="MicroPythonSerialDeviceInterface.executeAsync" id="MicroPythonSerialDeviceInterface.executeAsync" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.executeAsync" /> + <keyword name="MicroPythonSerialDeviceInterface.handlePreferencesChanged" id="MicroPythonSerialDeviceInterface.handlePreferencesChanged" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.handlePreferencesChanged" /> + <keyword name="MicroPythonSerialDeviceInterface.isConnected" id="MicroPythonSerialDeviceInterface.isConnected" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.isConnected" /> + <keyword name="MicroPythonSerialDeviceInterface.probeDevice" id="MicroPythonSerialDeviceInterface.probeDevice" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.probeDevice" /> + <keyword name="MicroPythonSerialDeviceInterface.write" id="MicroPythonSerialDeviceInterface.write" ref="eric7.MicroPython.MicroPythonSerialDeviceInterface.html#MicroPythonSerialDeviceInterface.write" /> <keyword name="MicroPythonSerialPort" id="MicroPythonSerialPort" ref="eric7.MicroPython.MicroPythonSerialPort.html#MicroPythonSerialPort" /> <keyword name="MicroPythonSerialPort (Constructor)" id="MicroPythonSerialPort (Constructor)" ref="eric7.MicroPython.MicroPythonSerialPort.html#MicroPythonSerialPort.__init__" /> <keyword name="MicroPythonSerialPort (Module)" id="MicroPythonSerialPort (Module)" ref="eric7.MicroPython.MicroPythonSerialPort.html" /> @@ -10955,7 +10967,6 @@ <keyword name="MicroPythonWidget.deviceInterface" id="MicroPythonWidget.deviceInterface" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.deviceInterface" /> <keyword name="MicroPythonWidget.deviceSupportsLocalFileAccess" id="MicroPythonWidget.deviceSupportsLocalFileAccess" ref="eric7.MicroPython.MicroPythonWidget.html#MicroPythonWidget.deviceSupportsLocalFileAccess" /> <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" /> @@ -20569,6 +20580,7 @@ <file>eric7.MicroPython.MicroPythonFileSystemUtilities.html</file> <file>eric7.MicroPython.MicroPythonGraphWidget.html</file> <file>eric7.MicroPython.MicroPythonProgressInfoDialog.html</file> + <file>eric7.MicroPython.MicroPythonSerialDeviceInterface.html</file> <file>eric7.MicroPython.MicroPythonSerialPort.html</file> <file>eric7.MicroPython.MicroPythonWidget.html</file> <file>eric7.MicroPython.MipLocalInstaller.html</file>
--- a/src/eric7/Documentation/Source/eric7.MicroPython.MicroPythonDeviceInterface.html Thu Apr 27 17:59:09 2023 +0200 +++ b/src/eric7/Documentation/Source/eric7.MicroPython.MicroPythonDeviceInterface.html Fri Apr 28 12:07:41 2023 +0200 @@ -9,7 +9,7 @@ <h1>eric7.MicroPython.MicroPythonDeviceInterface</h1> <p> -Module implementing some file system commands for MicroPython. +Module implementing an interface base class to talk to a connected MicroPython device. </p> <h3>Global Attributes</h3> @@ -43,8 +43,8 @@ <dt>dataReceived(data)</dt> <dd> -emitted to send data received via the serial - connection for further processing +emitted to send data received via the connection + for further processing </dd> <dt>executeAsyncFinished()</dt> <dd> @@ -57,7 +57,7 @@ <h3>Class Attributes</h3> <table> -<tr><td>PasteModePrompt</td></tr><tr><td>TracebackMarker</td></tr> +<tr><td>None</td></tr> </table> <h3>Class Methods</h3> @@ -73,48 +73,12 @@ <td>Constructor</td> </tr> <tr> -<td><a href="#MicroPythonDeviceInterface.__executeAsyncPaste">__executeAsyncPaste</a></td> -<td>Private 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.__executeAsyncRaw">__executeAsyncRaw</a></td> -<td>Private 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.__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> -<tr> -<td><a href="#MicroPythonDeviceInterface.__rawOn">__rawOn</a></td> -<td>Private method to switch the connected device to 'raw' mode.</td> -</tr> -<tr> -<td><a href="#MicroPythonDeviceInterface.__readSerial">__readSerial</a></td> -<td>Private slot to read all available serial data and emit it with the "dataReceived" signal for further processing.</td> -</tr> -<tr> <td><a href="#MicroPythonDeviceInterface.connectToDevice">connectToDevice</a></td> -<td>Public slot to start the manager.</td> +<td>Public slot to connect to the device.</td> </tr> <tr> <td><a href="#MicroPythonDeviceInterface.disconnectFromDevice">disconnectFromDevice</a></td> -<td>Public slot to stop the thread.</td> +<td>Public slot to disconnect from the device.</td> </tr> <tr> <td><a href="#MicroPythonDeviceInterface.execute">execute</a></td> @@ -161,184 +125,18 @@ reference to the parent object </dd> </dl> -<a NAME="MicroPythonDeviceInterface.__executeAsyncPaste" ID="MicroPythonDeviceInterface.__executeAsyncPaste"></a> -<h4>MicroPythonDeviceInterface.__executeAsyncPaste</h4> -<b>__executeAsyncPaste</b>(<i>commandsList</i>) - -<p> - Private 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 str)</dt> -<dd> -list of commands to be execute on the device -</dd> -</dl> -<a NAME="MicroPythonDeviceInterface.__executeAsyncRaw" ID="MicroPythonDeviceInterface.__executeAsyncRaw"></a> -<h4>MicroPythonDeviceInterface.__executeAsyncRaw</h4> -<b>__executeAsyncRaw</b>(<i>commandsList</i>) - -<p> - Private 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.__execute_paste" ID="MicroPythonDeviceInterface.__execute_paste"></a> -<h4>MicroPythonDeviceInterface.__execute_paste</h4> -<b>__execute_paste</b>(<i>commands, timeout=0</i>) +<a NAME="MicroPythonDeviceInterface.connectToDevice" ID="MicroPythonDeviceInterface.connectToDevice"></a> +<h4>MicroPythonDeviceInterface.connectToDevice</h4> +<b>connectToDevice</b>(<i>connection</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. + Public slot to connect to the device. </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> +<dt><i>connection</i> (str)</dt> <dd> -bool -</dd> -</dl> -<a NAME="MicroPythonDeviceInterface.__rawOff" ID="MicroPythonDeviceInterface.__rawOff"></a> -<h4>MicroPythonDeviceInterface.__rawOff</h4> -<b>__rawOff</b>(<i></i>) - -<p> - Private method to switch 'raw' mode off. -</p> -<a NAME="MicroPythonDeviceInterface.__rawOn" ID="MicroPythonDeviceInterface.__rawOn"></a> -<h4>MicroPythonDeviceInterface.__rawOn</h4> -<b>__rawOn</b>(<i></i>) - -<p> - Private method to switch the connected device to 'raw' mode. -</p> -<p> - Note: switching to raw 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.__readSerial" ID="MicroPythonDeviceInterface.__readSerial"></a> -<h4>MicroPythonDeviceInterface.__readSerial</h4> -<b>__readSerial</b>(<i></i>) - -<p> - Private slot to read all available serial data and emit it with the - "dataReceived" signal for further processing. -</p> -<a NAME="MicroPythonDeviceInterface.connectToDevice" ID="MicroPythonDeviceInterface.connectToDevice"></a> -<h4>MicroPythonDeviceInterface.connectToDevice</h4> -<b>connectToDevice</b>(<i>port</i>) - -<p> - Public slot to start the manager. -</p> -<dl> - -<dt><i>port</i> (str)</dt> -<dd> -name of the port to be used +name of the connection to be used </dd> </dl> <dl> @@ -353,13 +151,29 @@ bool </dd> </dl> +<dl> + +<dt>Raises <b>NotImplementedError</b>:</dt> +<dd> +raised to indicate that this method needs to + be implemented in a derived class +</dd> +</dl> <a NAME="MicroPythonDeviceInterface.disconnectFromDevice" ID="MicroPythonDeviceInterface.disconnectFromDevice"></a> <h4>MicroPythonDeviceInterface.disconnectFromDevice</h4> <b>disconnectFromDevice</b>(<i></i>) <p> - Public slot to stop the thread. + Public slot to disconnect from the device. </p> +<dl> + +<dt>Raises <b>NotImplementedError</b>:</dt> +<dd> +raised to indicate that this method needs to + be implemented in a derived class +</dd> +</dl> <a NAME="MicroPythonDeviceInterface.execute" ID="MicroPythonDeviceInterface.execute"></a> <h4>MicroPythonDeviceInterface.execute</h4> <b>execute</b>(<i>commands, *, mode="raw", timeout=0</i>) @@ -369,7 +183,7 @@ result. </p> <p> - If no serial connection is available, empty results will be returned. + If no connection is available, empty results will be returned. </p> <dl> @@ -402,6 +216,11 @@ </dl> <dl> +<dt>Raises <b>NotImplementedError</b>:</dt> +<dd> +raised to indicate that this method needs to + be implemented in a derived class +</dd> <dt>Raises <b>ValueError</b>:</dt> <dd> raised in case of an unsupported submit mode @@ -421,13 +240,19 @@ <dd> list of commands to be execute on the device </dd> -<dt><i>submitMode</i> (str (one of 'raw' or 'paste'))</dt> +<dt><i>submitMode</i> (str)</dt> <dd> -mode to be used to submit the commands +mode to be used to submit the commands (one of 'raw' + or 'paste') </dd> </dl> <dl> +<dt>Raises <b>NotImplementedError</b>:</dt> +<dd> +raised to indicate that this method needs to + be implemented in a derived class +</dd> <dt>Raises <b>ValueError</b>:</dt> <dd> raised to indicate an unknown submit mode @@ -459,6 +284,14 @@ bool </dd> </dl> +<dl> + +<dt>Raises <b>NotImplementedError</b>:</dt> +<dd> +raised to indicate that this method needs to + be implemented in a derived class +</dd> +</dl> <a NAME="MicroPythonDeviceInterface.probeDevice" ID="MicroPythonDeviceInterface.probeDevice"></a> <h4>MicroPythonDeviceInterface.probeDevice</h4> <b>probeDevice</b>(<i></i>) @@ -467,7 +300,7 @@ Public method to check the device is responding. </p> <p> - If the device has not been flashed with a MicroPython formware, the + If the device has not been flashed with a MicroPython firmware, the probe will fail. </p> <dl> @@ -482,6 +315,14 @@ bool </dd> </dl> +<dl> + +<dt>Raises <b>NotImplementedError</b>:</dt> +<dd> +raised to indicate that this method needs to + be implemented in a derived class +</dd> +</dl> <a NAME="MicroPythonDeviceInterface.write" ID="MicroPythonDeviceInterface.write"></a> <h4>MicroPythonDeviceInterface.write</h4> <b>write</b>(<i>data</i>) @@ -496,6 +337,14 @@ data to be written </dd> </dl> +<dl> + +<dt>Raises <b>NotImplementedError</b>:</dt> +<dd> +raised to indicate that this method needs to + be implemented in a derived class +</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.MicroPythonSerialDeviceInterface.html Fri Apr 28 12:07:41 2023 +0200 @@ -0,0 +1,489 @@ +<!DOCTYPE html> +<html><head> +<title>eric7.MicroPython.MicroPythonSerialDeviceInterface</title> +<meta charset="UTF-8"> +<link rel="stylesheet" href="styles.css"> +</head> +<body> +<a NAME="top" ID="top"></a> +<h1>eric7.MicroPython.MicroPythonSerialDeviceInterface</h1> + +<p> +Module implementing an interface to talk to a connected MicroPython device via +a serial link. +</p> +<h3>Global Attributes</h3> + +<table> +<tr><td>None</td></tr> +</table> +<h3>Classes</h3> + +<table> + +<tr> +<td><a href="#MicroPythonSerialDeviceInterface">MicroPythonSerialDeviceInterface</a></td> +<td>Class implementing an interface to talk to a connected MicroPython device via a serial link.</td> +</tr> +</table> +<h3>Functions</h3> + +<table> +<tr><td>None</td></tr> +</table> +<hr /> +<hr /> +<a NAME="MicroPythonSerialDeviceInterface" ID="MicroPythonSerialDeviceInterface"></a> +<h2>MicroPythonSerialDeviceInterface</h2> + +<p> + Class implementing an interface to talk to a connected MicroPython device via + a serial link. +</p> +<h3>Derived from</h3> +MicroPythonDeviceInterface +<h3>Class Attributes</h3> + +<table> +<tr><td>PasteModePrompt</td></tr><tr><td>TracebackMarker</td></tr> +</table> +<h3>Class Methods</h3> + +<table> +<tr><td>None</td></tr> +</table> +<h3>Methods</h3> + +<table> + +<tr> +<td><a href="#MicroPythonSerialDeviceInterface.__init__">MicroPythonSerialDeviceInterface</a></td> +<td>Constructor</td> +</tr> +<tr> +<td><a href="#MicroPythonSerialDeviceInterface.__executeAsyncPaste">__executeAsyncPaste</a></td> +<td>Private method to execute a series of commands over a period of time without returning any result (asynchronous execution).</td> +</tr> +<tr> +<td><a href="#MicroPythonSerialDeviceInterface.__executeAsyncRaw">__executeAsyncRaw</a></td> +<td>Private method to execute a series of commands over a period of time without returning any result (asynchronous execution).</td> +</tr> +<tr> +<td><a href="#MicroPythonSerialDeviceInterface.__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="#MicroPythonSerialDeviceInterface.__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="#MicroPythonSerialDeviceInterface.__pasteOff">__pasteOff</a></td> +<td>Private method to switch 'paste' mode off.</td> +</tr> +<tr> +<td><a href="#MicroPythonSerialDeviceInterface.__pasteOn">__pasteOn</a></td> +<td>Private method to switch the connected device to 'paste' mode.</td> +</tr> +<tr> +<td><a href="#MicroPythonSerialDeviceInterface.__rawOff">__rawOff</a></td> +<td>Private method to switch 'raw' mode off.</td> +</tr> +<tr> +<td><a href="#MicroPythonSerialDeviceInterface.__rawOn">__rawOn</a></td> +<td>Private method to switch the connected device to 'raw' mode.</td> +</tr> +<tr> +<td><a href="#MicroPythonSerialDeviceInterface.__readSerial">__readSerial</a></td> +<td>Private slot to read all available serial data and emit it with the "dataReceived" signal for further processing.</td> +</tr> +<tr> +<td><a href="#MicroPythonSerialDeviceInterface.connectToDevice">connectToDevice</a></td> +<td>Public slot to connect to the device.</td> +</tr> +<tr> +<td><a href="#MicroPythonSerialDeviceInterface.disconnectFromDevice">disconnectFromDevice</a></td> +<td>Public slot to disconnect from the device.</td> +</tr> +<tr> +<td><a href="#MicroPythonSerialDeviceInterface.execute">execute</a></td> +<td>Public method to send commands to the connected device and return the result.</td> +</tr> +<tr> +<td><a href="#MicroPythonSerialDeviceInterface.executeAsync">executeAsync</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="#MicroPythonSerialDeviceInterface.handlePreferencesChanged">handlePreferencesChanged</a></td> +<td>Public slot to handle a change of the preferences.</td> +</tr> +<tr> +<td><a href="#MicroPythonSerialDeviceInterface.isConnected">isConnected</a></td> +<td>Public method to get the connection status.</td> +</tr> +<tr> +<td><a href="#MicroPythonSerialDeviceInterface.probeDevice">probeDevice</a></td> +<td>Public method to check the device is responding.</td> +</tr> +<tr> +<td><a href="#MicroPythonSerialDeviceInterface.write">write</a></td> +<td>Public method to write data to the connected device.</td> +</tr> +</table> +<h3>Static Methods</h3> + +<table> +<tr><td>None</td></tr> +</table> + +<a NAME="MicroPythonSerialDeviceInterface.__init__" ID="MicroPythonSerialDeviceInterface.__init__"></a> +<h4>MicroPythonSerialDeviceInterface (Constructor)</h4> +<b>MicroPythonSerialDeviceInterface</b>(<i>parent=None</i>) + +<p> + Constructor +</p> +<dl> + +<dt><i>parent</i> (QObject)</dt> +<dd> +reference to the parent object +</dd> +</dl> +<a NAME="MicroPythonSerialDeviceInterface.__executeAsyncPaste" ID="MicroPythonSerialDeviceInterface.__executeAsyncPaste"></a> +<h4>MicroPythonSerialDeviceInterface.__executeAsyncPaste</h4> +<b>__executeAsyncPaste</b>(<i>commandsList</i>) + +<p> + Private 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 str)</dt> +<dd> +list of commands to be execute on the device +</dd> +</dl> +<a NAME="MicroPythonSerialDeviceInterface.__executeAsyncRaw" ID="MicroPythonSerialDeviceInterface.__executeAsyncRaw"></a> +<h4>MicroPythonSerialDeviceInterface.__executeAsyncRaw</h4> +<b>__executeAsyncRaw</b>(<i>commandsList</i>) + +<p> + Private 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="MicroPythonSerialDeviceInterface.__execute_paste" ID="MicroPythonSerialDeviceInterface.__execute_paste"></a> +<h4>MicroPythonSerialDeviceInterface.__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="MicroPythonSerialDeviceInterface.__execute_raw" ID="MicroPythonSerialDeviceInterface.__execute_raw"></a> +<h4>MicroPythonSerialDeviceInterface.__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="MicroPythonSerialDeviceInterface.__pasteOff" ID="MicroPythonSerialDeviceInterface.__pasteOff"></a> +<h4>MicroPythonSerialDeviceInterface.__pasteOff</h4> +<b>__pasteOff</b>(<i></i>) + +<p> + Private method to switch 'paste' mode off. +</p> +<a NAME="MicroPythonSerialDeviceInterface.__pasteOn" ID="MicroPythonSerialDeviceInterface.__pasteOn"></a> +<h4>MicroPythonSerialDeviceInterface.__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="MicroPythonSerialDeviceInterface.__rawOff" ID="MicroPythonSerialDeviceInterface.__rawOff"></a> +<h4>MicroPythonSerialDeviceInterface.__rawOff</h4> +<b>__rawOff</b>(<i></i>) + +<p> + Private method to switch 'raw' mode off. +</p> +<a NAME="MicroPythonSerialDeviceInterface.__rawOn" ID="MicroPythonSerialDeviceInterface.__rawOn"></a> +<h4>MicroPythonSerialDeviceInterface.__rawOn</h4> +<b>__rawOn</b>(<i></i>) + +<p> + Private method to switch the connected device to 'raw' mode. +</p> +<p> + Note: switching to raw 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="MicroPythonSerialDeviceInterface.__readSerial" ID="MicroPythonSerialDeviceInterface.__readSerial"></a> +<h4>MicroPythonSerialDeviceInterface.__readSerial</h4> +<b>__readSerial</b>(<i></i>) + +<p> + Private slot to read all available serial data and emit it with the + "dataReceived" signal for further processing. +</p> +<a NAME="MicroPythonSerialDeviceInterface.connectToDevice" ID="MicroPythonSerialDeviceInterface.connectToDevice"></a> +<h4>MicroPythonSerialDeviceInterface.connectToDevice</h4> +<b>connectToDevice</b>(<i>connection</i>) + +<p> + Public slot to connect to the device. +</p> +<dl> + +<dt><i>connection</i> (str)</dt> +<dd> +name of the connection to be used +</dd> +</dl> +<dl> +<dt>Return:</dt> +<dd> +flag indicating success +</dd> +</dl> +<dl> +<dt>Return Type:</dt> +<dd> +bool +</dd> +</dl> +<a NAME="MicroPythonSerialDeviceInterface.disconnectFromDevice" ID="MicroPythonSerialDeviceInterface.disconnectFromDevice"></a> +<h4>MicroPythonSerialDeviceInterface.disconnectFromDevice</h4> +<b>disconnectFromDevice</b>(<i></i>) + +<p> + Public slot to disconnect from the device. +</p> +<a NAME="MicroPythonSerialDeviceInterface.execute" ID="MicroPythonSerialDeviceInterface.execute"></a> +<h4>MicroPythonSerialDeviceInterface.execute</h4> +<b>execute</b>(<i>commands, *, mode="raw", timeout=0</i>) + +<p> + Public method to send commands to the connected device 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>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> +<dd> +tuple containing stdout and stderr output of the device +</dd> +</dl> +<dl> +<dt>Return Type:</dt> +<dd> +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="MicroPythonSerialDeviceInterface.executeAsync" ID="MicroPythonSerialDeviceInterface.executeAsync"></a> +<h4>MicroPythonSerialDeviceInterface.executeAsync</h4> +<b>executeAsync</b>(<i>commandsList, submitMode</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 str)</dt> +<dd> +list of commands to be execute on the device +</dd> +<dt><i>submitMode</i> (str (one of 'raw' or 'paste'))</dt> +<dd> +mode to be used to submit the commands +</dd> +</dl> +<dl> + +<dt>Raises <b>ValueError</b>:</dt> +<dd> +raised to indicate an unknown submit mode +</dd> +</dl> +<a NAME="MicroPythonSerialDeviceInterface.handlePreferencesChanged" ID="MicroPythonSerialDeviceInterface.handlePreferencesChanged"></a> +<h4>MicroPythonSerialDeviceInterface.handlePreferencesChanged</h4> +<b>handlePreferencesChanged</b>(<i></i>) + +<p> + Public slot to handle a change of the preferences. +</p> +<a NAME="MicroPythonSerialDeviceInterface.isConnected" ID="MicroPythonSerialDeviceInterface.isConnected"></a> +<h4>MicroPythonSerialDeviceInterface.isConnected</h4> +<b>isConnected</b>(<i></i>) + +<p> + Public method to get the connection status. +</p> +<dl> +<dt>Return:</dt> +<dd> +flag indicating the connection status +</dd> +</dl> +<dl> +<dt>Return Type:</dt> +<dd> +bool +</dd> +</dl> +<a NAME="MicroPythonSerialDeviceInterface.probeDevice" ID="MicroPythonSerialDeviceInterface.probeDevice"></a> +<h4>MicroPythonSerialDeviceInterface.probeDevice</h4> +<b>probeDevice</b>(<i></i>) + +<p> + Public method to check the device is responding. +</p> +<p> + If the device has not been flashed with a MicroPython firmware, the + probe will fail. +</p> +<dl> +<dt>Return:</dt> +<dd> +flag indicating a communicating MicroPython device +</dd> +</dl> +<dl> +<dt>Return Type:</dt> +<dd> +bool +</dd> +</dl> +<a NAME="MicroPythonSerialDeviceInterface.write" ID="MicroPythonSerialDeviceInterface.write"></a> +<h4>MicroPythonSerialDeviceInterface.write</h4> +<b>write</b>(<i>data</i>) + +<p> + Public method to write data to the connected device. +</p> +<dl> + +<dt><i>data</i> (bytes or bytearray)</dt> +<dd> +data to be written +</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.MicroPythonWidget.html Thu Apr 27 17:59:09 2023 +0200 +++ b/src/eric7/Documentation/Source/eric7.MicroPython.MicroPythonWidget.html Fri Apr 28 12:07:41 2023 +0200 @@ -52,7 +52,7 @@ <h3>Class Attributes</h3> <table> -<tr><td>DeviceBoardRole</td></tr><tr><td>DevicePidRole</td></tr><tr><td>DevicePortRole</td></tr><tr><td>DeviceSerNoRole</td></tr><tr><td>DeviceTypeRole</td></tr><tr><td>DeviceVidRole</td></tr><tr><td>ManualMarker</td></tr><tr><td>ZoomMax</td></tr><tr><td>ZoomMin</td></tr> +<tr><td>DeviceBoardRole</td></tr><tr><td>DeviceInterfaceTypeRole</td></tr><tr><td>DevicePidRole</td></tr><tr><td>DevicePortRole</td></tr><tr><td>DeviceSerNoRole</td></tr><tr><td>DeviceTypeRole</td></tr><tr><td>DeviceVidRole</td></tr><tr><td>ManualMarker</td></tr><tr><td>ZoomMax</td></tr><tr><td>ZoomMin</td></tr> </table> <h3>Class Methods</h3> @@ -228,10 +228,6 @@ <td>Public method to process events for the REPL pane.</td> </tr> <tr> -<td><a href="#MicroPythonWidget.getCurrentBoard">getCurrentBoard</a></td> -<td>Public method to get the board name of the selected device.</td> -</tr> -<tr> <td><a href="#MicroPythonWidget.getCurrentPort">getCurrentPort</a></td> <td>Public method to determine the port path of the selected device.</td> </tr> @@ -388,6 +384,13 @@ automatically </dd> </dl> +<dl> + +<dt>Raises <b>ValueError</b>:</dt> +<dd> +raised to indicate an unsupported interface type +</dd> +</dl> <a NAME="MicroPythonWidget.__convertToUF2" ID="MicroPythonWidget.__convertToUF2"></a> <h4>MicroPythonWidget.__convertToUF2</h4> <b>__convertToUF2</b>(<i></i>) @@ -847,25 +850,6 @@ bool </dd> </dl> -<a NAME="MicroPythonWidget.getCurrentBoard" ID="MicroPythonWidget.getCurrentBoard"></a> -<h4>MicroPythonWidget.getCurrentBoard</h4> -<b>getCurrentBoard</b>(<i></i>) - -<p> - Public method to get the board name of the selected device. -</p> -<dl> -<dt>Return:</dt> -<dd> -board name of the selected device -</dd> -</dl> -<dl> -<dt>Return Type:</dt> -<dd> -str -</dd> -</dl> <a NAME="MicroPythonWidget.getCurrentPort" ID="MicroPythonWidget.getCurrentPort"></a> <h4>MicroPythonWidget.getCurrentPort</h4> <b>getCurrentPort</b>(<i></i>)
--- a/src/eric7/Documentation/Source/index-eric7.MicroPython.html Thu Apr 27 17:59:09 2023 +0200 +++ b/src/eric7/Documentation/Source/index-eric7.MicroPython.html Fri Apr 28 12:07:41 2023 +0200 @@ -61,7 +61,7 @@ </tr> <tr> <td><a href="eric7.MicroPython.MicroPythonDeviceInterface.html">MicroPythonDeviceInterface</a></td> -<td>Module implementing some file system commands for MicroPython.</td> +<td>Module implementing an interface base class to talk to a connected MicroPython device.</td> </tr> <tr> <td><a href="eric7.MicroPython.MicroPythonFileManager.html">MicroPythonFileManager</a></td> @@ -84,6 +84,10 @@ <td>Module implementing a dialog to show progress messages.</td> </tr> <tr> +<td><a href="eric7.MicroPython.MicroPythonSerialDeviceInterface.html">MicroPythonSerialDeviceInterface</a></td> +<td>Module implementing an interface to talk to a connected MicroPython device via a serial link.</td> +</tr> +<tr> <td><a href="eric7.MicroPython.MicroPythonSerialPort.html">MicroPythonSerialPort</a></td> <td>Module implementing a QSerialPort with additional functionality for MicroPython devices.</td> </tr>
--- a/src/eric7/MicroPython/MicroPythonDeviceInterface.py Thu Apr 27 17:59:09 2023 +0200 +++ b/src/eric7/MicroPython/MicroPythonDeviceInterface.py Fri Apr 28 12:07:41 2023 +0200 @@ -1,25 +1,13 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2019 - 2023 Detlev Offenbach <detlev@die-offenbachs.de> +# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de> # """ -Module implementing some file system commands for MicroPython. +Module implementing an interface base class to talk to a connected MicroPython device. """ -from PyQt6.QtCore import ( - QCoreApplication, - QEventLoop, - QObject, - QThread, - QTimer, - pyqtSignal, - pyqtSlot, -) - -from eric7 import Preferences - -from .MicroPythonSerialPort import MicroPythonSerialPort +from PyQt6.QtCore import QObject, pyqtSignal, pyqtSlot class MicroPythonDeviceInterface(QObject): @@ -28,16 +16,13 @@ @signal executeAsyncFinished() emitted to indicate the end of an asynchronously executed list of commands (e.g. a script) - @signal dataReceived(data) emitted to send data received via the serial - connection for further processing + @signal dataReceived(data) emitted to send data received via the connection + for further processing """ executeAsyncFinished = pyqtSignal() dataReceived = pyqtSignal(bytes) - PasteModePrompt = b"=== " - TracebackMarker = b"Traceback (most recent call last):" - def __init__(self, parent=None): """ Constructor @@ -47,43 +32,35 @@ """ super().__init__(parent) - self.__repl = parent - - self.__blockReadyRead = False - - self.__serial = MicroPythonSerialPort( - timeout=Preferences.getMicroPython("SerialTimeout"), parent=self - ) - self.__serial.readyRead.connect(self.__readSerial) - @pyqtSlot() - def __readSerial(self): + def connectToDevice(self, connection): """ - Private slot to read all available serial data and emit it with the - "dataReceived" signal for further processing. - """ - if not self.__blockReadyRead: - data = bytes(self.__serial.readAll()) - self.dataReceived.emit(data) + Public slot to connect to the device. - @pyqtSlot() - def connectToDevice(self, port): - """ - Public slot to start the manager. - - @param port name of the port to be used + @param connection name of the connection to be used @type str @return flag indicating success @rtype bool + @exception NotImplementedError raised to indicate that this method needs to + be implemented in a derived class """ - return self.__serial.openSerialLink(port) + raise NotImplementedError( + "This method needs to be implemented in a derived class." + ) + + return False @pyqtSlot() def disconnectFromDevice(self): """ - Public slot to stop the thread. + Public slot to disconnect from the device. + + @exception NotImplementedError raised to indicate that this method needs to + be implemented in a derived class """ - self.__serial.closeSerialLink() + raise NotImplementedError( + "This method needs to be implemented in a derived class." + ) def isConnected(self): """ @@ -91,15 +68,21 @@ @return flag indicating the connection status @rtype bool + @exception NotImplementedError raised to indicate that this method needs to + be implemented in a derived class """ - return self.__serial.isConnected() + raise NotImplementedError( + "This method needs to be implemented in a derived class." + ) + + return False @pyqtSlot() def handlePreferencesChanged(self): """ Public slot to handle a change of the preferences. """ - self.__serial.setTimeout(Preferences.getMicroPython("SerialTimeout")) + pass def write(self, data): """ @@ -107,149 +90,37 @@ @param data data to be written @type bytes or bytearray - """ - 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.clear() # clear any buffered output before entering paste mode - 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. + @exception NotImplementedError raised to indicate that this method needs to + be implemented in a derived class """ - 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. - - Note: switching to raw mode is done with synchronous writes. - - @return flag indicating success - @rtype bool - """ - if not self.__serial: - return False - - rawReplMessage = b"raw REPL; CTRL-B to exit\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\x01") # send CTRL-A to enter raw mode - self.__serial.readUntil(rawReplMessage) - if self.__serial.hasTimedOut(): - # it timed out; try it again and than fail - self.__serial.write(b"\r\x01") # send CTRL-A again - self.__serial.readUntil(rawReplMessage) - if self.__serial.hasTimedOut(): - return False - - QCoreApplication.processEvents( - QEventLoop.ProcessEventsFlag.ExcludeUserInputEvents + raise NotImplementedError( + "This method needs to be implemented in a derived class." ) - self.__serial.readAll() # read all data and discard it - return True - - def __rawOff(self): - """ - Private method to switch 'raw' mode off. - """ - if self.__serial: - self.__serial.write(b"\x02") # send CTRL-B to cancel raw mode - self.__serial.readUntil(b">>> ") # read until Python prompt - self.__serial.readAll() # read all data and discard it def probeDevice(self): """ Public method to check the device is responding. - If the device has not been flashed with a MicroPython formware, the + If the device has not been flashed with a MicroPython firmware, the probe will fail. @return flag indicating a communicating MicroPython device @rtype bool + @exception NotImplementedError raised to indicate that this method needs to + be implemented in a derived class """ - if not self.__serial: - return False - - if not self.__serial.isConnected(): - return False + raise NotImplementedError( + "This method needs to be implemented in a derived class." + ) - # switch on raw mode - self.__blockReadyRead = True - ok = self.__pasteOn() - if not ok: - self.__blockReadyRead = False - return False - - # switch off raw mode - QThread.msleep(10) - self.__pasteOff() - self.__blockReadyRead = False - - return True + return False def execute(self, commands, *, mode="raw", timeout=0): """ Public method to send commands to the connected device and return the result. - If no serial connection is available, empty results will be returned. + If no connection is available, empty results will be returned. @param commands list of commands to be executed @type str or list of str @@ -261,171 +132,18 @@ @type int (optional) @return tuple containing stdout and stderr output of the device @rtype tuple of (bytes, bytes) + @exception NotImplementedError raised to indicate that this method needs to + be implemented in a derived class @exception ValueError raised in case of an unsupported submit mode """ + raise NotImplementedError( + "This method needs to be implemented in a derived class." + ) + 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) - """ - if not self.__serial: - return b"", b"" - - if not self.__serial.isConnected(): - return b"", b"Device not connected or not switched on." - - result = bytearray() - err = b"" - - if isinstance(commands, str): - commands = [commands] - - # switch on raw mode - self.__blockReadyRead = True - ok = self.__rawOn() - 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: - if command: - commandBytes = command.encode("utf-8") - self.__serial.write(commandBytes + b"\x04") - QCoreApplication.processEvents( - QEventLoop.ProcessEventsFlag.ExcludeUserInputEvents - ) - ok = self.__serial.readUntil(b"OK") - if ok != b"OK": - self.__blockReadyRead = False - return ( - b"", - "Expected 'OK', got '{0}', followed by '{1}'".format( - ok, self.__serial.readAll() - ).encode("utf-8"), - ) - - # read until prompt - response = self.__serial.readUntil(b"\x04>", timeout=timeout) - if self.__serial.hasTimedOut(): - self.__blockReadyRead = False - return b"", b"Timeout while processing commands." - if b"\x04" in response[:-2]: - # split stdout, stderr - out, err = response[:-2].split(b"\x04") - result += out - else: - err = b"invalid response received: " + response - if err: - result = b"" - break - - # switch off raw mode - QThread.msleep(10) - self.__rawOff() - self.__blockReadyRead = False - - 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 paste mode - self.__blockReadyRead = True - ok = self.__pasteOn() - if not ok: - self.__blockReadyRead = False - return (b"", b"Could not switch to paste 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) - # read until Python prompt - result = ( - self.__serial.readUntil(b">>> ", timeout=timeout) - .replace(b">>> ", b"") - .strip() - ) - if self.__serial.hasTimedOut(): - self.__blockReadyRead = False - return b"", b"Timeout while processing commands." - - # get rid of any OSD string - if result.startswith(b"\x1b]0;"): - result = result.split(b"\x1b\\")[-1] - - if self.TracebackMarker in result: - errorIndex = result.find(self.TracebackMarker) - out, err = result[:errorIndex], result[errorIndex:] - else: - out = result - err = b"" - - self.__blockReadyRead = False - return out, err + return b"", b"" def executeAsync(self, commandsList, submitMode): """ @@ -434,61 +152,18 @@ @param commandsList list of commands to be execute on the device @type list of str - @param submitMode mode to be used to submit the commands - @type str (one of 'raw' or 'paste') + @param submitMode mode to be used to submit the commands (one of 'raw' + or 'paste') + @type str + @exception NotImplementedError raised to indicate that this method needs to + be implemented in a derived class @exception ValueError raised to indicate an unknown submit mode """ - if submitMode not in ("raw", "paste"): - raise ValueError("Illegal submit mode given ({0})".format(submitMode)) - - if submitMode == "raw": - startSequence = [ # 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 - b'print("\\n")\r', - ] - endSequence = [ - b"\r", - b"\x04", - ] - self.__executeAsyncRaw( - startSequence - + [c.encode("utf-8") + b"\r" for c in commandsList] - + endSequence - ) - elif submitMode == "paste": - self.__executeAsyncPaste(commandsList) - - def __executeAsyncRaw(self, commandsList): - """ - Private method to execute a series of commands over a period of time - without returning any result (asynchronous execution). + raise NotImplementedError( + "This method needs to be implemented in a derived class." + ) - @param commandsList list of commands to be execute on the device - @type list of bytes - """ - if commandsList: - command = commandsList.pop(0) - self.__serial.write(command) - QTimer.singleShot(2, lambda: self.__executeAsyncRaw(commandsList)) - else: - self.__rawOff() - self.executeAsyncFinished.emit() - - def __executeAsyncPaste(self, commandsList): - """ - Private 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 str - """ - self.__blockReadyRead = True - self.__pasteOn() - command = b"\n".join(c.encode("utf-8)") for c in commandsList) - self.__serial.write(command) - self.__serial.readUntil(command) - self.__blockReadyRead = False - self.__pasteOff() - self.executeAsyncFinished.emit + if submitMode not in ("raw", "paste"): + raise ValueError( + "Unsupported submit mode given ('{0}').".format(submitMode) + )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/eric7/MicroPython/MicroPythonSerialDeviceInterface.py Fri Apr 28 12:07:41 2023 +0200 @@ -0,0 +1,479 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2019 - 2023 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing an interface to talk to a connected MicroPython device via +a serial link. +""" + +from PyQt6.QtCore import QCoreApplication, QEventLoop, QThread, QTimer, pyqtSlot + +from eric7 import Preferences + +from .MicroPythonDeviceInterface import MicroPythonDeviceInterface +from .MicroPythonSerialPort import MicroPythonSerialPort + + +class MicroPythonSerialDeviceInterface(MicroPythonDeviceInterface): + """ + Class implementing an interface to talk to a connected MicroPython device via + a serial link. + """ + + PasteModePrompt = b"=== " + TracebackMarker = b"Traceback (most recent call last):" + + def __init__(self, parent=None): + """ + Constructor + + @param parent reference to the parent object + @type QObject + """ + super().__init__(parent) + + self.__blockReadyRead = False + + self.__serial = MicroPythonSerialPort( + timeout=Preferences.getMicroPython("SerialTimeout"), parent=self + ) + self.__serial.readyRead.connect(self.__readSerial) + + @pyqtSlot() + def __readSerial(self): + """ + Private slot to read all available serial data and emit it with the + "dataReceived" signal for further processing. + """ + if not self.__blockReadyRead: + data = bytes(self.__serial.readAll()) + self.dataReceived.emit(data) + + @pyqtSlot() + def connectToDevice(self, connection): + """ + Public slot to connect to the device. + + @param connection name of the connection to be used + @type str + @return flag indicating success + @rtype bool + """ + return self.__serial.openSerialLink(connection) + + @pyqtSlot() + def disconnectFromDevice(self): + """ + Public slot to disconnect from the device. + """ + self.__serial.closeSerialLink() + + def isConnected(self): + """ + Public method to get the connection status. + + @return flag indicating the connection status + @rtype bool + """ + return self.__serial.isConnected() + + @pyqtSlot() + def handlePreferencesChanged(self): + """ + Public slot to handle a change of the preferences. + """ + self.__serial.setTimeout(Preferences.getMicroPython("SerialTimeout")) + + def write(self, data): + """ + Public method to write data to the connected device. + + @param data data to be written + @type bytes or bytearray + """ + 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.clear() # clear any buffered output before entering paste mode + 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. + + Note: switching to raw mode is done with synchronous writes. + + @return flag indicating success + @rtype bool + """ + if not self.__serial: + return False + + rawReplMessage = b"raw REPL; CTRL-B to exit\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\x01") # send CTRL-A to enter raw mode + self.__serial.readUntil(rawReplMessage) + if self.__serial.hasTimedOut(): + # it timed out; try it again and than fail + self.__serial.write(b"\r\x01") # send CTRL-A again + self.__serial.readUntil(rawReplMessage) + if self.__serial.hasTimedOut(): + return False + + QCoreApplication.processEvents( + QEventLoop.ProcessEventsFlag.ExcludeUserInputEvents + ) + self.__serial.readAll() # read all data and discard it + return True + + def __rawOff(self): + """ + Private method to switch 'raw' mode off. + """ + if self.__serial: + self.__serial.write(b"\x02") # send CTRL-B to cancel raw mode + self.__serial.readUntil(b">>> ") # read until Python prompt + self.__serial.readAll() # read all data and discard it + + def probeDevice(self): + """ + Public method to check the device is responding. + + If the device has not been flashed with a MicroPython firmware, the + probe will fail. + + @return flag indicating a communicating MicroPython device + @rtype bool + """ + if not self.__serial: + return False + + if not self.__serial.isConnected(): + return False + + # switch on raw mode + self.__blockReadyRead = True + ok = self.__pasteOn() + if not ok: + self.__blockReadyRead = False + return False + + # switch off raw mode + QThread.msleep(10) + self.__pasteOff() + self.__blockReadyRead = False + + return True + + def execute(self, commands, *, mode="raw", timeout=0): + """ + Public method to send commands to the connected device 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 + @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) + """ + if not self.__serial: + return b"", b"" + + if not self.__serial.isConnected(): + return b"", b"Device not connected or not switched on." + + result = bytearray() + err = b"" + + if isinstance(commands, str): + commands = [commands] + + # switch on raw mode + self.__blockReadyRead = True + ok = self.__rawOn() + 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: + if command: + commandBytes = command.encode("utf-8") + self.__serial.write(commandBytes + b"\x04") + QCoreApplication.processEvents( + QEventLoop.ProcessEventsFlag.ExcludeUserInputEvents + ) + ok = self.__serial.readUntil(b"OK") + if ok != b"OK": + self.__blockReadyRead = False + return ( + b"", + "Expected 'OK', got '{0}', followed by '{1}'".format( + ok, self.__serial.readAll() + ).encode("utf-8"), + ) + + # read until prompt + response = self.__serial.readUntil(b"\x04>", timeout=timeout) + if self.__serial.hasTimedOut(): + self.__blockReadyRead = False + return b"", b"Timeout while processing commands." + if b"\x04" in response[:-2]: + # split stdout, stderr + out, err = response[:-2].split(b"\x04") + result += out + else: + err = b"invalid response received: " + response + if err: + result = b"" + break + + # switch off raw mode + QThread.msleep(10) + self.__rawOff() + self.__blockReadyRead = False + + 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 paste mode + self.__blockReadyRead = True + ok = self.__pasteOn() + if not ok: + self.__blockReadyRead = False + return (b"", b"Could not switch to paste 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) + # read until Python prompt + result = ( + self.__serial.readUntil(b">>> ", timeout=timeout) + .replace(b">>> ", b"") + .strip() + ) + if self.__serial.hasTimedOut(): + self.__blockReadyRead = False + return b"", b"Timeout while processing commands." + + # get rid of any OSD string + if result.startswith(b"\x1b]0;"): + result = result.split(b"\x1b\\")[-1] + + if self.TracebackMarker in result: + errorIndex = result.find(self.TracebackMarker) + out, err = result[:errorIndex], result[errorIndex:] + else: + out = result + err = b"" + + self.__blockReadyRead = False + return out, err + + def executeAsync(self, commandsList, submitMode): + """ + 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 str + @param submitMode mode to be used to submit the commands + @type str (one of 'raw' or 'paste') + @exception ValueError raised to indicate an unknown submit mode + """ + if submitMode not in ("raw", "paste"): + raise ValueError("Illegal submit mode given ({0})".format(submitMode)) + + if submitMode == "raw": + startSequence = [ # 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 + b'print("\\n")\r', + ] + endSequence = [ + b"\r", + b"\x04", + ] + self.__executeAsyncRaw( + startSequence + + [c.encode("utf-8") + b"\r" for c in commandsList] + + endSequence + ) + elif submitMode == "paste": + self.__executeAsyncPaste(commandsList) + + def __executeAsyncRaw(self, commandsList): + """ + Private 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: + command = commandsList.pop(0) + self.__serial.write(command) + QTimer.singleShot(2, lambda: self.__executeAsyncRaw(commandsList)) + else: + self.__rawOff() + self.executeAsyncFinished.emit() + + def __executeAsyncPaste(self, commandsList): + """ + Private 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 str + """ + self.__blockReadyRead = True + self.__pasteOn() + command = b"\n".join(c.encode("utf-8)") for c in commandsList) + self.__serial.write(command) + self.__serial.readUntil(command) + self.__blockReadyRead = False + self.__pasteOff() + self.executeAsyncFinished.emit
--- a/src/eric7/MicroPython/MicroPythonWidget.py Thu Apr 27 17:59:09 2023 +0200 +++ b/src/eric7/MicroPython/MicroPythonWidget.py Fri Apr 28 12:07:41 2023 +0200 @@ -7,6 +7,10 @@ Module implementing the MicroPython REPL widget. """ +# TODO: refactor the code such to have the MicroPythonWidget as the top level +# container and a MicroPythonReplWidget containing the REPL related stuff +# (incl. device status line and zoom widget ?) + import contextlib import functools import os @@ -57,7 +61,7 @@ HAS_QTCHART = False try: - from .MicroPythonDeviceInterface import MicroPythonDeviceInterface + from .MicroPythonSerialDeviceInterface import MicroPythonSerialDeviceInterface HAS_QTSERIALPORT = True except ImportError: @@ -211,6 +215,7 @@ DeviceVidRole = Qt.ItemDataRole.UserRole + 3 DevicePidRole = Qt.ItemDataRole.UserRole + 4 DeviceSerNoRole = Qt.ItemDataRole.UserRole + 5 + DeviceInterfaceTypeRole = Qt.ItemDataRole.UserRole + 6 dataReceived = pyqtSignal(bytes) @@ -290,10 +295,7 @@ self.__lastPort = None self.__lastDeviceType = None - if HAS_QTSERIALPORT: - self.__interface = MicroPythonDeviceInterface(self) - else: - self.__interface = None + self.__interface = None self.__device = None self.__connected = False self.__linkConnected = False @@ -324,7 +326,6 @@ self.replEdit.customContextMenuRequested.connect(self.__showContextMenu) self.__ui.preferencesChanged.connect(self.__handlePreferencesChanged) - self.__ui.preferencesChanged.connect(self.__interface.handlePreferencesChanged) self.__handlePreferencesChanged() @@ -376,6 +377,9 @@ self.deviceTypeComboBox.setItemData( index, serialNumber, self.DeviceSerNoRole ) + self.deviceTypeComboBox.setItemData( + index, "serial", self.DeviceInterfaceTypeRole + ) else: supportedMessage = self.tr("No supported devices detected.") @@ -478,6 +482,9 @@ else: self.replEdit.setLineWrapMode(QTextEdit.LineWrapMode.NoWrap) + if self.__interface is not None: + self.__interface.handlePreferencesChanged + if self.__chartWidget is not None: self.__chartWidget.preferencesChanged() @@ -622,7 +629,7 @@ @type bool """ self.__connected = connected - self.__linkConnected = self.__interface.isConnected() + self.__linkConnected = bool(self.__interface) and self.__interface.isConnected() self.deviceConnectedLed.setOn(self.__linkConnected) if self.__fileManagerWidget: @@ -723,7 +730,8 @@ self.replEdit.setFocus(Qt.FocusReason.OtherFocusReason) else: with contextlib.suppress(TypeError): - self.__interface.dataReceived.disconnect(self.__processData) + if self.__interface is not None: + self.__interface.dataReceived.disconnect(self.__processData) if not self.chartButton.isChecked() and not self.filesButton.isChecked(): self.__disconnectFromDevice() self.__device.setRepl(False) @@ -1134,16 +1142,6 @@ else: return "" - def getCurrentBoard(self): - """ - Public method to get the board name of the selected device. - - @return board name of the selected device - @rtype str - """ - boardName = self.deviceTypeComboBox.currentData(self.DeviceBoardRole) - return boardName - def getDevice(self): """ Public method to get a reference to the current device. @@ -1182,27 +1180,44 @@ @param withAutostart flag indicating to start the repl and file manager automatically @type bool + @exception ValueError raised to indicate an unsupported interface type """ from .ConnectionSelectionDialog import ConnectionSelectionDialog - port = self.getCurrentPort() - if not port: - with EricOverridenCursor(): - dlg = ConnectionSelectionDialog( - self.__unknownPorts, self.__lastPort, self.__lastDeviceType - ) - if dlg.exec() == QDialog.DialogCode.Accepted: - vid, pid, port, deviceType = dlg.getData() + interfaceType = ( + self.deviceTypeComboBox.currentData(self.DeviceInterfaceTypeRole) + or "serial" + ) # 'serial' is the default + + if interfaceType not in ("serial", "webrepl"): + raise ValueError( + "Unsupported interface type detected ('{0}')".format(interfaceType) + ) - self.deviceIconLabel.setPixmap( - Devices.getDeviceIcon(deviceType, False) + if interfaceType == "serial": + port = self.getCurrentPort() + if not port: + with EricOverridenCursor(): + dlg = ConnectionSelectionDialog( + self.__unknownPorts, self.__lastPort, self.__lastDeviceType ) - self.__device = Devices.getDevice(deviceType, self, vid, pid) + if dlg.exec() == QDialog.DialogCode.Accepted: + vid, pid, port, deviceType = dlg.getData() - self.__lastPort = port - self.__lastDeviceType = deviceType - else: - return + self.deviceIconLabel.setPixmap( + Devices.getDeviceIcon(deviceType, False) + ) + self.__device = Devices.getDevice(deviceType, self, vid, pid) + + self.__lastPort = port + self.__lastDeviceType = deviceType + else: + return + + self.__interface = MicroPythonSerialDeviceInterface(self) + elif interfaceType == "webrepl": + # TODO: not yet implemented + return if self.__interface.connectToDevice(port): deviceResponding = self.__interface.probeDevice() @@ -1250,9 +1265,13 @@ Private method to disconnect from the device. """ self.__device and self.__device.setConnected(False) - self.__interface.disconnectFromDevice() self.__setConnected(False) + if self.__interface is not None: + self.__interface.disconnectFromDevice() + self.__interface.deleteLater() + self.__interface = None + @pyqtSlot() def on_runButton_clicked(self): """