micrOSDevToolKit 2.9.1__py3-none-any.whl → 2.9.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of micrOSDevToolKit might be problematic. Click here for more details.
- micrOS/release_info/micrOS_ReleaseInfo/system_analysis_sum.json +4 -4
- micrOS/source/Common.py +1 -1
- micrOS/source/Logger.py +11 -3
- micrOS/source/Server.py +28 -37
- micrOS/source/Shell.py +71 -73
- {micrOSDevToolKit-2.9.1.dist-info → micrOSDevToolKit-2.9.4.dist-info}/METADATA +1 -1
- {micrOSDevToolKit-2.9.1.dist-info → micrOSDevToolKit-2.9.4.dist-info}/RECORD +19 -19
- toolkit/dashboard_apps/SystemTest.py +2 -1
- toolkit/lib/TerminalColors.py +4 -0
- toolkit/lib/micrOSClient.py +16 -16
- toolkit/socketClient.py +2 -2
- toolkit/workspace/precompiled/Common.mpy +0 -0
- toolkit/workspace/precompiled/Logger.mpy +0 -0
- toolkit/workspace/precompiled/Server.mpy +0 -0
- toolkit/workspace/precompiled/Shell.mpy +0 -0
- {micrOSDevToolKit-2.9.1.data → micrOSDevToolKit-2.9.4.data}/scripts/devToolKit.py +0 -0
- {micrOSDevToolKit-2.9.1.dist-info → micrOSDevToolKit-2.9.4.dist-info}/LICENSE +0 -0
- {micrOSDevToolKit-2.9.1.dist-info → micrOSDevToolKit-2.9.4.dist-info}/WHEEL +0 -0
- {micrOSDevToolKit-2.9.1.dist-info → micrOSDevToolKit-2.9.4.dist-info}/top_level.txt +0 -0
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
1
|
|
14
14
|
],
|
|
15
15
|
"Server.py": [
|
|
16
|
-
9.
|
|
16
|
+
9.5,
|
|
17
17
|
3
|
|
18
18
|
],
|
|
19
19
|
"Web.py": [
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
29
|
|
46
46
|
],
|
|
47
47
|
"Logger.py": [
|
|
48
|
-
8.
|
|
48
|
+
8.75,
|
|
49
49
|
4
|
|
50
50
|
],
|
|
51
51
|
"Common.py": [
|
|
@@ -315,7 +315,7 @@
|
|
|
315
315
|
},
|
|
316
316
|
"summary": {
|
|
317
317
|
"core": [
|
|
318
|
-
|
|
318
|
+
3274,
|
|
319
319
|
23
|
|
320
320
|
],
|
|
321
321
|
"load": [
|
|
@@ -332,6 +332,6 @@
|
|
|
332
332
|
],
|
|
333
333
|
"core_score": 9.06,
|
|
334
334
|
"load_score": 8.22,
|
|
335
|
-
"version": "2.9.
|
|
335
|
+
"version": "2.9.4-0"
|
|
336
336
|
}
|
|
337
337
|
}
|
micrOS/source/Common.py
CHANGED
micrOS/source/Logger.py
CHANGED
|
@@ -6,6 +6,7 @@ Designed by Marcell Ban aka BxNxM
|
|
|
6
6
|
"""
|
|
7
7
|
from time import localtime
|
|
8
8
|
from os import listdir, remove
|
|
9
|
+
from re import match
|
|
9
10
|
|
|
10
11
|
#############################################
|
|
11
12
|
# LOGGING WITH DATA ROTATION #
|
|
@@ -66,6 +67,8 @@ def log_get(f_name, msgobj=None):
|
|
|
66
67
|
"""
|
|
67
68
|
err_cnt = 0
|
|
68
69
|
try:
|
|
70
|
+
if msgobj is not None:
|
|
71
|
+
msgobj(f_name)
|
|
69
72
|
with open(f_name, 'r') as f:
|
|
70
73
|
eline = f.readline().strip()
|
|
71
74
|
while eline:
|
|
@@ -73,7 +76,7 @@ def log_get(f_name, msgobj=None):
|
|
|
73
76
|
err_cnt += 1 if "[ERR]" in eline else 0
|
|
74
77
|
# GIVE BACK .log file contents
|
|
75
78
|
if msgobj is not None:
|
|
76
|
-
msgobj(eline)
|
|
79
|
+
msgobj(f"\t{eline}")
|
|
77
80
|
eline = f.readline().strip()
|
|
78
81
|
except:
|
|
79
82
|
pass
|
|
@@ -82,8 +85,13 @@ def log_get(f_name, msgobj=None):
|
|
|
82
85
|
|
|
83
86
|
def syslog(data=None, msgobj=None):
|
|
84
87
|
if data is None:
|
|
85
|
-
|
|
86
|
-
|
|
88
|
+
err_cnt = sum([log_get(f, msgobj) for f in listdir() if f.endswith(".sys.log")])
|
|
89
|
+
return err_cnt
|
|
90
|
+
|
|
91
|
+
_match = match(r"^\[([^\[\]]+)\]", data)
|
|
92
|
+
log_lvl = _match.group(1).lower() if _match else 'user'
|
|
93
|
+
f_name = f"{log_lvl}.sys.log" if log_lvl in ("err", "warn", "boot") else 'user.sys.log'
|
|
94
|
+
return logger(data, f_name, limit=4)
|
|
87
95
|
|
|
88
96
|
|
|
89
97
|
def log_clean(msgobj=None):
|
micrOS/source/Server.py
CHANGED
|
@@ -114,7 +114,7 @@ class Client:
|
|
|
114
114
|
console_write("[Client] NoCon: response>dev/nul")
|
|
115
115
|
|
|
116
116
|
def send(self, response):
|
|
117
|
-
# Implement in child class - synchronous send method
|
|
117
|
+
# Implement in child class - synchronous send (all) method
|
|
118
118
|
pass
|
|
119
119
|
|
|
120
120
|
async def close(self):
|
|
@@ -196,7 +196,9 @@ class ShellCli(Client, Shell):
|
|
|
196
196
|
|
|
197
197
|
def send(self, response):
|
|
198
198
|
"""
|
|
199
|
-
|
|
199
|
+
Synchronous send function (with drain task)
|
|
200
|
+
- not used in Shell or ShellCli
|
|
201
|
+
- Note: it is a support function for synchronous scenarios: Server.reply_all
|
|
200
202
|
"""
|
|
201
203
|
if self.connected:
|
|
202
204
|
if self.prompt() != response:
|
|
@@ -219,8 +221,7 @@ class ShellCli(Client, Shell):
|
|
|
219
221
|
|
|
220
222
|
async def __wait_for_drain(self):
|
|
221
223
|
"""
|
|
222
|
-
Handle drain serialization
|
|
223
|
-
- solve output data duplicate
|
|
224
|
+
Handle drain serialization - for synchronous send function
|
|
224
225
|
"""
|
|
225
226
|
try:
|
|
226
227
|
# send write buffer
|
|
@@ -233,55 +234,45 @@ class ShellCli(Client, Shell):
|
|
|
233
234
|
# set drain free
|
|
234
235
|
self.drain_event.set() # set drain free (True)
|
|
235
236
|
|
|
236
|
-
async def
|
|
237
|
-
Client.console(f"[ShellCli] Close connection {self.client_id}")
|
|
238
|
-
self.send("Bye!\n")
|
|
239
|
-
# Reset shell state machine
|
|
240
|
-
self.reset()
|
|
241
|
-
await asyncio.sleep_ms(50)
|
|
242
|
-
# Used from Client parent class
|
|
243
|
-
await super().close()
|
|
244
|
-
|
|
245
|
-
async def __shell_cmd(self, request):
|
|
237
|
+
async def a_send(self, response, encode='utf8'):
|
|
246
238
|
"""
|
|
247
|
-
|
|
239
|
+
Async send for Shell (new line + prompt$)
|
|
248
240
|
"""
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
state = self.shell(request)
|
|
254
|
-
if state:
|
|
255
|
-
return False # exit_loop
|
|
256
|
-
return True # exit_loop : Close session when shell returns False (auth Failed, etc.)
|
|
257
|
-
except Exception as e:
|
|
258
|
-
Client.console(f"[ShellCli] Shell exception: {e}")
|
|
259
|
-
if "ECONNRESET" in str(e):
|
|
260
|
-
return True # exit_loop
|
|
261
|
-
self.send("[HA] Critical error - disconnect & hard reset")
|
|
262
|
-
errlog_add("[ERR] Socket critical error - reboot")
|
|
263
|
-
self.reboot()
|
|
241
|
+
if self.prompt() != response:
|
|
242
|
+
# [format] Add new line if not prompt
|
|
243
|
+
response = f"{response}\n"
|
|
244
|
+
await super().a_send(response, encode)
|
|
264
245
|
|
|
265
246
|
async def run_shell(self):
|
|
266
247
|
# Update server task output
|
|
267
248
|
Manager().server_task_msg(','.join(list(Client.ACTIVE_CLIS)))
|
|
268
249
|
# Init prompt
|
|
269
|
-
self.
|
|
250
|
+
await self.a_send(self.prompt())
|
|
270
251
|
# Run async connection handling
|
|
252
|
+
_exit = False
|
|
271
253
|
while self.connected:
|
|
272
254
|
try:
|
|
273
255
|
# Read request msg from client
|
|
274
256
|
state, request = await self.read()
|
|
275
257
|
if state:
|
|
276
258
|
break
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
259
|
+
# Run micrOS shell with request string
|
|
260
|
+
Client.console("[ShellCli] --- #Run shell")
|
|
261
|
+
# Shell -> True (OK) or False (NOK) -> NOK->Close session (auth Failed, etc.)
|
|
262
|
+
_exit = not await self.shell(request)
|
|
281
263
|
except Exception as e:
|
|
282
|
-
errlog_add(f"[ERR]
|
|
264
|
+
errlog_add(f"[ERR] Shell client: {e}")
|
|
265
|
+
if "ECONNRESET" in str(e):
|
|
266
|
+
_exit = True # exit_loop
|
|
267
|
+
else:
|
|
268
|
+
await self.a_send("[HA] Critical error - disconnect & hard reset")
|
|
269
|
+
errlog_add("[ERR] Socket critical error - reboot")
|
|
270
|
+
await self.reboot()
|
|
271
|
+
if _exit:
|
|
272
|
+
collect()
|
|
283
273
|
break
|
|
284
274
|
# Close connection
|
|
275
|
+
await self.a_send("Bye!")
|
|
285
276
|
await self.close()
|
|
286
277
|
|
|
287
278
|
|
|
@@ -418,7 +409,7 @@ class Server:
|
|
|
418
409
|
"""
|
|
419
410
|
for _, cli in Client.ACTIVE_CLIS.items():
|
|
420
411
|
if cli.connected:
|
|
421
|
-
cli.send(msg)
|
|
412
|
+
cli.send(f"~~~ {msg}")
|
|
422
413
|
|
|
423
414
|
def __del__(self):
|
|
424
415
|
Client.console("[ socket server ] <<destructor>>")
|
micrOS/source/Shell.py
CHANGED
|
@@ -25,7 +25,7 @@ from Debug import errlog_add
|
|
|
25
25
|
|
|
26
26
|
class Shell:
|
|
27
27
|
__slots__ = ['__devfid', '__auth_mode', '__hwuid', '__auth_ok', '__conf_mode']
|
|
28
|
-
MICROS_VERSION = '2.9.
|
|
28
|
+
MICROS_VERSION = '2.9.4-0'
|
|
29
29
|
|
|
30
30
|
def __init__(self):
|
|
31
31
|
"""
|
|
@@ -45,10 +45,8 @@ class Shell:
|
|
|
45
45
|
except Exception as e:
|
|
46
46
|
errlog_add(f"[ERR] micrOS version export failed (config): {e}")
|
|
47
47
|
|
|
48
|
-
def
|
|
49
|
-
"""
|
|
50
|
-
Must be defined by child class...
|
|
51
|
-
"""
|
|
48
|
+
async def a_send(self, msg):
|
|
49
|
+
""" Must be defined by parent class... """
|
|
52
50
|
pass
|
|
53
51
|
|
|
54
52
|
def reset(self):
|
|
@@ -56,44 +54,43 @@ class Shell:
|
|
|
56
54
|
self.__auth_ok = False
|
|
57
55
|
self.__conf_mode = False
|
|
58
56
|
|
|
59
|
-
def reboot(self, hard=False):
|
|
60
|
-
"""Reboot micropython VM"""
|
|
61
|
-
self.
|
|
62
|
-
self.send("Bye!")
|
|
57
|
+
async def reboot(self, hard=False):
|
|
58
|
+
""" Reboot micropython VM """
|
|
59
|
+
await self.a_send(f"{'[HARD] ' if hard else ''}Reboot micrOS system.\nBye!")
|
|
63
60
|
if hard:
|
|
64
61
|
hard_reset()
|
|
65
62
|
soft_reset()
|
|
66
63
|
|
|
67
64
|
def prompt(self):
|
|
68
|
-
"""Generate prompt"""
|
|
65
|
+
""" Generate prompt """
|
|
69
66
|
auth = "[password] " if self.__auth_mode and not self.__auth_ok else ""
|
|
70
67
|
mode = "[configure] " if self.__conf_mode else ""
|
|
71
68
|
return f"{auth}{mode}{self.__devfid} $ "
|
|
72
69
|
|
|
73
|
-
def __auth(self, msg_list):
|
|
74
|
-
"""Authorize user"""
|
|
70
|
+
async def __auth(self, msg_list):
|
|
71
|
+
""" Authorize user """
|
|
75
72
|
# Set user auth state
|
|
76
73
|
if self.__auth_mode and not self.__auth_ok:
|
|
77
74
|
# check password
|
|
78
75
|
usrpwd = cfgget('appwd')
|
|
79
76
|
if usrpwd == msg_list[0].strip():
|
|
80
77
|
self.__auth_ok = True
|
|
81
|
-
self.
|
|
78
|
+
await self.a_send("AuthOk")
|
|
82
79
|
return True, []
|
|
83
|
-
self.
|
|
80
|
+
await self.a_send("AuthFailed\nBye!")
|
|
84
81
|
return False, []
|
|
85
82
|
return True, msg_list
|
|
86
83
|
|
|
87
|
-
def shell(self, msg):
|
|
84
|
+
async def shell(self, msg):
|
|
88
85
|
"""
|
|
89
86
|
micrOS Shell main - input string handling
|
|
90
87
|
:param msg: incoming shell command (command or load module call)
|
|
91
88
|
"""
|
|
92
|
-
state = self.__shell(msg)
|
|
93
|
-
self.
|
|
89
|
+
state = await self.__shell(msg)
|
|
90
|
+
await self.a_send(self.prompt())
|
|
94
91
|
return state
|
|
95
92
|
|
|
96
|
-
def __shell(self, msg):
|
|
93
|
+
async def __shell(self, msg):
|
|
97
94
|
"""
|
|
98
95
|
Socket server - interpreter shell
|
|
99
96
|
:param msg: socket input string
|
|
@@ -118,11 +115,11 @@ class Shell:
|
|
|
118
115
|
# Hello message
|
|
119
116
|
if msg_list[0] == 'hello':
|
|
120
117
|
# For low level device identification - hello msg
|
|
121
|
-
self.
|
|
118
|
+
await self.a_send(f"hello:{self.__devfid}:{self.__hwuid}")
|
|
122
119
|
return True
|
|
123
120
|
|
|
124
121
|
# [!] AUTH
|
|
125
|
-
state, msg_list = self.__auth(msg_list)
|
|
122
|
+
state, msg_list = await self.__auth(msg_list)
|
|
126
123
|
if not state:
|
|
127
124
|
return False
|
|
128
125
|
if len(msg_list) == 0:
|
|
@@ -131,7 +128,7 @@ class Shell:
|
|
|
131
128
|
# Version handling
|
|
132
129
|
if msg_list[0] == 'version':
|
|
133
130
|
# For micrOS system version info
|
|
134
|
-
self.
|
|
131
|
+
await self.a_send(str(Shell.MICROS_VERSION))
|
|
135
132
|
return True
|
|
136
133
|
|
|
137
134
|
# Reboot micropython VM
|
|
@@ -140,12 +137,12 @@ class Shell:
|
|
|
140
137
|
if len(msg_list) >= 2 and "-h" in msg_list[1]:
|
|
141
138
|
# reboot / reboot -h
|
|
142
139
|
hard = True
|
|
143
|
-
self.reboot(hard)
|
|
140
|
+
await self.reboot(hard)
|
|
144
141
|
|
|
145
142
|
if msg_list[0].startswith('webrepl'):
|
|
146
143
|
if len(msg_list) == 2 and '-u' in msg_list[1]:
|
|
147
|
-
Shell.webrepl(msg_obj=self.
|
|
148
|
-
Shell.webrepl(msg_obj=self.
|
|
144
|
+
await Shell.webrepl(msg_obj=self.a_send, update=True)
|
|
145
|
+
return await Shell.webrepl(msg_obj=self.a_send)
|
|
149
146
|
|
|
150
147
|
# CONFIGURE MODE STATE: ACCESS FOR NODE_CONFIG.JSON
|
|
151
148
|
if msg_list[0].startswith('conf'):
|
|
@@ -157,34 +154,34 @@ class Shell:
|
|
|
157
154
|
|
|
158
155
|
# HELP MSG
|
|
159
156
|
if msg_list[0] == "help":
|
|
160
|
-
self.
|
|
161
|
-
self.
|
|
162
|
-
self.
|
|
163
|
-
self.
|
|
164
|
-
self.
|
|
165
|
-
self.
|
|
166
|
-
self.
|
|
167
|
-
self.
|
|
168
|
-
self.
|
|
169
|
-
self.
|
|
170
|
-
self.
|
|
171
|
-
self.
|
|
172
|
-
self.
|
|
173
|
-
self.
|
|
174
|
-
self.
|
|
175
|
-
self.
|
|
176
|
-
self.
|
|
177
|
-
self.
|
|
178
|
-
self.
|
|
157
|
+
await self.a_send("[MICROS] - built-in shell commands")
|
|
158
|
+
await self.a_send(" hello - hello msg - for device identification")
|
|
159
|
+
await self.a_send(" modules - show active Load Modules")
|
|
160
|
+
await self.a_send(" version - returns micrOS version")
|
|
161
|
+
await self.a_send(" exit - exit from shell socket prompt")
|
|
162
|
+
await self.a_send(" reboot - system soft reboot (vm), hard reboot (hw): reboot -h")
|
|
163
|
+
await self.a_send(" webrepl - start webrepl, for file transfers use with --update")
|
|
164
|
+
await self.a_send("[CONF] Configure mode - built-in shell commands")
|
|
165
|
+
await self.a_send(" conf - Enter conf mode")
|
|
166
|
+
await self.a_send(" dump - Dump all data")
|
|
167
|
+
await self.a_send(" key - Get value")
|
|
168
|
+
await self.a_send(" key value - Set value")
|
|
169
|
+
await self.a_send(" noconf - Exit conf mode")
|
|
170
|
+
await self.a_send("[TASK] postfix: &x - one-time, &&x - periodic, x: wait ms [x min: 20ms]")
|
|
171
|
+
await self.a_send(" task list - list tasks with <tag>s")
|
|
172
|
+
await self.a_send(" task kill <tag> - stop task")
|
|
173
|
+
await self.a_send(" task show <tag> - show task output")
|
|
174
|
+
await self.a_send("[EXEC] Command mode (LMs):")
|
|
175
|
+
await self.a_send(" help lm - list ALL LoadModules")
|
|
179
176
|
if "lm" in str(msg_list):
|
|
180
|
-
return Shell._show_lm_funcs(msg_obj=self.
|
|
181
|
-
return Shell._show_lm_funcs(msg_obj=self.
|
|
177
|
+
return await Shell._show_lm_funcs(msg_obj=self.a_send)
|
|
178
|
+
return await Shell._show_lm_funcs(msg_obj=self.a_send, active_only=True)
|
|
182
179
|
|
|
183
180
|
# [2] EXECUTE:
|
|
184
181
|
# @1 Configure mode
|
|
185
182
|
if self.__conf_mode and len(msg_list) > 0:
|
|
186
183
|
# Lock thread under config handling is threads available
|
|
187
|
-
return Shell._configure(self.
|
|
184
|
+
return await Shell._configure(self.a_send, msg_list)
|
|
188
185
|
# @2 Command mode
|
|
189
186
|
"""
|
|
190
187
|
INPUT MSG STRUCTURE
|
|
@@ -193,43 +190,43 @@ class Shell:
|
|
|
193
190
|
"""
|
|
194
191
|
try:
|
|
195
192
|
# Execute command via InterpreterCore
|
|
196
|
-
self.
|
|
193
|
+
await self.a_send(lm_exec(arg_list=msg_list)[1])
|
|
197
194
|
return True
|
|
198
195
|
except Exception as e:
|
|
199
|
-
self.
|
|
196
|
+
await self.a_send(f"[ERROR] shell.lm_exec internal error: {e}")
|
|
200
197
|
return False
|
|
201
198
|
|
|
202
199
|
#################################################################
|
|
203
200
|
# CONFIGURE MODE HANDLER #
|
|
204
201
|
#################################################################
|
|
205
202
|
@staticmethod
|
|
206
|
-
def _configure(msg_obj, msg_list):
|
|
203
|
+
async def _configure(msg_obj, msg_list):
|
|
207
204
|
"""
|
|
208
205
|
:param msg_obj: shell output stream function reference (write object)
|
|
209
206
|
:param msg_list: socket input param list
|
|
210
207
|
:return: execution status
|
|
211
208
|
"""
|
|
212
|
-
def dump():
|
|
209
|
+
async def dump():
|
|
213
210
|
nonlocal msg_obj, msg_list
|
|
214
211
|
if msg_list[0] == 'dump':
|
|
215
212
|
search = msg_list[1] if len(msg_list) == 2 else None
|
|
216
213
|
# DUMP DATA
|
|
217
214
|
for _key, value in cfgget().items():
|
|
218
215
|
if search is None or search in _key:
|
|
219
|
-
msg_obj(f" {_key}{' ' * (10 - len(_key))}:{' ' * 7} {value}")
|
|
216
|
+
await msg_obj(f" {_key}{' ' * (10 - len(_key))}:{' ' * 7} {value}")
|
|
220
217
|
return True
|
|
221
218
|
return False
|
|
222
219
|
|
|
223
220
|
# [CONFIG] Get value
|
|
224
221
|
if len(msg_list) == 1:
|
|
225
|
-
if dump(): # Simple dump without param filter
|
|
222
|
+
if await dump(): # Simple dump without param filter
|
|
226
223
|
return True
|
|
227
224
|
# GET SINGLE PARAMETER VALUE
|
|
228
|
-
msg_obj(cfgget(msg_list[0]))
|
|
225
|
+
await msg_obj(cfgget(msg_list[0]))
|
|
229
226
|
return True
|
|
230
227
|
# [CONFIG] Set value
|
|
231
228
|
if len(msg_list) >= 2:
|
|
232
|
-
if dump(): # Dump with search option
|
|
229
|
+
if await dump(): # Dump with search option
|
|
233
230
|
return True
|
|
234
231
|
# Deserialize params
|
|
235
232
|
key = msg_list[0]
|
|
@@ -237,28 +234,28 @@ class Shell:
|
|
|
237
234
|
try:
|
|
238
235
|
output = cfgput(key, " ".join(msg_list[1:]), type_check=True)
|
|
239
236
|
except Exception as e:
|
|
240
|
-
msg_obj(f"node_config write error: {e}")
|
|
237
|
+
await msg_obj(f"node_config write error: {e}")
|
|
241
238
|
output = False
|
|
242
239
|
# Evaluation and reply
|
|
243
|
-
msg_obj('Saved' if output else 'Invalid key' if cfgget(key) is None else 'Failed to save')
|
|
240
|
+
await msg_obj('Saved' if output else 'Invalid key' if cfgget(key) is None else 'Failed to save')
|
|
244
241
|
return True
|
|
245
242
|
|
|
246
243
|
#################################################################
|
|
247
244
|
# COMMAND MODE & LMS HANDLER #
|
|
248
245
|
#################################################################
|
|
249
246
|
@staticmethod
|
|
250
|
-
def _show_lm_funcs(msg_obj, active_only=False):
|
|
247
|
+
async def _show_lm_funcs(msg_obj, active_only=False):
|
|
251
248
|
"""
|
|
252
249
|
Dump LM modules with functions - in case of [py] files
|
|
253
250
|
Dump LM module with help function call - in case of [mpy] files
|
|
254
251
|
"""
|
|
255
|
-
def _help(mod):
|
|
252
|
+
async def _help(mod):
|
|
256
253
|
for lm_path in (i for i in mod if i.startswith('LM_') and (i.endswith('py'))):
|
|
257
254
|
lm_name = lm_path.replace('LM_', '').split('.')[0]
|
|
258
255
|
try:
|
|
259
|
-
msg_obj(f" {lm_name}")
|
|
256
|
+
await msg_obj(f" {lm_name}")
|
|
260
257
|
if lm_path.endswith('.mpy'):
|
|
261
|
-
msg_obj(f" {' ' * len(lm_path.replace('LM_', '').split('.')[0])}help")
|
|
258
|
+
await msg_obj(f" {' ' * len(lm_path.replace('LM_', '').split('.')[0])}help")
|
|
262
259
|
continue
|
|
263
260
|
with open(lm_path, 'r') as f:
|
|
264
261
|
line = "micrOSisTheBest"
|
|
@@ -266,9 +263,9 @@ class Shell:
|
|
|
266
263
|
line = f.readline()
|
|
267
264
|
ldata = line.strip()
|
|
268
265
|
if ldata.startswith('def ') and not ldata.split()[1].startswith("_") and 'self' not in ldata:
|
|
269
|
-
msg_obj(f" {' ' * len(lm_name)}{ldata.replace('def ', '').split('(')[0]}")
|
|
266
|
+
await msg_obj(f" {' ' * len(lm_name)}{ldata.replace('def ', '').split('(')[0]}")
|
|
270
267
|
except Exception as e:
|
|
271
|
-
msg_obj(f"[{lm_path}] SHOW LM PARSER WARNING: {e}")
|
|
268
|
+
await msg_obj(f"[{lm_path}] SHOW LM PARSER WARNING: {e}")
|
|
272
269
|
return False
|
|
273
270
|
return True
|
|
274
271
|
|
|
@@ -276,29 +273,30 @@ class Shell:
|
|
|
276
273
|
if active_only:
|
|
277
274
|
mod_keys = modules.keys()
|
|
278
275
|
active_modules = (dir_mod for dir_mod in listdir() if dir_mod.split('.')[0] in mod_keys)
|
|
279
|
-
return _help(active_modules)
|
|
276
|
+
return await _help(active_modules)
|
|
280
277
|
# [2] list all LMs on file system (ALL - help lm) - manual
|
|
281
|
-
return _help(listdir())
|
|
278
|
+
return await _help(listdir())
|
|
282
279
|
|
|
283
280
|
@staticmethod
|
|
284
|
-
def webrepl(msg_obj, update=False):
|
|
281
|
+
async def webrepl(msg_obj, update=False):
|
|
285
282
|
from Network import ifconfig
|
|
286
283
|
|
|
287
|
-
msg_obj(" Start micropython WEBREPL - file transfer and debugging")
|
|
288
|
-
msg_obj(" [i] restart machine shortcut: import reset")
|
|
289
|
-
msg_obj(f" Connect over http://micropython.org/webrepl/#{ifconfig()[1][0]}:8266/")
|
|
290
|
-
msg_obj(f" \t[!] webrepl password: {cfgget('appwd')}")
|
|
284
|
+
await msg_obj(" Start micropython WEBREPL - file transfer and debugging")
|
|
285
|
+
await msg_obj(" [i] restart machine shortcut: import reset")
|
|
286
|
+
await msg_obj(f" Connect over http://micropython.org/webrepl/#{ifconfig()[1][0]}:8266/")
|
|
287
|
+
await msg_obj(f" \t[!] webrepl password: {cfgget('appwd')}")
|
|
291
288
|
if update:
|
|
292
|
-
msg_obj(" Restart node then start webrepl...")
|
|
293
|
-
msg_obj(" Bye!")
|
|
289
|
+
await msg_obj(" Restart node then start webrepl...")
|
|
290
|
+
await msg_obj(" Bye!")
|
|
294
291
|
# Set .if_mode->webrepl (start webrepl after reboot and poll update status...)
|
|
295
292
|
with open('.if_mode', 'w') as f:
|
|
296
293
|
f.write('webrepl')
|
|
297
294
|
hard_reset()
|
|
298
295
|
try:
|
|
299
296
|
import webrepl
|
|
300
|
-
msg_obj(webrepl.start(password=cfgget('appwd')))
|
|
297
|
+
await msg_obj(webrepl.start(password=cfgget('appwd')))
|
|
301
298
|
except Exception as e:
|
|
302
299
|
_err_msg = f"[ERR] while starting webrepl: {e}"
|
|
303
|
-
msg_obj(_err_msg)
|
|
300
|
+
await msg_obj(_err_msg)
|
|
304
301
|
errlog_add(_err_msg)
|
|
302
|
+
return True
|
|
@@ -32,9 +32,9 @@ micrOS/micropython/esp32s3_spiram_oct-20231005-v1.21.0.bin,sha256=S-sv_QeL_Tylg1
|
|
|
32
32
|
micrOS/micropython/esp32s3_spiram_oct-20241129-v1.24.1.bin,sha256=VbOF_F0YeqttkQd2ePTW66Jd34RU8u9ccFfcv8kxO_U,1662672
|
|
33
33
|
micrOS/micropython/rpi-pico-w-20241129-v1.24.1.uf2,sha256=v4aYIbWaE94_f6DDzBWS-a9L1BzlcdkZwld9R7bOVA4,1727488
|
|
34
34
|
micrOS/micropython/tinypico-20241129-v1.24.1.bin,sha256=Kf3cr766a5SK99CZy8bwdWjwvAZxls3tBYvaHBsw7ac,1527200
|
|
35
|
-
micrOS/release_info/micrOS_ReleaseInfo/system_analysis_sum.json,sha256=
|
|
35
|
+
micrOS/release_info/micrOS_ReleaseInfo/system_analysis_sum.json,sha256=PTEMH6a2gWZnHxpB41WWkE5hJQwMUk_t6VECFbg2Ecc,5761
|
|
36
36
|
micrOS/source/.DS_Store,sha256=1lFlJ5EFymdzGAUAaI30vcaaLHt3F1LwpG7xILf9jsM,6148
|
|
37
|
-
micrOS/source/Common.py,sha256=
|
|
37
|
+
micrOS/source/Common.py,sha256=PAdtseGY6QxUM-5elOAcApUv8AwGQ_smsYex0FeV5w8,7937
|
|
38
38
|
micrOS/source/Config.py,sha256=me_mhQaqeIE5pVfd2SSZL5uuO2cTHRtjaiUcau4riJo,8867
|
|
39
39
|
micrOS/source/Debug.py,sha256=_7HZzZ2OKJrcNqeYsG1ZykBa6iN8YTj-K5FFXlEAcRw,5300
|
|
40
40
|
micrOS/source/Espnow.py,sha256=5B71XVm19byydMuhLmg-ij8uNmfMSAaRNi4iytvFN08,3715
|
|
@@ -104,12 +104,12 @@ micrOS/source/LM_telegram.py,sha256=8mwKUywZWbbjYKN68wnrXw4RnvOBI1OKlJrU4sfbG4U,
|
|
|
104
104
|
micrOS/source/LM_tinyrgb.py,sha256=kChL607HPTl3Z2hYN2XnzXXfZ6omdP78PQutHdbdfCo,3031
|
|
105
105
|
micrOS/source/LM_trackball.py,sha256=pVnL_GoXUbqwT6sflqysFWmamVGZOZwHPphrLt5MZXw,9728
|
|
106
106
|
micrOS/source/LM_veml7700.py,sha256=p2NXb5o5c_tM68rBfbgcfxBR31-BY2jGS2JVF3AYBfk,5771
|
|
107
|
-
micrOS/source/Logger.py,sha256=
|
|
107
|
+
micrOS/source/Logger.py,sha256=5dYTcxcGYRFkZvILuuW88coge1ChbupZvo_M8g0r5yE,3204
|
|
108
108
|
micrOS/source/Network.py,sha256=wLhAPiRyi376TKJA7tzCQidDBHq-AbZGGp7JabHIyl8,9417
|
|
109
109
|
micrOS/source/Notify.py,sha256=Fm4TfbiFCTz_95aQkMZBikakNUtAv7eZplI7XyufPRI,2351
|
|
110
110
|
micrOS/source/Scheduler.py,sha256=K6fw807UJnOmbfzgeJQGzGbTL4s2sTIB120ZcS5qrLs,9648
|
|
111
|
-
micrOS/source/Server.py,sha256=
|
|
112
|
-
micrOS/source/Shell.py,sha256
|
|
111
|
+
micrOS/source/Server.py,sha256=ytt0-PeoPnuyKdp08UNunna1a9MnVBtQaJQrlUpt4N8,16161
|
|
112
|
+
micrOS/source/Shell.py,sha256=DR_4OxlDty14I7j2AOIl3zCcOVcLMojdzt6z3kopH4g,12388
|
|
113
113
|
micrOS/source/Tasks.py,sha256=YMYt86TWnUBWa8j1DQjbOavYpktCizzfZXaKXrb6Fmo,22498
|
|
114
114
|
micrOS/source/Time.py,sha256=96XMJjHCPwQ2qNuBD2Un7FXxzXZNbV1xCQn-RujsggU,6351
|
|
115
115
|
micrOS/source/Types.py,sha256=3O_Vb1jN92RPtvgbV8ui6_iFzDOD-BUzVXlPB7PgmM4,3507
|
|
@@ -127,7 +127,7 @@ micrOS/source/urequests.py,sha256=f6IAPK1_xKVL69t1GlPc3zyKkWIwjOCEN7l8vqMjBp8,84
|
|
|
127
127
|
micrOS/source/ustyle.css,sha256=P-s8ENwAcWoZi5bocrK3_kVzEjaRFKtFvEF6JRh4MBY,1429
|
|
128
128
|
micrOS/source/uwidgets.js,sha256=BGeUSbNHn6PClgIgIE6QszwQVJ6j7lzgCBwvIX8cYgo,6631
|
|
129
129
|
micrOS/source/uwidgets_pro.js,sha256=gbkk3SVttEVvDCwde-pJhAh4k7GuCFPdcWNq32pcKPE,3639
|
|
130
|
-
micrOSDevToolKit-2.9.
|
|
130
|
+
micrOSDevToolKit-2.9.4.data/scripts/devToolKit.py,sha256=CVgEETK2JwWgtEFw_dAZPEfOpAQTYZfTb6810E1j2Hg,10660
|
|
131
131
|
toolkit/DevEnvCompile.py,sha256=H19-60ZpHzP30C-wqR5QTzMDHHpWrTk0Uzh--TZHxvw,12148
|
|
132
132
|
toolkit/DevEnvOTA.py,sha256=OkEtO5cpym-kEgGpE3TQbyZ-nQOzZpGzbFdbgCibe7I,25356
|
|
133
133
|
toolkit/DevEnvUSB.py,sha256=-Fdigxi8asEJG4npQpvbpgjHhESq0gz0rL6lthRupVA,33848
|
|
@@ -139,7 +139,7 @@ toolkit/img_stream.html,sha256=ZGyrUgpi-JhMl4euS-TTjwwGrg66a2pGUQCopWiveds,5135
|
|
|
139
139
|
toolkit/index.html,sha256=pnwz1tpBdO-FRlsOLQ4-ah5hT8f-O_hhAI411QdiVJA,10873
|
|
140
140
|
toolkit/micrOSdashboard.py,sha256=SOBzGU1b-NIn40GMd2gE01Fuo8HZP5d1XyVG24RkPeA,54433
|
|
141
141
|
toolkit/micrOSlint.py,sha256=Ujmgtt79UFkoPmyp1u_XN8FYjOh2puA8XpaJNk47bZ0,25107
|
|
142
|
-
toolkit/socketClient.py,sha256=
|
|
142
|
+
toolkit/socketClient.py,sha256=qBPmDPu9FyASlNZ2Q2gP4e-EGu6VyAC7ByiApQlu-CY,18623
|
|
143
143
|
toolkit/dashboard_apps/AirQualityBME280.py,sha256=ufYAn_eFpCIcNSQUW6AGQN6Uh_5A3xVqSyoWegUNBuY,747
|
|
144
144
|
toolkit/dashboard_apps/AirQualityDHT22_CO2.py,sha256=TG8Wkx7WOaGM1rpqD6t2rKFES0aqdCJvK-f5I5IK3a4,749
|
|
145
145
|
toolkit/dashboard_apps/BackupRestore.py,sha256=zRkj6KDFnO9Cj6QUpE0Av39OQZcI8CycQcrqbvWBHqU,6339
|
|
@@ -156,7 +156,7 @@ toolkit/dashboard_apps/PresenceTest.py,sha256=MnWjqh3W3qAR9pKdjrOfx74numQw6-acrR
|
|
|
156
156
|
toolkit/dashboard_apps/RGBTest.py,sha256=x9ehV6EGH2B4syKGEQrZQbMy1pBsB1M6in8idJ73Jrw,3920
|
|
157
157
|
toolkit/dashboard_apps/RoboArm.py,sha256=STFIYYy0Li6gLdJx7eu3FZOucF_f5jupHVNFzU-Ta-Q,2084
|
|
158
158
|
toolkit/dashboard_apps/SED_test.py,sha256=ASVRcoVQiS80tvjQHBnXd69aAioJ4lt_UnL1KAy01sM,2782
|
|
159
|
-
toolkit/dashboard_apps/SystemTest.py,sha256=
|
|
159
|
+
toolkit/dashboard_apps/SystemTest.py,sha256=Cc_CBiNLaE1UYw9TIQtDLKgtCUcjCtjKbE5lX6utQJE,21816
|
|
160
160
|
toolkit/dashboard_apps/Template_app.py,sha256=fKF43E-XqibavvjUrCQzG-kMSTCe-sb3ckbLwDgGuTc,1002
|
|
161
161
|
toolkit/dashboard_apps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
162
162
|
toolkit/dashboard_apps/_capture.py,sha256=75aS8ajhEYWNqoG2DwQgqJyArMouGHZNN-0mo1RH9bU,3076
|
|
@@ -167,11 +167,11 @@ toolkit/lib/LocalMachine.py,sha256=m5xaWRx1PumKFLQ5_O8vVxC4NTclF1h9J3__pK8N-C4,1
|
|
|
167
167
|
toolkit/lib/SafeInput.py,sha256=gMXsMalPcFCwlN6niJlG2twOHfoGsEgHL9-Uh2YQJHE,855
|
|
168
168
|
toolkit/lib/SearchDevices.py,sha256=1nnJDwo_U5cCN2xsdNUT6EQqdt2fW-qAWXWzyzXzyyc,5813
|
|
169
169
|
toolkit/lib/SerialDriverHandler.py,sha256=Zn0zeq4mshTMVc6fzycvrOZiKt6w6YOxJcTWw3BMN2M,7344
|
|
170
|
-
toolkit/lib/TerminalColors.py,sha256=
|
|
170
|
+
toolkit/lib/TerminalColors.py,sha256=Ly_8o9-eBmka1dqA2M3DBlcd1zvCCO2K_BnQ1XbqxcE,947
|
|
171
171
|
toolkit/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
172
172
|
toolkit/lib/file_extensions.py,sha256=0DpayBGjKQg7y2ZGJXf5wVPnre_4C5j-7YIViNGvYz4,372
|
|
173
173
|
toolkit/lib/macroScript.py,sha256=Hic98kyOR1Up18T6Lrpnnv_8bkNdocnIbiXdv6R7jrI,13854
|
|
174
|
-
toolkit/lib/micrOSClient.py,sha256=
|
|
174
|
+
toolkit/lib/micrOSClient.py,sha256=Rej1x9IpFmCW6LAoFf6ylua7wjwm7Apil2mf1DNW7QA,17163
|
|
175
175
|
toolkit/lib/pip_package_installer.py,sha256=jpC-y1KR72_PJlqyUR6-U5b6l1szVqnIZ4nrSgUsOTM,4262
|
|
176
176
|
toolkit/simulator_lib/.DS_Store,sha256=1lFlJ5EFymdzGAUAaI30vcaaLHt3F1LwpG7xILf9jsM,6148
|
|
177
177
|
toolkit/simulator_lib/IO_darwin.py,sha256=f8HOfQKJvniShvjpBe6f4nisr6oJd9SnvxPsbdNIGQk,2336
|
|
@@ -263,7 +263,7 @@ toolkit/user_data/webhooks/macro.py,sha256=E_Um6fc9P6sBKvChyrKgksHmBmaFUuq_Xxy8I
|
|
|
263
263
|
toolkit/user_data/webhooks/template.macro,sha256=XikSl3FsD6W9pUx3sqavM5tWIMBquFx9f3bh_CB8k-A,631
|
|
264
264
|
toolkit/user_data/webhooks/template.py,sha256=WssXY2BDKIwvObq0SpFCjjpEGzgbLlozFTug4ANswWM,342
|
|
265
265
|
toolkit/workspace/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
266
|
-
toolkit/workspace/precompiled/Common.mpy,sha256=
|
|
266
|
+
toolkit/workspace/precompiled/Common.mpy,sha256=2bUIMJPc9AAVGtgzI_6DaNqF6T-kLyyd4Ys_yjrgI9A,2140
|
|
267
267
|
toolkit/workspace/precompiled/Config.mpy,sha256=X1SAfiWEMvduP6kFcVSjfY3TJsIKcbITDq1lrEIj67M,3076
|
|
268
268
|
toolkit/workspace/precompiled/Debug.mpy,sha256=OpoE-QcllAnASSnAC0V364G7zHjbYI_0jSPzPRBhWkI,1823
|
|
269
269
|
toolkit/workspace/precompiled/Espnow.mpy,sha256=yzC_KeCfVzWKidRbEw_R6LQeKG6DFMu4XAssXqFSuKQ,1438
|
|
@@ -333,12 +333,12 @@ toolkit/workspace/precompiled/LM_telegram.mpy,sha256=qdsv0aHVhrpNvrWKzzdIi4xvuT2
|
|
|
333
333
|
toolkit/workspace/precompiled/LM_tinyrgb.mpy,sha256=qWR-e8DXuzmstxQlyic0YjwFaGiBBBWpf57Wyn1jjFc,1016
|
|
334
334
|
toolkit/workspace/precompiled/LM_trackball.mpy,sha256=8OFO02VeETcwkuOACh0e9amRWwTpoRogEXcVmRBrUn4,3474
|
|
335
335
|
toolkit/workspace/precompiled/LM_veml7700.mpy,sha256=-MPEbH9RzOk0hzBuXf5XzOHKZdeRD0xBgf890GJu6Vg,1956
|
|
336
|
-
toolkit/workspace/precompiled/Logger.mpy,sha256=
|
|
336
|
+
toolkit/workspace/precompiled/Logger.mpy,sha256=ztBXR7yqWezXuLSbsmZP41pWUq_4cw9K6aNcQgNe-nM,1081
|
|
337
337
|
toolkit/workspace/precompiled/Network.mpy,sha256=WtpvhGB2bvEe94dAHV40fpEyk-Fi0D6vL1q_m6k4qBg,3274
|
|
338
338
|
toolkit/workspace/precompiled/Notify.mpy,sha256=lyl5J16b8X2vnHzHSikzlNCX5XLQ7JaB0midEmVMn58,872
|
|
339
339
|
toolkit/workspace/precompiled/Scheduler.mpy,sha256=ctCj7FfXj5TchPPxe_9dmnTXWN88egtbAnmJ0N9u_1w,2202
|
|
340
|
-
toolkit/workspace/precompiled/Server.mpy,sha256=
|
|
341
|
-
toolkit/workspace/precompiled/Shell.mpy,sha256=
|
|
340
|
+
toolkit/workspace/precompiled/Server.mpy,sha256=Rk_Pkg_Pc_7W6tIiRcGfU4S9YChYPYw4-WKOqz0gUZY,4746
|
|
341
|
+
toolkit/workspace/precompiled/Shell.mpy,sha256=z52FjUhn2S345FjXp8KgyQ30rFvgOVkcVDwpcSfDqNk,4334
|
|
342
342
|
toolkit/workspace/precompiled/Tasks.mpy,sha256=vL3tDV7Us3Wg7qtZA8ovqEsvLndOmu14GHcZF2_DtrY,6253
|
|
343
343
|
toolkit/workspace/precompiled/Time.mpy,sha256=D6jvLP5tUKQdJGcn6Q4-ru-p0at6hnxfLC5bqC78gv0,2756
|
|
344
344
|
toolkit/workspace/precompiled/Types.mpy,sha256=LssRbPgvsWuR4d2m3R7VMIvsnkVp9nN0ltwaY2wGop8,1401
|
|
@@ -358,8 +358,8 @@ toolkit/workspace/precompiled/urequests.mpy,sha256=FnrzbNJtHfmIJN1PpwhQ__CDx6Vmd
|
|
|
358
358
|
toolkit/workspace/precompiled/ustyle.css,sha256=P-s8ENwAcWoZi5bocrK3_kVzEjaRFKtFvEF6JRh4MBY,1429
|
|
359
359
|
toolkit/workspace/precompiled/uwidgets.js,sha256=BGeUSbNHn6PClgIgIE6QszwQVJ6j7lzgCBwvIX8cYgo,6631
|
|
360
360
|
toolkit/workspace/precompiled/uwidgets_pro.js,sha256=gbkk3SVttEVvDCwde-pJhAh4k7GuCFPdcWNq32pcKPE,3639
|
|
361
|
-
micrOSDevToolKit-2.9.
|
|
362
|
-
micrOSDevToolKit-2.9.
|
|
363
|
-
micrOSDevToolKit-2.9.
|
|
364
|
-
micrOSDevToolKit-2.9.
|
|
365
|
-
micrOSDevToolKit-2.9.
|
|
361
|
+
micrOSDevToolKit-2.9.4.dist-info/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
|
|
362
|
+
micrOSDevToolKit-2.9.4.dist-info/METADATA,sha256=2UV8fRBCkJApZjqaoF9oIvrKoWke7Bnl_YUoErTz0Pw,53468
|
|
363
|
+
micrOSDevToolKit-2.9.4.dist-info/WHEEL,sha256=UvcQYKBHoFqaQd6LKyqHw9fxEolWLQnlzP0h_LgJAfI,91
|
|
364
|
+
micrOSDevToolKit-2.9.4.dist-info/top_level.txt,sha256=rOGOIXqLBdGZAoDTiLdZ9B_leFB7bMv7YabLwuIc2bc,25
|
|
365
|
+
micrOSDevToolKit-2.9.4.dist-info/RECORD,,
|
|
@@ -359,8 +359,9 @@ def check_robustness_recursion():
|
|
|
359
359
|
def check_intercon(host=None):
|
|
360
360
|
def _convert_return_to_dict(data):
|
|
361
361
|
try:
|
|
362
|
-
data_dict = ast.literal_eval(data[1])
|
|
362
|
+
data_dict = ast.literal_eval(data[1].split("\n")[0])
|
|
363
363
|
except Exception as e:
|
|
364
|
+
print(f"WARNING: cannot parse output as dir: {e}")
|
|
364
365
|
data_dict = {'tag': None, 'verdict': f'{data}: {str(e)}'}
|
|
365
366
|
return data[0], data_dict
|
|
366
367
|
|
toolkit/lib/TerminalColors.py
CHANGED
|
@@ -16,6 +16,8 @@ class Colors:
|
|
|
16
16
|
OKGREEN = '\033[92m'
|
|
17
17
|
HEADER = '\033[95m'
|
|
18
18
|
UNDERLINE = '\033[4m'
|
|
19
|
+
LIGHT_GRAY = '\033[37m'
|
|
20
|
+
GRAY = '\033[90m'
|
|
19
21
|
else:
|
|
20
22
|
NC = ''
|
|
21
23
|
OK = ''
|
|
@@ -26,6 +28,8 @@ class Colors:
|
|
|
26
28
|
OKGREEN = ''
|
|
27
29
|
HEADER = ''
|
|
28
30
|
UNDERLINE = ''
|
|
31
|
+
LIGHT_GRAY = ''
|
|
32
|
+
GRAY = ''
|
|
29
33
|
|
|
30
34
|
|
|
31
35
|
if __name__ == "__main__":
|
toolkit/lib/micrOSClient.py
CHANGED
|
@@ -160,7 +160,7 @@ class micrOSClient:
|
|
|
160
160
|
self.preprompt = ""
|
|
161
161
|
return _data
|
|
162
162
|
|
|
163
|
-
def __receive_data(self, read_timeout=20):
|
|
163
|
+
def __receive_data(self, read_timeout=20, stream=False):
|
|
164
164
|
"""
|
|
165
165
|
Client Receiver Loop
|
|
166
166
|
- read_timeout - wait for server to reply (should be <15, avoid msg queue-ing)
|
|
@@ -173,7 +173,11 @@ class micrOSClient:
|
|
|
173
173
|
# Collect answer data
|
|
174
174
|
if select.select([self.conn], [], [], read_timeout)[0]:
|
|
175
175
|
while True:
|
|
176
|
-
|
|
176
|
+
incoming_data = self.conn.recv(4096).decode('utf-8')
|
|
177
|
+
if stream:
|
|
178
|
+
incoming_data = incoming_data.replace(self.prompt, f"{color.NC}{color.BOLD}{self.prompt}{color.NC}")
|
|
179
|
+
print(f"\r{color.LIGHT_GRAY}{incoming_data}{color.NC}", end="")
|
|
180
|
+
data_buffer += incoming_data
|
|
177
181
|
# Last line from data_buffer (handle fragmented messages - prompt detection)
|
|
178
182
|
last_line = data_buffer.strip().split("\n")[-1]
|
|
179
183
|
# Wait for prompt or special cases (exit/prompt)
|
|
@@ -200,7 +204,7 @@ class micrOSClient:
|
|
|
200
204
|
self.isconn = False
|
|
201
205
|
self.spacer = 0
|
|
202
206
|
|
|
203
|
-
def __run_command(self, cmd):
|
|
207
|
+
def __run_command(self, cmd, stream=False):
|
|
204
208
|
"""
|
|
205
209
|
Run command on server tcp/ip connection
|
|
206
210
|
- prompt check - validate device ("hostname $" = "prompt")
|
|
@@ -218,14 +222,14 @@ class micrOSClient:
|
|
|
218
222
|
# Workaround for reboot command - micrOS async server cannot send Bye! msg before reboot.
|
|
219
223
|
if reboot_request:
|
|
220
224
|
return 'Bye!'
|
|
221
|
-
data = self.__receive_data()
|
|
225
|
+
data = self.__receive_data(stream=stream)
|
|
222
226
|
return data
|
|
223
227
|
# Skip command run: prompt and host not the same!
|
|
224
228
|
print(f"[micrOSClient] {color.ERR}prompt mismatch{color.NC}, hostname: {check_hostname} prompt: {check_prompt} ")
|
|
225
229
|
# Check UID?
|
|
226
230
|
return None
|
|
227
231
|
|
|
228
|
-
def send_cmd(self, cmd, timeout=3, retry=5):
|
|
232
|
+
def send_cmd(self, cmd, timeout=3, retry=5, stream=False):
|
|
229
233
|
"""
|
|
230
234
|
Send command function - main usage for non interactive mode
|
|
231
235
|
"""
|
|
@@ -244,7 +248,7 @@ class micrOSClient:
|
|
|
244
248
|
|
|
245
249
|
# @ Run command
|
|
246
250
|
try:
|
|
247
|
-
out = self.__run_command(cmd)
|
|
251
|
+
out = self.__run_command(cmd, stream=stream)
|
|
248
252
|
except Exception as e:
|
|
249
253
|
self.dbg_print("{}[ERR]{} send_cmd error: {}".format(color.ERR, color.NC, e))
|
|
250
254
|
self.dbg_print("Auto deinit connection")
|
|
@@ -261,11 +265,11 @@ class micrOSClient:
|
|
|
261
265
|
# return output list
|
|
262
266
|
return out
|
|
263
267
|
|
|
264
|
-
def send_cmd_retry(self, cmd, timeout=6, retry=5):
|
|
268
|
+
def send_cmd_retry(self, cmd, timeout=6, retry=5, stream=False):
|
|
265
269
|
out = None
|
|
266
270
|
for cnt in range(0, retry):
|
|
267
271
|
try:
|
|
268
|
-
out = self.send_cmd(cmd, timeout)
|
|
272
|
+
out = self.send_cmd(cmd, timeout, stream=stream)
|
|
269
273
|
if out is None or isinstance(out, list):
|
|
270
274
|
break
|
|
271
275
|
except OSError as e:
|
|
@@ -287,16 +291,12 @@ class micrOSClient:
|
|
|
287
291
|
print("Telnet connect: {}".format(e))
|
|
288
292
|
if "busy" in str(e) or "timed out" in str(e) or "No route to host" in str(e) or "Host is down" in str(e):
|
|
289
293
|
return
|
|
294
|
+
|
|
295
|
+
print(f"{color.BOLD}{self.preprompt}{self.prompt}{color.NC} ", end="")
|
|
290
296
|
while True:
|
|
291
|
-
cmd = input(
|
|
297
|
+
cmd = input()
|
|
292
298
|
# send command
|
|
293
|
-
output = self.send_cmd(cmd)
|
|
294
|
-
# Format output to human readable
|
|
295
|
-
output = '\n'.join(output) if isinstance(output, list) else output
|
|
296
|
-
# output to STDOUT
|
|
297
|
-
if not (cmd.strip() == '' and output is None):
|
|
298
|
-
print(output)
|
|
299
|
-
# Close session
|
|
299
|
+
output = self.send_cmd(cmd, stream=True)
|
|
300
300
|
if 'Bye!' in str(output):
|
|
301
301
|
break
|
|
302
302
|
self.close()
|
toolkit/socketClient.py
CHANGED
|
@@ -210,8 +210,8 @@ class ConnectionData:
|
|
|
210
210
|
start_comm = time.time()
|
|
211
211
|
version_data = SocketDictClient(host=ip, port=port, silent_mode=True, tout=3).non_interactive(['version'])
|
|
212
212
|
elapsed_time = "{:.3f}".format(time.time() - start_comm)
|
|
213
|
-
except:
|
|
214
|
-
|
|
213
|
+
except Exception as e:
|
|
214
|
+
print(f"Getting device version {fuid}:{uid} error: {e}")
|
|
215
215
|
|
|
216
216
|
# Generate line printout
|
|
217
217
|
base_info = "{uid}{spr1}{fuid}".format(uid=uid, spr1=spacer1, fuid=fuid)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|