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.

Files changed (104) hide show
  1. env/driver_cp210x/.DS_Store +0 -0
  2. env/driver_cp210x/macOS_VCP_Driver/SiLabsUSBDriverDisk.dmg +0 -0
  3. env/driver_cp210x/macOS_VCP_Driver/macOS_VCP_Driver_Release_Notes.txt +0 -0
  4. micrOS/micropython/esp32-20241129-v1.24.1.bin +0 -0
  5. micrOS/micropython/esp32s3-20241129-v1.24.1.bin +0 -0
  6. micrOS/micropython/esp32s3_spiram_oct-20241129-v1.24.1.bin +0 -0
  7. micrOS/micropython/rpi-pico-w-20241129-v1.24.1.uf2 +0 -0
  8. micrOS/micropython/tinypico-20241129-v1.24.1.bin +0 -0
  9. micrOS/release_info/micrOS_ReleaseInfo/system_analysis_sum.json +40 -40
  10. micrOS/source/Common.py +12 -17
  11. micrOS/source/Config.py +20 -1
  12. micrOS/source/Hooks.py +25 -15
  13. micrOS/source/LM_buzzer.py +16 -9
  14. micrOS/source/LM_cct.py +2 -3
  15. micrOS/source/LM_dimmer.py +1 -2
  16. micrOS/source/LM_distance.py +2 -4
  17. micrOS/source/LM_genIO.py +1 -1
  18. micrOS/source/LM_i2s_mic.py +4 -4
  19. micrOS/source/LM_keychain.py +2 -3
  20. micrOS/source/LM_light_sensor.py +1 -2
  21. micrOS/source/LM_neoeffects.py +22 -7
  22. micrOS/source/LM_neopixel.py +2 -3
  23. micrOS/source/LM_oledui.py +3 -4
  24. micrOS/source/LM_pet_feeder.py +3 -4
  25. micrOS/source/LM_ph_sensor.py +2 -2
  26. micrOS/source/LM_presence.py +2 -3
  27. micrOS/source/LM_rest.py +52 -9
  28. micrOS/source/LM_rgb.py +1 -2
  29. micrOS/source/LM_roboarm.py +1 -2
  30. micrOS/source/LM_sound_event.py +2 -3
  31. micrOS/source/LM_system.py +14 -3
  32. micrOS/source/LM_telegram.py +226 -15
  33. micrOS/source/Logger.py +6 -0
  34. micrOS/source/Notify.py +46 -218
  35. micrOS/source/Scheduler.py +7 -4
  36. micrOS/source/Shell.py +2 -2
  37. micrOS/source/Tasks.py +106 -98
  38. micrOS/source/Types.py +6 -2
  39. micrOS/source/Web.py +32 -8
  40. micrOS/source/dashboard.html +4 -4
  41. micrOS/source/micrOS.py +5 -10
  42. micrOS/source/micrOSloader.py +16 -18
  43. micrOS/source/uapi.js +5 -6
  44. micrOS/source/urequests.py +171 -85
  45. {micrOSDevToolKit-2.8.6.dist-info → micrOSDevToolKit-2.9.0.dist-info}/METADATA +2 -2
  46. {micrOSDevToolKit-2.8.6.dist-info → micrOSDevToolKit-2.9.0.dist-info}/RECORD +95 -97
  47. toolkit/DevEnvUSB.py +1 -6
  48. toolkit/MicrOSDevEnv.py +8 -5
  49. toolkit/simulator_lib/__pycache__/simulator.cpython-312.pyc +0 -0
  50. toolkit/simulator_lib/__pycache__/uasyncio.cpython-312.pyc +0 -0
  51. toolkit/simulator_lib/__pycache__/usocket.cpython-312.pyc +0 -0
  52. toolkit/simulator_lib/simulator.py +14 -0
  53. toolkit/simulator_lib/uasyncio.py +2 -2
  54. toolkit/simulator_lib/usocket.py +5 -1
  55. toolkit/workspace/precompiled/Common.mpy +0 -0
  56. toolkit/workspace/precompiled/Config.mpy +0 -0
  57. toolkit/workspace/precompiled/Hooks.mpy +0 -0
  58. toolkit/workspace/precompiled/LM_buzzer.mpy +0 -0
  59. toolkit/workspace/precompiled/LM_cct.mpy +0 -0
  60. toolkit/workspace/precompiled/LM_dimmer.mpy +0 -0
  61. toolkit/workspace/precompiled/LM_distance.mpy +0 -0
  62. toolkit/workspace/precompiled/LM_genIO.mpy +0 -0
  63. toolkit/workspace/precompiled/LM_i2s_mic.mpy +0 -0
  64. toolkit/workspace/precompiled/LM_keychain.mpy +0 -0
  65. toolkit/workspace/precompiled/LM_light_sensor.mpy +0 -0
  66. toolkit/workspace/precompiled/LM_neoeffects.mpy +0 -0
  67. toolkit/workspace/precompiled/LM_neopixel.mpy +0 -0
  68. toolkit/workspace/precompiled/LM_oledui.mpy +0 -0
  69. toolkit/workspace/precompiled/LM_pet_feeder.py +3 -4
  70. toolkit/workspace/precompiled/LM_ph_sensor.py +2 -2
  71. toolkit/workspace/precompiled/LM_presence.mpy +0 -0
  72. toolkit/workspace/precompiled/LM_rest.mpy +0 -0
  73. toolkit/workspace/precompiled/LM_rgb.mpy +0 -0
  74. toolkit/workspace/precompiled/LM_roboarm.mpy +0 -0
  75. toolkit/workspace/precompiled/LM_sound_event.mpy +0 -0
  76. toolkit/workspace/precompiled/LM_system.mpy +0 -0
  77. toolkit/workspace/precompiled/LM_telegram.mpy +0 -0
  78. toolkit/workspace/precompiled/Logger.mpy +0 -0
  79. toolkit/workspace/precompiled/Notify.mpy +0 -0
  80. toolkit/workspace/precompiled/Scheduler.mpy +0 -0
  81. toolkit/workspace/precompiled/Shell.mpy +0 -0
  82. toolkit/workspace/precompiled/Tasks.mpy +0 -0
  83. toolkit/workspace/precompiled/Types.mpy +0 -0
  84. toolkit/workspace/precompiled/Web.mpy +0 -0
  85. toolkit/workspace/precompiled/dashboard.html +4 -4
  86. toolkit/workspace/precompiled/micrOS.mpy +0 -0
  87. toolkit/workspace/precompiled/micrOSloader.mpy +0 -0
  88. toolkit/workspace/precompiled/node_config.json +1 -1
  89. toolkit/workspace/precompiled/uapi.js +5 -6
  90. toolkit/workspace/precompiled/urequests.mpy +0 -0
  91. env/driver_cp210x/CH34XSER_MAC/CH34X_DRV_INSTALL_INSTRUCTIONS.pdf +0 -0
  92. env/driver_cp210x/CH34XSER_MAC/CH34xVCPDriver.pkg +0 -0
  93. micrOS/micropython/esp32-20231005-v1.21.0.bin +0 -0
  94. micrOS/micropython/esp32-GENERIC-20240602-v1.23.0.bin +0 -0
  95. micrOS/micropython/rpi-pico-w-20240602-v1.23.0.uf2 +0 -0
  96. micrOS/micropython/tinypico-20231005-v1.21.0.bin +0 -0
  97. micrOS/micropython/tinypico_usbc-UM-20240105-v1.22.1.bin +0 -0
  98. /micrOS/micropython/{esp32c3-GENERIC-20240222-v1.22.2.bin → esp32c3-20240222-v1.22.2.bin} +0 -0
  99. /micrOS/micropython/{esp32s2-GENERIC-20240602-v1.23.0.bin → esp32s2-20240602-v1.23.0.bin} +0 -0
  100. /micrOS/micropython/{esp32s3-GENERIC-20240105-v1.22.1.bin → esp32s3-20240105-v1.22.1.bin} +0 -0
  101. {micrOSDevToolKit-2.8.6.data → micrOSDevToolKit-2.9.0.data}/scripts/devToolKit.py +0 -0
  102. {micrOSDevToolKit-2.8.6.dist-info → micrOSDevToolKit-2.9.0.dist-info}/LICENSE +0 -0
  103. {micrOSDevToolKit-2.8.6.dist-info → micrOSDevToolKit-2.9.0.dist-info}/WHEEL +0 -0
  104. {micrOSDevToolKit-2.8.6.dist-info → micrOSDevToolKit-2.9.0.dist-info}/top_level.txt +0 -0
@@ -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
- def request(method, url, data=None, json=None, headers=None, sock_size=256, jsonify=False):
17
+
18
+ def _host_to_addr(host, port, force=False):
14
19
  """
15
- Micropython syncronous HTTP request function for REST API handling
16
- :param method: GET/POST
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
- # Extract the chunk size and convert to int
37
- chunk_size_str = _body[:line_end]
38
- try:
39
- chunk_size = int(chunk_size_str, 16)
40
- except ValueError as e:
41
- chunk_size = 0
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
- # Check chunk size
44
- if chunk_size == 0:
45
- break
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
- # Add the chunk data to the decoded data
48
- chunk_data = _body[line_end + 2: line_end + 2 + chunk_size]
49
- decoded += chunk_data
45
+ # Check chunk size
46
+ if chunk_size == 0:
47
+ break
50
48
 
51
- # Move to the next chunk
52
- _body = _body[line_end + 4 + chunk_size:]
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
- # Check for end of message marker again
55
- if not _body.startswith(b"\r\n"):
56
- break
57
- return decoded
58
-
59
- def _host_to_addr(force=False):
60
- """
61
- Cache host address to avoid getaddrinfo (slow)
62
- """
63
- nonlocal host, port
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
- # [_build_request] Create request (body, headers)
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
- # [_parse_response] Parse response - get body
142
- headers, body = response.split(b'\r\n\r\n', 1)
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, headers and body (text or jsons)
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
- # Implement http get/post functions #
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.8.6
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
  # ![LOGO](./media/logo_mini.png?raw=true) micrOS
30
30
 
31
- > **"Simple, yet increadbly useful."**
31
+ > **"The mini yet powerful operating system for DIY projects."**
32
32
 
33
33
  ![telnet](https://img.shields.io/badge/wifi-telnet-blue) ![esp32S2](https://img.shields.io/badge/esp32-S2-olive) ![tinypico](https://img.shields.io/badge/esp32-tinypico-olive) ![esp32S3](https://img.shields.io/badge/esp32-S3-olive) ![esp32S3](https://img.shields.io/badge/esp32-S3_RAM-olive) ![PYQT](https://img.shields.io/badge/esp32-PYQT-olive) ![raspberry-pico-w](https://img.shields.io/badge/raspberry-pico_W-critical) ![espCAM-esp-s](https://img.shields.io/badge/esp32-CAM_OV2640-olive) ![esp32-c3](https://img.shields.io/badge/esp32-C3_RISCV-olive) ![OTA](https://img.shields.io/badge/ota-update-blue) ![GPIO](https://img.shields.io/badge/gpio-i2c-success) ![clock](https://img.shields.io/badge/rtc-ntp-success) ![async](https://img.shields.io/badge/async-task_manager-success) ![irq](https://img.shields.io/badge/hardware-IRQs-success) ![socket](https://img.shields.io/badge/socket-STA_or_AP-blue) ![cron](https://img.shields.io/badge/scheduling-cron-success) ![stable](https://img.shields.io/badge/stabile-master_HEAD-success) ![stable](https://img.shields.io/badge/micropython-OS-gold)<br/>
34
34