src/eric7/MicroPython/MicroPythonWebreplDeviceInterface.py

Tue, 02 May 2023 12:01:40 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Tue, 02 May 2023 12:01:40 +0200
branch
mpy_network
changeset 10008
c5bcafe3485c
child 10012
d649d500a9a1
permissions
-rw-r--r--

MicroPython
- Added an interface to the `WebRepl` of some devices.

10008
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1 # -*- coding: utf-8 -*-
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
2
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
3 # Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
4 #
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
5
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
6 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
7 Module implementing an interface to talk to a connected MicroPython device via
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
8 a webrepl connection.
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
9 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
10
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
11 from PyQt6.QtCore import QThread, pyqtSlot
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
12 from PyQt6.QtWidgets import QInputDialog, QLineEdit
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
13
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
14 from eric7 import Preferences
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
15 from eric7.EricWidgets import EricMessageBox
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
16
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
17 from .MicroPythonDeviceInterface import MicroPythonDeviceInterface
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
18 from .MicroPythonWebreplSocket import MicroPythonWebreplSocket
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
19
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
20
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
21 class MicroPythonWebreplDeviceInterface(MicroPythonDeviceInterface):
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
22 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
23 Class implementing an interface to talk to a connected MicroPython device via
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
24 a webrepl connection.
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
25 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
26
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
27 def __init__(self, parent=None):
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
28 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
29 Constructor
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
30
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
31 @param parent reference to the parent object
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
32 @type QObject
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
33 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
34 super().__init__(parent)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
35
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
36 self.__blockReadyRead = False
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
37
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
38 self.__socket = MicroPythonWebreplSocket(
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
39 timeout=Preferences.getMicroPython("WebreplTimeout"), parent=self
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
40 )
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
41 self.__connected = False
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
42 self.__socket.readyRead.connect(self.__readSocket)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
43
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
44 @pyqtSlot()
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
45 def __readSocket(self):
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
46 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
47 Private slot to read all available data and emit it with the
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
48 "dataReceived" signal for further processing.
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
49 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
50 if not self.__blockReadyRead:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
51 data = bytes(self.__socket.readAll())
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
52 self.dataReceived.emit(data)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
53
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
54 def __readAll(self):
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
55 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
56 Private method to read all data and emit it for further processing.
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
57 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
58 data = self.__socket.readAll()
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
59 self.dataReceived.emit(data)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
60
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
61 @pyqtSlot()
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
62 def connectToDevice(self, connection):
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
63 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
64 Public slot to connect to the device.
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
65
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
66 @param connection name of the connection to be used in the form of an URL string
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
67 (ws://password@host:port)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
68 @type str
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
69 @return flag indicating success
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
70 @rtype bool
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
71 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
72 connection = connection.replace("ws://", "")
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
73 try:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
74 password, hostPort = connection.split("@", 1)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
75 except ValueError:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
76 password, hostPort = None, connection
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
77 if password is None:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
78 password, ok = QInputDialog.getText(
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
79 None,
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
80 self.tr("WebRepl Password"),
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
81 self.tr("Enter the WebRepl password:"),
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
82 QLineEdit.EchoMode.Password,
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
83 )
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
84 if not ok:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
85 return False
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
86
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
87 try:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
88 host, port = hostPort.split(":", 1)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
89 port = int(port)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
90 except ValueError:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
91 host, port = hostPort, 8266 # default port is 8266
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
92
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
93 self.__blockReadyRead = True
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
94 ok = self.__socket.connectToDevice(host, port)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
95 if ok:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
96 ok = self.__socket.login(password)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
97 if not ok:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
98 EricMessageBox.warning(
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
99 None,
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
100 self.tr("WebRepl Login"),
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
101 self.tr(
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
102 "The login to the selected device 'webrepl' failed. The given"
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
103 " password may be incorrect."
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
104 ),
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
105 )
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
106
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
107 self.__connected = ok
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
108 self.__blockReadyRead = False
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
109
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
110 return self.__connected
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
111
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
112 @pyqtSlot()
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
113 def disconnectFromDevice(self):
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
114 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
115 Public slot to disconnect from the device.
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
116 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
117 self.__socket.disconnect()
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
118 self.__connected = False
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
119
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
120 def isConnected(self):
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
121 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
122 Public method to get the connection status.
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
123
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
124 @return flag indicating the connection status
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
125 @rtype bool
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
126 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
127 return self.__connected
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
128
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
129 @pyqtSlot()
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
130 def handlePreferencesChanged(self):
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
131 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
132 Public slot to handle a change of the preferences.
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
133 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
134 self.__socket.setTimeout(Preferences.getMicroPython("WebreplTimeout"))
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
135
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
136 def write(self, data):
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
137 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
138 Public method to write data to the connected device.
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
139
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
140 @param data data to be written
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
141 @type bytes or bytearray
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
142 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
143 self.__connected and self.__socket.writeTextMessage(data)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
144
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
145 def probeDevice(self):
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
146 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
147 Public method to check the device is responding.
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
148
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
149 If the device has not been flashed with a MicroPython firmware, the
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
150 probe will fail.
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
151
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
152 @return flag indicating a communicating MicroPython device
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
153 @rtype bool
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
154 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
155 if not self.__connected:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
156 return False
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
157
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
158 # switch on paste mode
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
159 self.__blockReadyRead = True
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
160 ok = self.__pasteOn()
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
161 if not ok:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
162 self.__blockReadyRead = False
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
163 return False
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
164
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
165 # switch off raw mode
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
166 QThread.msleep(10)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
167 self.__pasteOff()
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
168 self.__blockReadyRead = False
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
169
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
170 return True
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
171
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
172 def execute(self, commands, *, mode="raw", timeout=0):
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
173 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
174 Public method to send commands to the connected device and return the
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
175 result.
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
176
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
177 @param commands list of commands to be executed
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
178 @type str or list of str
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
179 @keyparam mode submit mode to be used (one of 'raw' or 'paste') (defaults to
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
180 'raw'). This is ignored because webrepl always uses 'paste' mode.
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
181 @type str
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
182 @keyparam timeout per command timeout in milliseconds (0 for configured default)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
183 (defaults to 0)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
184 @type int (optional)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
185 @return tuple containing stdout and stderr output of the device
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
186 @rtype tuple of (bytes, bytes)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
187 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
188 if not self.__connected:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
189 return b"", b"Device is not connected."
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
190
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
191 if isinstance(commands, list):
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
192 commands = "\n".join(commands)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
193
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
194 # switch on paste mode
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
195 self.__blockReadyRead = True
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
196 ok = self.__pasteOn()
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
197 if not ok:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
198 self.__blockReadyRead = False
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
199 return (b"", b"Could not switch to paste mode. Is the device switched on?")
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
200
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
201 # send commands
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
202 commandBytes = commands.encode("utf-8")
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
203 self.__socket.writeTextMessage(commandBytes)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
204 ok = self.__socket.readUntil(commandBytes)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
205 if ok != commandBytes:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
206 self.__blockReadyRead = False
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
207 return (
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
208 b"",
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
209 "Expected '{0}', got '{1}', followed by '{2}'".format(
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
210 commandBytes, ok, self.__socket.readAll()
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
211 ).encode("utf-8"),
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
212 )
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
213
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
214 # switch off paste mode causing the commands to be executed
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
215 self.__pasteOff()
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
216
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
217 # read until Python prompt
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
218 result = (
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
219 self.__socket.readUntil(b">>> ", timeout=timeout)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
220 .replace(b">>> ", b"")
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
221 .strip()
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
222 )
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
223 if self.__socket.hasTimedOut():
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
224 self.__blockReadyRead = False
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
225 return b"", b"Timeout while processing commands."
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
226
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
227 # get rid of any OSD string
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
228 # TODO: emit the OSD data
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
229 if result.startswith(b"\x1b]0;"):
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
230 result = result.split(b"\x1b\\")[-1]
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
231
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
232 if self.TracebackMarker in result:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
233 errorIndex = result.find(self.TracebackMarker)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
234 out, err = result[:errorIndex], result[errorIndex:].replace(">>> ", "")
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
235 else:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
236 out = result
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
237 err = b""
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
238
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
239 self.__blockReadyRead = False
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
240 return out, err
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
241
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
242 def executeAsync(self, commandsList, submitMode):
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
243 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
244 Public method to execute a series of commands over a period of time
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
245 without returning any result (asynchronous execution).
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
246
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
247 @param commandsList list of commands to be execute on the device
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
248 @type list of str
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
249 @param submitMode mode to be used to submit the commands
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
250 @type str (one of 'raw' or 'paste')
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
251 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
252 self.__blockReadyRead = True
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
253 self.__pasteOn()
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
254 command = b"\n".join(c.encode("utf-8)") for c in commandsList)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
255 self.__socket.writeTextMessage(command)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
256 self.__socket.readUntil(command)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
257 self.__blockReadyRead = False
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
258 self.__pasteOff()
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
259 self.executeAsyncFinished.emit()
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
260
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
261 def __pasteOn(self):
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
262 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
263 Private method to switch the connected device to 'paste' mode.
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
264
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
265 Note: switching to paste mode is done with synchronous writes.
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
266
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
267 @return flag indicating success
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
268 @rtype bool
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
269 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
270 if not self.__connected:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
271 return False
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
272
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
273 pasteMessage = b"paste mode; Ctrl-C to cancel, Ctrl-D to finish\r\n=== "
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
274
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
275 self.__socket.writeTextMessage(b"\x02") # end raw mode if required
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
276 for _i in range(3):
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
277 # CTRL-C three times to break out of loops
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
278 self.__socket.writeTextMessage(b"\r\x03")
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
279 # time out after 500ms if device is not responding
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
280 self.__socket.readAll() # read all data and discard it
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
281 self.__socket.writeTextMessage(b"\r\x05") # send CTRL-E to enter paste mode
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
282 self.__socket.readUntil(pasteMessage)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
283
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
284 if self.__socket.hasTimedOut():
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
285 # it timed out; try it again and than fail
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
286 self.__socket.writeTextMessage(b"\r\x05") # send CTRL-E again
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
287 self.__socket.readUntil(pasteMessage)
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
288 if self.__socket.hasTimedOut():
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
289 return False
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
290
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
291 self.__socket.readAll() # read all data and discard it
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
292 return True
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
293
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
294 def __pasteOff(self):
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
295 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
296 Private method to switch 'paste' mode off.
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
297 """
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
298 if self.__connected:
c5bcafe3485c MicroPython
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
299 self.__socket.writeTextMessage(b"\x04") # send CTRL-D to cancel paste mode

eric ide

mercurial