micrOSDevToolKit 2.8.6__py3-none-any.whl → 2.9.0__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.
- env/driver_cp210x/.DS_Store +0 -0
- env/driver_cp210x/macOS_VCP_Driver/SiLabsUSBDriverDisk.dmg +0 -0
- env/driver_cp210x/macOS_VCP_Driver/macOS_VCP_Driver_Release_Notes.txt +0 -0
- micrOS/micropython/esp32-20241129-v1.24.1.bin +0 -0
- micrOS/micropython/esp32s3-20241129-v1.24.1.bin +0 -0
- micrOS/micropython/esp32s3_spiram_oct-20241129-v1.24.1.bin +0 -0
- micrOS/micropython/rpi-pico-w-20241129-v1.24.1.uf2 +0 -0
- micrOS/micropython/tinypico-20241129-v1.24.1.bin +0 -0
- micrOS/release_info/micrOS_ReleaseInfo/system_analysis_sum.json +40 -40
- micrOS/source/Common.py +12 -17
- micrOS/source/Config.py +20 -1
- micrOS/source/Hooks.py +25 -15
- micrOS/source/LM_buzzer.py +16 -9
- micrOS/source/LM_cct.py +2 -3
- micrOS/source/LM_dimmer.py +1 -2
- micrOS/source/LM_distance.py +2 -4
- micrOS/source/LM_genIO.py +1 -1
- micrOS/source/LM_i2s_mic.py +4 -4
- micrOS/source/LM_keychain.py +2 -3
- micrOS/source/LM_light_sensor.py +1 -2
- micrOS/source/LM_neoeffects.py +22 -7
- micrOS/source/LM_neopixel.py +2 -3
- micrOS/source/LM_oledui.py +3 -4
- micrOS/source/LM_pet_feeder.py +3 -4
- micrOS/source/LM_ph_sensor.py +2 -2
- micrOS/source/LM_presence.py +2 -3
- micrOS/source/LM_rest.py +52 -9
- micrOS/source/LM_rgb.py +1 -2
- micrOS/source/LM_roboarm.py +1 -2
- micrOS/source/LM_sound_event.py +2 -3
- micrOS/source/LM_system.py +14 -3
- micrOS/source/LM_telegram.py +226 -15
- micrOS/source/Logger.py +6 -0
- micrOS/source/Notify.py +46 -218
- micrOS/source/Scheduler.py +7 -4
- micrOS/source/Shell.py +2 -2
- micrOS/source/Tasks.py +106 -98
- micrOS/source/Types.py +6 -2
- micrOS/source/Web.py +32 -8
- micrOS/source/dashboard.html +4 -4
- micrOS/source/micrOS.py +5 -10
- micrOS/source/micrOSloader.py +16 -18
- micrOS/source/uapi.js +5 -6
- micrOS/source/urequests.py +171 -85
- {micrOSDevToolKit-2.8.6.dist-info → micrOSDevToolKit-2.9.0.dist-info}/METADATA +2 -2
- {micrOSDevToolKit-2.8.6.dist-info → micrOSDevToolKit-2.9.0.dist-info}/RECORD +95 -97
- toolkit/DevEnvUSB.py +1 -6
- toolkit/MicrOSDevEnv.py +8 -5
- toolkit/simulator_lib/__pycache__/simulator.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/uasyncio.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/usocket.cpython-312.pyc +0 -0
- toolkit/simulator_lib/simulator.py +14 -0
- toolkit/simulator_lib/uasyncio.py +2 -2
- toolkit/simulator_lib/usocket.py +5 -1
- toolkit/workspace/precompiled/Common.mpy +0 -0
- toolkit/workspace/precompiled/Config.mpy +0 -0
- toolkit/workspace/precompiled/Hooks.mpy +0 -0
- toolkit/workspace/precompiled/LM_buzzer.mpy +0 -0
- toolkit/workspace/precompiled/LM_cct.mpy +0 -0
- toolkit/workspace/precompiled/LM_dimmer.mpy +0 -0
- toolkit/workspace/precompiled/LM_distance.mpy +0 -0
- toolkit/workspace/precompiled/LM_genIO.mpy +0 -0
- toolkit/workspace/precompiled/LM_i2s_mic.mpy +0 -0
- toolkit/workspace/precompiled/LM_keychain.mpy +0 -0
- toolkit/workspace/precompiled/LM_light_sensor.mpy +0 -0
- toolkit/workspace/precompiled/LM_neoeffects.mpy +0 -0
- toolkit/workspace/precompiled/LM_neopixel.mpy +0 -0
- toolkit/workspace/precompiled/LM_oledui.mpy +0 -0
- toolkit/workspace/precompiled/LM_pet_feeder.py +3 -4
- toolkit/workspace/precompiled/LM_ph_sensor.py +2 -2
- toolkit/workspace/precompiled/LM_presence.mpy +0 -0
- toolkit/workspace/precompiled/LM_rest.mpy +0 -0
- toolkit/workspace/precompiled/LM_rgb.mpy +0 -0
- toolkit/workspace/precompiled/LM_roboarm.mpy +0 -0
- toolkit/workspace/precompiled/LM_sound_event.mpy +0 -0
- 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/Scheduler.mpy +0 -0
- toolkit/workspace/precompiled/Shell.mpy +0 -0
- toolkit/workspace/precompiled/Tasks.mpy +0 -0
- toolkit/workspace/precompiled/Types.mpy +0 -0
- toolkit/workspace/precompiled/Web.mpy +0 -0
- toolkit/workspace/precompiled/dashboard.html +4 -4
- toolkit/workspace/precompiled/micrOS.mpy +0 -0
- toolkit/workspace/precompiled/micrOSloader.mpy +0 -0
- toolkit/workspace/precompiled/node_config.json +1 -1
- toolkit/workspace/precompiled/uapi.js +5 -6
- toolkit/workspace/precompiled/urequests.mpy +0 -0
- env/driver_cp210x/CH34XSER_MAC/CH34X_DRV_INSTALL_INSTRUCTIONS.pdf +0 -0
- env/driver_cp210x/CH34XSER_MAC/CH34xVCPDriver.pkg +0 -0
- micrOS/micropython/esp32-20231005-v1.21.0.bin +0 -0
- micrOS/micropython/esp32-GENERIC-20240602-v1.23.0.bin +0 -0
- micrOS/micropython/rpi-pico-w-20240602-v1.23.0.uf2 +0 -0
- micrOS/micropython/tinypico-20231005-v1.21.0.bin +0 -0
- micrOS/micropython/tinypico_usbc-UM-20240105-v1.22.1.bin +0 -0
- /micrOS/micropython/{esp32c3-GENERIC-20240222-v1.22.2.bin → esp32c3-20240222-v1.22.2.bin} +0 -0
- /micrOS/micropython/{esp32s2-GENERIC-20240602-v1.23.0.bin → esp32s2-20240602-v1.23.0.bin} +0 -0
- /micrOS/micropython/{esp32s3-GENERIC-20240105-v1.22.1.bin → esp32s3-20240105-v1.22.1.bin} +0 -0
- {micrOSDevToolKit-2.8.6.data → micrOSDevToolKit-2.9.0.data}/scripts/devToolKit.py +0 -0
- {micrOSDevToolKit-2.8.6.dist-info → micrOSDevToolKit-2.9.0.dist-info}/LICENSE +0 -0
- {micrOSDevToolKit-2.8.6.dist-info → micrOSDevToolKit-2.9.0.dist-info}/WHEEL +0 -0
- {micrOSDevToolKit-2.8.6.dist-info → micrOSDevToolKit-2.9.0.dist-info}/top_level.txt +0 -0
micrOS/source/urequests.py
CHANGED
|
@@ -5,102 +5,73 @@ except ImportError:
|
|
|
5
5
|
from ssl import wrap_socket # From micropython 1.23...
|
|
6
6
|
from json import loads, dumps
|
|
7
7
|
from Debug import errlog_add
|
|
8
|
+
import uasyncio as asyncio
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
ADDR_CACHE = {}
|
|
11
12
|
|
|
13
|
+
#############################################
|
|
14
|
+
# micropython request - helper functions #
|
|
15
|
+
#############################################
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
|
|
18
|
+
def _host_to_addr(host, port, force=False):
|
|
14
19
|
"""
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
:param url: URL for REST API
|
|
18
|
-
:param data: string body (handle bare string as data for POST method)
|
|
19
|
-
:param json: json body (handle json as data for POST method)
|
|
20
|
-
:param headers: define headers
|
|
21
|
-
:param sock_size: socket buffer size (chuck size), default 256 byte (micropython defualt)
|
|
22
|
-
:param jsonify: convert response body to json
|
|
20
|
+
Resolve host name to IP address
|
|
21
|
+
and cache host address to avoid slow getaddrinfo
|
|
23
22
|
"""
|
|
23
|
+
addr = ADDR_CACHE.get(host, None)
|
|
24
|
+
if addr is None or force:
|
|
25
|
+
addr = getaddrinfo(host, port)[0][-1]
|
|
26
|
+
ADDR_CACHE[host] = addr
|
|
27
|
+
return addr
|
|
24
28
|
|
|
25
|
-
#############################################
|
|
26
|
-
# micropython request - internal functions #
|
|
27
|
-
#############################################
|
|
28
|
-
def _chunked(_body):
|
|
29
|
-
decoded = bytearray()
|
|
30
|
-
while _body:
|
|
31
|
-
# Find the end of the chunk size line
|
|
32
|
-
line_end = _body.find(b"\r\n")
|
|
33
|
-
if line_end < 0:
|
|
34
|
-
break
|
|
35
29
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
30
|
+
def _chunked(_body):
|
|
31
|
+
decoded = bytearray()
|
|
32
|
+
while _body:
|
|
33
|
+
# Find the end of the chunk size line
|
|
34
|
+
line_end = _body.find(b"\r\n")
|
|
35
|
+
if line_end < 0:
|
|
36
|
+
break
|
|
42
37
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
# Extract the chunk size and convert to int
|
|
39
|
+
chunk_size_str = _body[:line_end]
|
|
40
|
+
try:
|
|
41
|
+
chunk_size = int(chunk_size_str, 16)
|
|
42
|
+
except ValueError as e:
|
|
43
|
+
chunk_size = 0
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
# Check chunk size
|
|
46
|
+
if chunk_size == 0:
|
|
47
|
+
break
|
|
50
48
|
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
# Add the chunk data to the decoded data
|
|
50
|
+
chunk_data = _body[line_end + 2: line_end + 2 + chunk_size]
|
|
51
|
+
decoded += chunk_data
|
|
53
52
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
_addr = ADDR_CACHE.get(host, None)
|
|
65
|
-
if _addr is None or force:
|
|
66
|
-
_addr = getaddrinfo(host, port)[0][-1]
|
|
67
|
-
ADDR_CACHE[host] = _addr
|
|
68
|
-
return _addr
|
|
69
|
-
|
|
70
|
-
#############################################
|
|
71
|
-
# micropython request main #
|
|
72
|
-
#############################################
|
|
73
|
-
|
|
74
|
-
# [_parse_url] Parse HTTP(S) URL
|
|
75
|
-
headers = {} if headers is None else headers
|
|
53
|
+
# Move to the next chunk
|
|
54
|
+
_body = _body[line_end + 4 + chunk_size:]
|
|
55
|
+
|
|
56
|
+
# Check for end of message marker again
|
|
57
|
+
if not _body.startswith(b"\r\n"):
|
|
58
|
+
break
|
|
59
|
+
return decoded
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _parse_url(url):
|
|
76
63
|
# PARSE URL -> proto (http/https), host, path + SET PORT
|
|
77
64
|
proto, _, host, path = url.split('/', 3)
|
|
78
|
-
|
|
79
65
|
port = 443 if proto == 'https:' else 80
|
|
80
66
|
# PARSE HOST - handle direct port number as input after :
|
|
81
67
|
if ':' in host:
|
|
82
68
|
host, port = host.split(':', 1)
|
|
83
69
|
port = int(port)
|
|
70
|
+
return host, port, proto, path
|
|
84
71
|
|
|
85
|
-
# [1] CONNECT - create socket object
|
|
86
|
-
sock = socket()
|
|
87
|
-
sock.settimeout(3)
|
|
88
|
-
# [1.1] CONNECT - resolve IP by host
|
|
89
|
-
addr = _host_to_addr()
|
|
90
|
-
# [1.2] CONNECT - if https handle ssl
|
|
91
|
-
try:
|
|
92
|
-
sock.connect(addr)
|
|
93
|
-
except Exception:
|
|
94
|
-
# Refresh host address & reconnect
|
|
95
|
-
addr = _host_to_addr(force=True)
|
|
96
|
-
sock.connect(addr)
|
|
97
|
-
|
|
98
|
-
try:
|
|
99
|
-
sock = wrap_socket(sock) if proto == 'https:' else sock
|
|
100
|
-
except Exception as e:
|
|
101
|
-
errlog_add(f'[ERR] https soc-wrap: {e}')
|
|
102
72
|
|
|
103
|
-
|
|
73
|
+
def _build_request(host, method, path, headers, data=None, json=None):
|
|
74
|
+
# Create request (body, headers)
|
|
104
75
|
body = None
|
|
105
76
|
if data:
|
|
106
77
|
body = data.encode('utf-8')
|
|
@@ -119,6 +90,60 @@ def request(method, url, data=None, json=None, headers=None, sock_size=256, json
|
|
|
119
90
|
http_request = '\r\n'.join(lines) + '\r\n\r\n'
|
|
120
91
|
if body:
|
|
121
92
|
http_request += body.decode('utf-8')
|
|
93
|
+
return http_request
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _parse_response(response):
|
|
97
|
+
# Parse response - get body
|
|
98
|
+
headers, body = response.split(b'\r\n\r\n', 1)
|
|
99
|
+
status_code = int(headers.split(b' ')[1])
|
|
100
|
+
headers = dict(h.split(b': ') for h in headers.split(b'\r\n')[1:])
|
|
101
|
+
if headers.get(b'Transfer-Encoding', b'') == b'chunked':
|
|
102
|
+
body = _chunked(body)
|
|
103
|
+
else:
|
|
104
|
+
body = body.decode('utf-8')
|
|
105
|
+
return status_code, body
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
#############################################
|
|
109
|
+
# micropython HTTP request #
|
|
110
|
+
#############################################
|
|
111
|
+
|
|
112
|
+
def request(method, url, data=None, json=None, headers=None, sock_size=256, jsonify=False):
|
|
113
|
+
"""
|
|
114
|
+
Micropython syncronous HTTP request function for REST API handling
|
|
115
|
+
:param method: GET/POST
|
|
116
|
+
:param url: URL for REST API
|
|
117
|
+
:param data: string body (handle bare string as data for POST method)
|
|
118
|
+
:param json: json body (handle json as data for POST method)
|
|
119
|
+
:param headers: define headers
|
|
120
|
+
:param sock_size: socket buffer size (chuck size), default 256 byte (micropython defualt)
|
|
121
|
+
:param jsonify: convert response body to json
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
# Parse HTTP(S) URL and headers
|
|
125
|
+
headers = {} if headers is None else headers
|
|
126
|
+
host, port, proto, path = _parse_url(url)
|
|
127
|
+
addr = _host_to_addr(host, port)
|
|
128
|
+
|
|
129
|
+
# [1] CONNECT - create socket object
|
|
130
|
+
sock = socket()
|
|
131
|
+
sock.settimeout(3)
|
|
132
|
+
# [1.1] CONNECT - if https handle ssl
|
|
133
|
+
try:
|
|
134
|
+
sock.connect(addr)
|
|
135
|
+
except Exception:
|
|
136
|
+
# Refresh host address & reconnect
|
|
137
|
+
addr = _host_to_addr(host, port, force=True)
|
|
138
|
+
sock.connect(addr)
|
|
139
|
+
|
|
140
|
+
try:
|
|
141
|
+
sock = wrap_socket(sock) if proto == 'https:' else sock
|
|
142
|
+
except Exception as e:
|
|
143
|
+
errlog_add(f'[ERR] https soc-wrap: {e}')
|
|
144
|
+
|
|
145
|
+
# [1] BUILD REQUEST
|
|
146
|
+
http_request = _build_request(host, method, path, headers, data, json)
|
|
122
147
|
|
|
123
148
|
# [2] SEND REQUEST
|
|
124
149
|
if proto == 'https:':
|
|
@@ -138,23 +163,68 @@ def request(method, url, data=None, json=None, headers=None, sock_size=256, json
|
|
|
138
163
|
response += data
|
|
139
164
|
sock.close()
|
|
140
165
|
|
|
141
|
-
# [
|
|
142
|
-
|
|
143
|
-
status_code = int(headers.split(b' ')[1])
|
|
144
|
-
headers = dict(h.split(b': ') for h in headers.split(b'\r\n')[1:])
|
|
145
|
-
if headers.get(b'Transfer-Encoding', b'') == b'chunked':
|
|
146
|
-
body = _chunked(body)
|
|
147
|
-
else:
|
|
148
|
-
body = body.decode('utf-8')
|
|
166
|
+
# [4] PARSE RESPONSE
|
|
167
|
+
status_code, body = _parse_response(response)
|
|
149
168
|
|
|
150
|
-
# Return status code,
|
|
151
|
-
return status_code, loads(body) if jsonify else body
|
|
169
|
+
# Return status code, body (text or json)
|
|
170
|
+
return status_code, loads(body) if jsonify and status_code == 200 else body
|
|
152
171
|
|
|
153
172
|
|
|
154
173
|
#############################################
|
|
155
|
-
#
|
|
174
|
+
# async micropython HTTP request #
|
|
156
175
|
#############################################
|
|
157
176
|
|
|
177
|
+
async def arequest(method, url, data=None, json=None, headers=None, sock_size=256, jsonify=False):
|
|
178
|
+
"""
|
|
179
|
+
Micropython asynchronous HTTP request function for REST API handling
|
|
180
|
+
:param method: GET/POST
|
|
181
|
+
:param url: URL for REST API
|
|
182
|
+
:param data: string body (handle bare string as data for POST method)
|
|
183
|
+
:param json: json body (handle json as data for POST method)
|
|
184
|
+
:param headers: define headers
|
|
185
|
+
:param sock_size: socket buffer size (chunk size), default 256 bytes (micropython default)
|
|
186
|
+
:param jsonify: convert response body to json
|
|
187
|
+
"""
|
|
188
|
+
headers = {} if headers is None else headers
|
|
189
|
+
host, port, proto, path = _parse_url(url)
|
|
190
|
+
addr = _host_to_addr(host, port)
|
|
191
|
+
reader, writer = None, None
|
|
192
|
+
|
|
193
|
+
try:
|
|
194
|
+
# Open a connection
|
|
195
|
+
reader, writer = await asyncio.open_connection(addr[0], port, ssl=(proto == 'https:'))
|
|
196
|
+
|
|
197
|
+
# Build the HTTP request
|
|
198
|
+
http_request = _build_request(host, method, path, headers, data, json)
|
|
199
|
+
|
|
200
|
+
# Send the request
|
|
201
|
+
writer.write(http_request.encode('utf-8'))
|
|
202
|
+
await writer.drain()
|
|
203
|
+
|
|
204
|
+
# Receive response
|
|
205
|
+
response = b''
|
|
206
|
+
while True:
|
|
207
|
+
chunk = await reader.read(sock_size)
|
|
208
|
+
if not chunk:
|
|
209
|
+
break
|
|
210
|
+
response += chunk
|
|
211
|
+
|
|
212
|
+
# Parse response
|
|
213
|
+
status_code, body = _parse_response(response)
|
|
214
|
+
except Exception as e:
|
|
215
|
+
status_code = 500
|
|
216
|
+
body = f'[ERR] arequest failed: {e}'
|
|
217
|
+
errlog_add(body)
|
|
218
|
+
finally:
|
|
219
|
+
if writer:
|
|
220
|
+
writer.close()
|
|
221
|
+
await writer.wait_closed()
|
|
222
|
+
return status_code, loads(body) if jsonify and status_code == 200 else body
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
#############################################
|
|
226
|
+
# Implement http get/post functions #
|
|
227
|
+
#############################################
|
|
158
228
|
|
|
159
229
|
def get(url, headers={}, sock_size=256, jsonify=False):
|
|
160
230
|
"""
|
|
@@ -172,6 +242,22 @@ def post(url, data=None, json=None, headers={}, sock_size=256, jsonify=False):
|
|
|
172
242
|
return request('POST', url, data=data, json=json, headers=headers, sock_size=sock_size, jsonify=jsonify)
|
|
173
243
|
|
|
174
244
|
|
|
245
|
+
async def aget(url, headers={}, sock_size=256, jsonify=False):
|
|
246
|
+
"""
|
|
247
|
+
GENERIC ASYNC HTTP GET FUNCTION
|
|
248
|
+
"""
|
|
249
|
+
return await arequest('GET', url, headers=headers, sock_size=sock_size, jsonify=jsonify)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
async def apost(url, data=None, json=None, headers={}, sock_size=256, jsonify=False):
|
|
253
|
+
"""
|
|
254
|
+
GENERIC ASYNC HTTP POST FUNCTION
|
|
255
|
+
:param data: string body (handle bare string as data for POST method)
|
|
256
|
+
:param json: json body (handle json as data for POST method)
|
|
257
|
+
"""
|
|
258
|
+
return await arequest('POST', url, data=data, json=json, headers=headers, sock_size=sock_size, jsonify=jsonify)
|
|
259
|
+
|
|
260
|
+
|
|
175
261
|
def host_cache():
|
|
176
262
|
"""
|
|
177
263
|
Return address cache
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: micrOSDevToolKit
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.9.0
|
|
4
4
|
Summary: Development and deployment environment for micrOS, the diy micropython automation OS (IoT)
|
|
5
5
|
Home-page: https://github.com/BxNxM/micrOS
|
|
6
6
|
Author: Marcell Ban
|
|
@@ -28,7 +28,7 @@ Requires-Dist: soundfile
|
|
|
28
28
|
|
|
29
29
|
#  micrOS
|
|
30
30
|
|
|
31
|
-
> **"
|
|
31
|
+
> **"The mini yet powerful operating system for DIY projects."**
|
|
32
32
|
|
|
33
33
|
                 <br/>
|
|
34
34
|
|