micrOSDevToolKit 2.9.4__py3-none-any.whl → 2.9.6__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 +19 -19
- micrOS/source/Config.py +6 -6
- micrOS/source/LM_pacman.py +248 -0
- micrOS/source/LM_rest.py +0 -1
- micrOS/source/LM_robustness.py +2 -2
- micrOS/source/LM_system.py +4 -16
- micrOS/source/LM_telegram.py +95 -61
- micrOS/source/Logger.py +41 -15
- micrOS/source/Notify.py +4 -3
- micrOS/source/Server.py +5 -2
- micrOS/source/Shell.py +2 -2
- micrOS/source/Web.py +22 -23
- micrOS/source/microIO.py +1 -2
- micrOS/source/reset.py +5 -1
- micrOS/source/urequests.py +12 -4
- {micrOSDevToolKit-2.9.4.data → micrOSDevToolKit-2.9.6.data}/scripts/devToolKit.py +3 -2
- {micrOSDevToolKit-2.9.4.dist-info → micrOSDevToolKit-2.9.6.dist-info}/METADATA +1 -1
- {micrOSDevToolKit-2.9.4.dist-info → micrOSDevToolKit-2.9.6.dist-info}/RECORD +54 -51
- toolkit/Gateway.py +2 -2
- toolkit/dashboard_apps/SystemTest.py +12 -11
- toolkit/index.html +4 -4
- toolkit/lib/macroScript.py +6 -0
- toolkit/lib/micrOSClient.py +35 -8
- toolkit/lib/micrOSClientHistory.py +122 -0
- toolkit/micrOSlint.py +1 -1
- toolkit/simulator_lib/__pycache__/machine.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/uasyncio.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/uos.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/ussl.cpython-312.pyc +0 -0
- toolkit/simulator_lib/machine.py +4 -0
- toolkit/simulator_lib/node_config.json +1 -1
- toolkit/simulator_lib/uasyncio.py +7 -1
- toolkit/simulator_lib/uos.py +138 -0
- toolkit/socketClient.py +2 -2
- toolkit/workspace/precompiled/Config.mpy +0 -0
- toolkit/workspace/precompiled/Espnow.mpy +0 -0
- toolkit/workspace/precompiled/LM_pacman.py +248 -0
- toolkit/workspace/precompiled/LM_rest.mpy +0 -0
- toolkit/workspace/precompiled/LM_robustness.py +2 -2
- toolkit/workspace/precompiled/LM_system.mpy +0 -0
- toolkit/workspace/precompiled/LM_telegram.mpy +0 -0
- toolkit/workspace/precompiled/Logger.mpy +0 -0
- toolkit/workspace/precompiled/Notify.mpy +0 -0
- toolkit/workspace/precompiled/Server.mpy +0 -0
- toolkit/workspace/precompiled/Shell.mpy +0 -0
- toolkit/workspace/precompiled/Web.mpy +0 -0
- toolkit/workspace/precompiled/_mpy.version +1 -1
- toolkit/workspace/precompiled/microIO.mpy +0 -0
- toolkit/workspace/precompiled/node_config.json +1 -1
- toolkit/workspace/precompiled/reset.mpy +0 -0
- toolkit/workspace/precompiled/urequests.mpy +0 -0
- micrOS/source/LM_lmpacman.py +0 -126
- toolkit/workspace/precompiled/LM_lmpacman.mpy +0 -0
- {micrOSDevToolKit-2.9.4.dist-info → micrOSDevToolKit-2.9.6.dist-info}/LICENSE +0 -0
- {micrOSDevToolKit-2.9.4.dist-info → micrOSDevToolKit-2.9.6.dist-info}/WHEEL +0 -0
- {micrOSDevToolKit-2.9.4.dist-info → micrOSDevToolKit-2.9.6.dist-info}/top_level.txt +0 -0
toolkit/simulator_lib/machine.py
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"devfid": "simulator",
|
|
3
3
|
"appwd": "ADmin123",
|
|
4
4
|
"webui": true,
|
|
5
|
-
"boothook": "dashboard_be load; neopixel load; #
|
|
5
|
+
"boothook": "dashboard_be load; neopixel load; #telegram receiver_loop &2000",
|
|
6
6
|
"aioqueue": 4,
|
|
7
7
|
"telegram": "6185435843:AAH71wEyoOil8bRKecQHp4zazTQ_MmE7bvE"}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import ssl
|
|
3
|
+
|
|
4
|
+
ssl_context = ssl.create_default_context()
|
|
5
|
+
ssl_context.check_hostname = False # Disable hostname check
|
|
6
|
+
ssl_context.verify_mode = ssl.CERT_NONE # Disable certificate verification
|
|
2
7
|
|
|
3
8
|
|
|
4
9
|
def open_connection(host, port, ssl=False):
|
|
5
|
-
return asyncio.open_connection(host, port, ssl=ssl)
|
|
10
|
+
#return asyncio.open_connection(host, port, ssl=ssl)
|
|
11
|
+
return asyncio.open_connection(host, port, ssl=ssl_context if ssl else None)
|
|
6
12
|
|
|
7
13
|
|
|
8
14
|
class Lock(asyncio.Lock):
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import stat as py_fs_stat
|
|
3
|
+
|
|
4
|
+
# https://docs.micropython.org/en/v1.9.2/pyboard/library/uos.html
|
|
5
|
+
# https://docs.micropython.org/en/v1.18/library/os.html
|
|
6
|
+
|
|
7
|
+
MOCK_SIM = False
|
|
8
|
+
|
|
9
|
+
def listdir(path=None):
|
|
10
|
+
if path is None:
|
|
11
|
+
return os.listdir()
|
|
12
|
+
path = __mock_sim_dir(path)
|
|
13
|
+
print(f"[uos.SIM] listdir: {path}")
|
|
14
|
+
return os.listdir(path)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def getcwd():
|
|
18
|
+
_cwd = os.getcwd()
|
|
19
|
+
if MOCK_SIM:
|
|
20
|
+
cwd = f"{_cwd}/../workspace/simulator/"
|
|
21
|
+
print(f"MOCK PATH: {cwd}")
|
|
22
|
+
elif "workspace/simulator" not in _cwd:
|
|
23
|
+
cwd = f"{_cwd}/toolkit/workspace/simulator/"
|
|
24
|
+
print(f"[uos.SIM] MOCK PATH: {_cwd} -> {cwd}")
|
|
25
|
+
else:
|
|
26
|
+
cwd = _cwd
|
|
27
|
+
return cwd
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def __mock_sim_dir(path):
|
|
31
|
+
"""
|
|
32
|
+
micropython sim hack
|
|
33
|
+
"""
|
|
34
|
+
if MOCK_SIM:
|
|
35
|
+
cwd = getcwd()
|
|
36
|
+
path = f"{cwd}{path}"
|
|
37
|
+
print(f"[!!!] [uos.SIM] CWD PATH HACK: {path}")
|
|
38
|
+
elif "workspace/simulator" not in path:
|
|
39
|
+
path = f"{getcwd()}{path}"
|
|
40
|
+
return path
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def ilistdir(path):
|
|
44
|
+
buffer = []
|
|
45
|
+
for filename in listdir(path):
|
|
46
|
+
_name, _type, _inode = filename, stat(f"{path}/{filename}")[0], 0
|
|
47
|
+
print(f"[uos.SIM] ilistdir {path}: ({_name}, {_type:#x}, {_inode}")
|
|
48
|
+
buffer.append((_name, _type, _inode))
|
|
49
|
+
return tuple(buffer)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def mkdir(path):
|
|
53
|
+
print(f"[uos.SIM] mkdir: {path}")
|
|
54
|
+
return os.mkdir(path)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def remove(path):
|
|
58
|
+
path = __mock_sim_dir(path)
|
|
59
|
+
print(f"[uos.SIM] remove: {path}")
|
|
60
|
+
if "simulator" in path and path.replace('/', '').endswith('simulator'):
|
|
61
|
+
print(f"\t[uos.SIM] rmdir: Invalid path! {path}")
|
|
62
|
+
return False
|
|
63
|
+
return os.remove(path)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def rename(old_path, new_path):
|
|
67
|
+
old_path, new_path = __mock_sim_dir(old_path), __mock_sim_dir(new_path)
|
|
68
|
+
print(f"[uos.SIM] rename: {old_path} -> {new_path}")
|
|
69
|
+
os.rename(old_path, new_path)
|
|
70
|
+
|
|
71
|
+
def _stat_eval(stat_result):
|
|
72
|
+
"""
|
|
73
|
+
micropython converter
|
|
74
|
+
"""
|
|
75
|
+
micropython_file_identifier = {'dir': 0x4000, 'file': 0x8000}
|
|
76
|
+
# Check if it's a file
|
|
77
|
+
if py_fs_stat.S_ISREG(stat_result.st_mode):
|
|
78
|
+
# FILE
|
|
79
|
+
return (micropython_file_identifier['file'],)
|
|
80
|
+
if py_fs_stat.S_ISDIR(stat_result.st_mode):
|
|
81
|
+
# DIRECTORY
|
|
82
|
+
return (micropython_file_identifier['dir'],)
|
|
83
|
+
return (0x0,)
|
|
84
|
+
|
|
85
|
+
def stat(path):
|
|
86
|
+
path = __mock_sim_dir(path)
|
|
87
|
+
stat_result = os.stat(path)
|
|
88
|
+
micropython_stat_result = _stat_eval(stat_result)
|
|
89
|
+
path_type = 'dir' if micropython_stat_result[0] & 0x4000 else 'file'
|
|
90
|
+
print(f"[uos.SIM] stat: {path} {path_type}({micropython_stat_result[0]:#x})")
|
|
91
|
+
return micropython_stat_result
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def rmdir(path):
|
|
95
|
+
print(f"[uos.SIM] rmdir: {path}")
|
|
96
|
+
if "simulator" in path and path.replace('/', '').endswith('simulator'):
|
|
97
|
+
print(f"\t[uos.SIM] rmdir: Invalid path! {path}")
|
|
98
|
+
return False
|
|
99
|
+
return os.rmdir(path)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def statvfs(path=None):
|
|
103
|
+
if path is None:
|
|
104
|
+
return os.statvfs(__mock_sim_dir(path))
|
|
105
|
+
return os.statvfs(path)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def uname():
|
|
109
|
+
return os.uname()
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def sync():
|
|
113
|
+
print("[uos.SIM] sync - dummy")
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def urandom(n):
|
|
117
|
+
print(f"[uos.SIM] sync {n}")
|
|
118
|
+
return os.urandom(n)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def dupterm(stream_object):
|
|
122
|
+
print("[uos.SIM] dupterm - dummy")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def mount(*args, **kwargs):
|
|
126
|
+
print("[uos.SIM] mount - dummy")
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def umount(*args, **kwargs):
|
|
130
|
+
print("[uos.SIM] unmount - dummy")
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
if __name__ == "__main__":
|
|
134
|
+
MOCK_SIM = True
|
|
135
|
+
print(f"SIM root (mock: {MOCK_SIM}): {__mock_sim_dir('/')}\ngetcwd: {getcwd()}")
|
|
136
|
+
print(listdir("/"))
|
|
137
|
+
print(stat('/'))
|
|
138
|
+
print(ilistdir('/'))
|
toolkit/socketClient.py
CHANGED
|
@@ -341,7 +341,7 @@ class SocketDictClient:
|
|
|
341
341
|
#########################################################
|
|
342
342
|
|
|
343
343
|
|
|
344
|
-
def main(args, host='127.0.0.1', port=9008, timeout=
|
|
344
|
+
def main(args, host='127.0.0.1', port=9008, timeout=5, pwd=None, verbose=False):
|
|
345
345
|
""" main connection wrapper function """
|
|
346
346
|
answer_msg = None
|
|
347
347
|
|
|
@@ -426,7 +426,7 @@ def socket_commandline_args(arg_list):
|
|
|
426
426
|
return ' <a> '.join(command_buffer), return_action_dict
|
|
427
427
|
|
|
428
428
|
|
|
429
|
-
def run(arg_list=[], timeout=
|
|
429
|
+
def run(arg_list=[], timeout=10):
|
|
430
430
|
""" Run from code
|
|
431
431
|
- Handles extra command line arguments
|
|
432
432
|
"""
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
from uos import listdir, remove, stat
|
|
2
|
+
from sys import modules
|
|
3
|
+
from Common import socket_stream
|
|
4
|
+
|
|
5
|
+
WEB_EXT = ('html', 'js', 'css')
|
|
6
|
+
DATA_TYPES = ('log', 'pds', 'dat')
|
|
7
|
+
|
|
8
|
+
def _is_app_resource(path='/'):
|
|
9
|
+
if stat(path)[0] & 0x4000: # Dir check
|
|
10
|
+
return True, 'd'
|
|
11
|
+
file_name = path.split("/")[-1]
|
|
12
|
+
if file_name.startswith('LM_') or file_name.split('.')[-1] in WEB_EXT + DATA_TYPES:
|
|
13
|
+
return True, 'f'
|
|
14
|
+
return False, '?'
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
#############################################
|
|
18
|
+
# Safe file system handler functions #
|
|
19
|
+
#############################################
|
|
20
|
+
|
|
21
|
+
def ls(path="/", content='*', raw=False):
|
|
22
|
+
"""
|
|
23
|
+
Linux like ls command - list app resources and app folders
|
|
24
|
+
:param path: path to list, default: /
|
|
25
|
+
:param content: content type, default all, f-file, d-dir can be selected
|
|
26
|
+
:param raw: keep raw output [(is_app, type), ...]
|
|
27
|
+
"""
|
|
28
|
+
path = path if path.endswith('/') else f"{path}/"
|
|
29
|
+
items = []
|
|
30
|
+
for item in listdir(path):
|
|
31
|
+
is_app, item_type = _is_app_resource(path + item)
|
|
32
|
+
if is_app and (content == "*" or item_type == content):
|
|
33
|
+
items.append((item_type, item))
|
|
34
|
+
if raw:
|
|
35
|
+
return items
|
|
36
|
+
formatted_output = ""
|
|
37
|
+
i = 0
|
|
38
|
+
for f in items:
|
|
39
|
+
i += 1
|
|
40
|
+
spacer = " " * (4 - len(str(i)))
|
|
41
|
+
formatted_output += f"{i}{spacer}{f[0]} {f[1]}\n"
|
|
42
|
+
return formatted_output
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def rm(path):
|
|
46
|
+
"""
|
|
47
|
+
Linux like rm command - delete app resources and folders
|
|
48
|
+
:param path: app resource name/path, ex.: LM_robustness.py
|
|
49
|
+
"""
|
|
50
|
+
if 'pacman.' in path or 'system.' in path or "/" == path.strip():
|
|
51
|
+
return f'Load module {path} is protected, skip delete.'
|
|
52
|
+
is_app, item_type = _is_app_resource(path)
|
|
53
|
+
if is_app:
|
|
54
|
+
remove(path)
|
|
55
|
+
return f"Remove: {path} {'dir' if item_type == 'd' else 'file'}"
|
|
56
|
+
return f"Invalid path {path}"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def dirtree(path="/", raw=False):
|
|
60
|
+
"""Return only directories from a given path."""
|
|
61
|
+
path = path if path.endswith('/') else f"{path}/"
|
|
62
|
+
folders = [f"{path}/{item}" for item in listdir(path) if _is_app_resource(f"{path}{item}")[1] == 'd']
|
|
63
|
+
folder_contents = {folder:listdir(folder) for folder in folders}
|
|
64
|
+
if raw:
|
|
65
|
+
return folder_contents
|
|
66
|
+
formatted_output = ""
|
|
67
|
+
for k, v in folder_contents.items():
|
|
68
|
+
formatted_output += f"{k}\n"
|
|
69
|
+
for val in v:
|
|
70
|
+
formatted_output += f"\t{val}\n"
|
|
71
|
+
return formatted_output
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def download(url=None, package=None):
|
|
75
|
+
"""
|
|
76
|
+
[BETA] Load Module downloader with mip
|
|
77
|
+
:param url: github url path, ex. BxNxM/micrOS/master/toolkit/workspace/precompiled/LM_robustness.py
|
|
78
|
+
:param package: mip package name or raw url (hack)
|
|
79
|
+
"""
|
|
80
|
+
if url is None and package is None:
|
|
81
|
+
return "Nothing to download, url=None package=None"
|
|
82
|
+
if package is None:
|
|
83
|
+
base_url = "https://raw.githubusercontent.com/"
|
|
84
|
+
file_name = url.split("/")[-1]
|
|
85
|
+
if not(file_name.endswith("py") and file_name.startswith("LM_")):
|
|
86
|
+
return "Invalid file name in url ending, hint: /LM_*.mpy or /LM_*.py"
|
|
87
|
+
# Convert GitHub URL to raw content URL
|
|
88
|
+
if "github.com" in url and "blob" in url:
|
|
89
|
+
url = url.replace("https://github.com/", base_url).replace("/blob", "")
|
|
90
|
+
else:
|
|
91
|
+
url = f"{base_url}{url}"
|
|
92
|
+
else:
|
|
93
|
+
url = package
|
|
94
|
+
from mip import install
|
|
95
|
+
verdict = ""
|
|
96
|
+
try:
|
|
97
|
+
verdict += f"Install {url}\n"
|
|
98
|
+
install(url)
|
|
99
|
+
verdict += "\n|- Done"
|
|
100
|
+
except Exception as e:
|
|
101
|
+
verdict += f"|- Cannot install: {url}\n{e}"
|
|
102
|
+
return verdict
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def del_duplicates():
|
|
106
|
+
"""
|
|
107
|
+
Load module package manager (Not just load modules)
|
|
108
|
+
- delete duplicated .mpy and .py resources, keep .mpy resource!
|
|
109
|
+
"""
|
|
110
|
+
msg_buf = []
|
|
111
|
+
py = list((res.split('.')[0] for res in listdir() if res.endswith('.py'))) # Normally smaller list
|
|
112
|
+
mpy = (res.split('.')[0] for res in listdir() if res.endswith('.mpy'))
|
|
113
|
+
for m in mpy:
|
|
114
|
+
# Iterate over mpy resources
|
|
115
|
+
state = True
|
|
116
|
+
if m in py and m != 'main':
|
|
117
|
+
to_delete = f'{m}.py'
|
|
118
|
+
try:
|
|
119
|
+
remove(to_delete)
|
|
120
|
+
except:
|
|
121
|
+
state = False
|
|
122
|
+
msg_buf.append(f' Delete {to_delete} {state}')
|
|
123
|
+
return '\n'.join(msg_buf) if len(msg_buf) > 0 else 'Nothing to delete.'
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def moduls(unload=None):
|
|
127
|
+
"""
|
|
128
|
+
List / unload loaded upython Load Modules
|
|
129
|
+
:param unload: module name to unload
|
|
130
|
+
:param unload: None - list active modules
|
|
131
|
+
:return str: verdict
|
|
132
|
+
"""
|
|
133
|
+
if unload is None:
|
|
134
|
+
return list(modules.keys())
|
|
135
|
+
if unload in modules.keys():
|
|
136
|
+
del modules[unload]
|
|
137
|
+
return f"Module unload {unload} done."
|
|
138
|
+
return f"Module unload {unload} failed."
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
@socket_stream
|
|
142
|
+
def cachedump(delpds=None, msgobj=None):
|
|
143
|
+
"""
|
|
144
|
+
Cache system persistent data storage files (.pds)
|
|
145
|
+
:param delpds: cache name to delete
|
|
146
|
+
"""
|
|
147
|
+
if delpds is None:
|
|
148
|
+
# List pds files aka application cache
|
|
149
|
+
msg_buf = []
|
|
150
|
+
for pds in (_pds for _pds in listdir() if _pds.endswith('.pds')):
|
|
151
|
+
with open(pds, 'r') as f:
|
|
152
|
+
if msgobj is None:
|
|
153
|
+
msg_buf.append(f'{pds}: {f.read()}')
|
|
154
|
+
else:
|
|
155
|
+
msgobj(f'{pds}: {f.read()}')
|
|
156
|
+
return msg_buf if len(msg_buf) > 0 else ''
|
|
157
|
+
# Remove given pds file
|
|
158
|
+
try:
|
|
159
|
+
remove(f'{delpds}.pds')
|
|
160
|
+
return f'{delpds}.pds delete done.'
|
|
161
|
+
except:
|
|
162
|
+
return f'{delpds}.pds not exists'
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def dat_dump():
|
|
166
|
+
"""
|
|
167
|
+
Generic .dat file dump
|
|
168
|
+
- logged data from LMs, sensor datat, etc...
|
|
169
|
+
"""
|
|
170
|
+
logs_dir = "/logs/"
|
|
171
|
+
dats = (f for f in listdir(logs_dir) if f.endswith('.dat'))
|
|
172
|
+
out = {}
|
|
173
|
+
for dat in dats:
|
|
174
|
+
with open(f"{logs_dir}{dat}", 'r') as f:
|
|
175
|
+
out[dat] = f.read()
|
|
176
|
+
return out
|
|
177
|
+
|
|
178
|
+
#############################################
|
|
179
|
+
# Legacy features #
|
|
180
|
+
#############################################
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
@socket_stream
|
|
184
|
+
def listmods(msgobj=None):
|
|
185
|
+
"""
|
|
186
|
+
Load module package manager
|
|
187
|
+
- list all load modules
|
|
188
|
+
"""
|
|
189
|
+
# Dump available LMs
|
|
190
|
+
msg_buf = []
|
|
191
|
+
for k in (res.replace('LM_', '') for res in listdir("/")
|
|
192
|
+
if res.startswith('LM_') or res.split('.')[-1] in WEB_EXT):
|
|
193
|
+
if msgobj is None:
|
|
194
|
+
msg_buf.append(f' {k}')
|
|
195
|
+
else:
|
|
196
|
+
msgobj(f' {k}')
|
|
197
|
+
return msg_buf if len(msg_buf) > 0 else ''
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def delmod(mod=None):
|
|
201
|
+
"""
|
|
202
|
+
Module package manager
|
|
203
|
+
:param mod:
|
|
204
|
+
Delete Load Module with full name: module.py or module.mpy
|
|
205
|
+
OR delete any web resource: *.js, *.css, *.html
|
|
206
|
+
"""
|
|
207
|
+
if mod is not None and (mod.endswith('py') or mod.split('.')[-1] in WEB_EXT):
|
|
208
|
+
# LM exception list - system and pacman cannot be deleted
|
|
209
|
+
if 'pacman.' in mod or 'system.' in mod:
|
|
210
|
+
return f'Load module {mod} is in use, skip delete.'
|
|
211
|
+
try:
|
|
212
|
+
to_remove = mod if mod.split('.')[-1] in WEB_EXT else f'LM_{mod}'
|
|
213
|
+
remove(to_remove)
|
|
214
|
+
return f'Delete module: {mod}'
|
|
215
|
+
except Exception as e:
|
|
216
|
+
return f'Cannot delete: {mod}: {e}'
|
|
217
|
+
return f'Invalid value: {mod}'
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
@socket_stream
|
|
221
|
+
def micros_checksum(msgobj=None):
|
|
222
|
+
from hashlib import sha1
|
|
223
|
+
from binascii import hexlify
|
|
224
|
+
from Config import cfgget
|
|
225
|
+
|
|
226
|
+
for f_name in (_pds for _pds in listdir() if _pds.endswith('py')):
|
|
227
|
+
with open(f_name, 'rb') as f:
|
|
228
|
+
cs = hexlify(sha1(f.read()).digest()).decode('utf-8')
|
|
229
|
+
msgobj(f"{cs} {f_name}")
|
|
230
|
+
# GC collect?
|
|
231
|
+
return f"micrOS version: {cfgget('version')}"
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def help(widgets=False):
|
|
235
|
+
"""
|
|
236
|
+
[i] micrOS LM naming convention - built-in help message
|
|
237
|
+
:return tuple:
|
|
238
|
+
(widgets=False) list of functions implemented by this application
|
|
239
|
+
(widgets=True) list of widget json for UI generation
|
|
240
|
+
"""
|
|
241
|
+
return ('listmods', 'delmod mod=<module>.py/.mpy or .js/.html/.css', 'del_duplicates',
|
|
242
|
+
'moduls unload="LM_rgb/None"',
|
|
243
|
+
'cachedump delpds="rgb/None"',
|
|
244
|
+
'dat_dump',
|
|
245
|
+
'download url="BxNxM/micrOS/master/toolkit/workspace/precompiled/LM_robustness.py"',
|
|
246
|
+
'micros_checksum',
|
|
247
|
+
'ls path="/" content="*/f/d"',
|
|
248
|
+
'rm <path>', 'dirtree path="/"')
|
|
Binary file
|
|
@@ -9,8 +9,8 @@ def raise_error(msgobj=None):
|
|
|
9
9
|
"""
|
|
10
10
|
if msgobj is not None:
|
|
11
11
|
msgobj("Raise test exception")
|
|
12
|
-
syslog('Robustness TeSt ErRoR')
|
|
13
|
-
raise Exception("Test exception")
|
|
12
|
+
state = syslog('Robustness TeSt ErRoR')
|
|
13
|
+
raise Exception(f"Test exception: {'OK' if state else 'NOK'}")
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
@socket_stream
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
1.
|
|
1
|
+
1.24.1
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"
|
|
1
|
+
{"irq2": false, "irq2_cbf": "n/a", "irq3_cbf": "n/a", "timirq": true, "irq4": false, "auth": false, "irq4_cbf": "n/a", "devip": "10.0.1.129", "soctout": 100, "appwd": "ADmin123", "timirqcbf": "rgb run_transition", "timirqseq": 800, "hwuid": "micr8caab594e9d4OS", "staessid": "T-3588F3;elektroncsakpozitivan_2G", "irq1_cbf": "rgb toggle", "cron": true, "irq4_trig": "n/a", "nwmd": "STA", "boothook": "rgb load_n_init", "version": "1.41.0-0", "irq_prell_ms": 300, "crontasks": "sunrise!rgb set_transition 400 0 0 3600;sunset!rgb run_transition 143 330 0 300;*:9:0:0!rgb set_transition 0 300 300 1800;*:12:0:0!rgb toggle False;*:20:0:0!rgb set_transition 600 211 2 3600;*:21:2:0!rgb rgb 100 30 0;*:23:0:0!rgb toggle False", "aioqueue": 3, "utc": 60, "boostmd": true, "irq1_trig": "n/a", "guimeta": "...", "socport": 9008, "webui": true, "cstmpmap": "n/a", "telegram": "n/a", "irq3_trig": "n/a", "dbg": true, "irq2_trig": "n/a", "irq3": false, "devfid": "ujelet", "stapwd": "jBRU7SJmreae8n5p;BNM3,1415", "irq1": false}
|
|
Binary file
|
|
Binary file
|
micrOS/source/LM_lmpacman.py
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
from os import listdir, remove
|
|
2
|
-
from sys import modules
|
|
3
|
-
from Common import socket_stream
|
|
4
|
-
|
|
5
|
-
WEB_EXT = ('html', 'js', 'css')
|
|
6
|
-
|
|
7
|
-
@socket_stream
|
|
8
|
-
def listmods(msgobj=None):
|
|
9
|
-
"""
|
|
10
|
-
Load module package manager
|
|
11
|
-
- list all load modules
|
|
12
|
-
"""
|
|
13
|
-
# Dump available LMs
|
|
14
|
-
msg_buf = []
|
|
15
|
-
for k in (res.replace('LM_', '') for res in listdir()
|
|
16
|
-
if res.startswith('LM_') or res.split('.')[-1] in WEB_EXT):
|
|
17
|
-
if msgobj is None:
|
|
18
|
-
msg_buf.append(f' {k}')
|
|
19
|
-
else:
|
|
20
|
-
msgobj(f' {k}')
|
|
21
|
-
return msg_buf if len(msg_buf) > 0 else ''
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def delmod(mod=None):
|
|
25
|
-
"""
|
|
26
|
-
Module package manager
|
|
27
|
-
:param mod:
|
|
28
|
-
Delete Load Module with full name: module.py or module.mpy
|
|
29
|
-
OR delete any web resource: *.js, *.css, *.html
|
|
30
|
-
"""
|
|
31
|
-
if mod is not None and (mod.endswith('py') or mod.split('.')[-1] in WEB_EXT):
|
|
32
|
-
# LM exception list - system and lmpacman cannot be deleted
|
|
33
|
-
if 'lmpacman.' in mod or 'system.' in mod:
|
|
34
|
-
return f'Load module {mod} is in use, skip delete.'
|
|
35
|
-
try:
|
|
36
|
-
to_remove = mod if mod.split('.')[-1] in WEB_EXT else f'LM_{mod}'
|
|
37
|
-
remove(to_remove)
|
|
38
|
-
return f'Delete module: {mod}'
|
|
39
|
-
except Exception as e:
|
|
40
|
-
return f'Cannot delete: {mod}: {e}'
|
|
41
|
-
return f'Invalid value: {mod}'
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def del_duplicates():
|
|
45
|
-
"""
|
|
46
|
-
Load module package manager (Not just load modules)
|
|
47
|
-
- delete duplicated .mpy and .py resources, keep .mpy resource!
|
|
48
|
-
"""
|
|
49
|
-
msg_buf = []
|
|
50
|
-
py = list((res.split('.')[0] for res in listdir() if res.endswith('.py'))) # Normally smaller list
|
|
51
|
-
mpy = (res.split('.')[0] for res in listdir() if res.endswith('.mpy'))
|
|
52
|
-
for m in mpy:
|
|
53
|
-
# Iterate over mpy resources
|
|
54
|
-
state = True
|
|
55
|
-
if m in py and m != 'main':
|
|
56
|
-
to_delete = f'{m}.py'
|
|
57
|
-
try:
|
|
58
|
-
remove(to_delete)
|
|
59
|
-
except:
|
|
60
|
-
state = False
|
|
61
|
-
msg_buf.append(f' Delete {to_delete} {state}')
|
|
62
|
-
return '\n'.join(msg_buf) if len(msg_buf) > 0 else 'Nothing to delete.'
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def module(unload=None):
|
|
66
|
-
"""
|
|
67
|
-
List / unload loaded upython Load Modules
|
|
68
|
-
:param unload: module name to unload
|
|
69
|
-
:param unload: None - list active modules
|
|
70
|
-
:return str: verdict
|
|
71
|
-
"""
|
|
72
|
-
if unload is None:
|
|
73
|
-
return list(modules.keys())
|
|
74
|
-
if unload in modules.keys():
|
|
75
|
-
del modules[unload]
|
|
76
|
-
return f"Module unload {unload} done."
|
|
77
|
-
return f"Module unload {unload} failed."
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
@socket_stream
|
|
81
|
-
def cachedump(cdel=None, msgobj=None):
|
|
82
|
-
"""
|
|
83
|
-
Cache system persistent data storage files (.pds)
|
|
84
|
-
"""
|
|
85
|
-
if cdel is None:
|
|
86
|
-
# List pds files aka application cache
|
|
87
|
-
msg_buf = []
|
|
88
|
-
for pds in (_pds for _pds in listdir() if _pds.endswith('.pds')):
|
|
89
|
-
with open(pds, 'r') as f:
|
|
90
|
-
if msgobj is None:
|
|
91
|
-
msg_buf.append(f'{pds}: {f.read()}')
|
|
92
|
-
else:
|
|
93
|
-
msgobj(f'{pds}: {f.read()}')
|
|
94
|
-
return msg_buf if len(msg_buf) > 0 else ''
|
|
95
|
-
# Remove given pds file
|
|
96
|
-
try:
|
|
97
|
-
remove(f'{cdel}.pds')
|
|
98
|
-
return f'{cdel}.pds delete done.'
|
|
99
|
-
except:
|
|
100
|
-
return f'{cdel}.pds not exists'
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
@socket_stream
|
|
104
|
-
def micros_checksum(msgobj=None):
|
|
105
|
-
from hashlib import sha1
|
|
106
|
-
from binascii import hexlify
|
|
107
|
-
from Config import cfgget
|
|
108
|
-
|
|
109
|
-
for f_name in (_pds for _pds in listdir() if _pds.endswith('py')):
|
|
110
|
-
with open(f_name, 'rb') as f:
|
|
111
|
-
cs = hexlify(sha1(f.read()).digest()).decode('utf-8')
|
|
112
|
-
msgobj(f"{cs} {f_name}")
|
|
113
|
-
# GC collect?
|
|
114
|
-
return f"micrOS version: {cfgget('version')}"
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
def help(widgets=False):
|
|
118
|
-
"""
|
|
119
|
-
[i] micrOS LM naming convention - built-in help message
|
|
120
|
-
:return tuple:
|
|
121
|
-
(widgets=False) list of functions implemented by this application
|
|
122
|
-
(widgets=True) list of widget json for UI generation
|
|
123
|
-
"""
|
|
124
|
-
return 'listmods', 'delmod mod=<module>.py/.mpy or .js/.html/.css', 'del_duplicates',\
|
|
125
|
-
'module unload="LM_rgb/None"',\
|
|
126
|
-
'cachedump cdel="rgb.pds/None"', 'micros_checksum'
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|