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