micrOSDevToolKit 2.13.1__py3-none-any.whl → 2.17.1__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 (220) hide show
  1. micrOS/release_info/micrOS_ReleaseInfo/system_analysis_sum.json +125 -121
  2. micrOS/source/Common.py +48 -26
  3. micrOS/source/Config.py +13 -5
  4. micrOS/source/Espnow.py +100 -58
  5. micrOS/source/Files.py +77 -41
  6. micrOS/source/Hooks.py +18 -34
  7. micrOS/source/Logger.py +2 -7
  8. micrOS/source/Network.py +36 -16
  9. micrOS/source/Server.py +22 -8
  10. micrOS/source/Shell.py +9 -6
  11. micrOS/source/Tasks.py +34 -13
  12. micrOS/source/Web.py +69 -31
  13. micrOS/source/__pycache__/Common.cpython-312.pyc +0 -0
  14. micrOS/source/__pycache__/Files.cpython-312.pyc +0 -0
  15. micrOS/source/__pycache__/Logger.cpython-312.pyc +0 -0
  16. micrOS/source/__pycache__/Server.cpython-312.pyc +0 -0
  17. micrOS/source/config/_git.keep +0 -0
  18. micrOS/source/micrOS.py +7 -0
  19. micrOS/source/micrOSloader.py +4 -10
  20. micrOS/source/microIO.py +2 -2
  21. micrOS/source/modules/IO_esp32c6.py +38 -0
  22. micrOS/source/modules/LM_L298N.py +161 -0
  23. micrOS/source/modules/LM_cluster.py +255 -0
  24. {toolkit/workspace/precompiled → micrOS/source/modules}/LM_esp32.py +5 -0
  25. micrOS/source/modules/LM_espnow.py +36 -0
  26. micrOS/source/{LM_i2c.py → modules/LM_i2c.py} +1 -1
  27. micrOS/source/{LM_light_sensor.py → modules/LM_light_sensor.py} +2 -2
  28. micrOS/source/modules/LM_mqtt_client.py +246 -0
  29. micrOS/source/{LM_neoeffects.py → modules/LM_neoeffects.py} +14 -4
  30. micrOS/source/{LM_neomatrix.py → modules/LM_neomatrix.py} +140 -38
  31. micrOS/source/{LM_oled_ui.py → modules/LM_oled_ui.py} +2 -2
  32. micrOS/source/{LM_oledui.py → modules/LM_oledui.py} +2 -2
  33. micrOS/source/{LM_pacman.py → modules/LM_pacman.py} +74 -29
  34. micrOS/source/{LM_presence.py → modules/LM_presence.py} +2 -2
  35. micrOS/source/{LM_robustness.py → modules/LM_robustness.py} +49 -2
  36. micrOS/source/{LM_tcs3472.py → modules/LM_tcs3472.py} +4 -6
  37. micrOS/source/web/dashboard.html +2 -0
  38. micrOS/source/web/matrix_draw.html +390 -0
  39. micrOS/source/web/uapi.js +9 -6
  40. {microsdevtoolkit-2.13.1.dist-info → microsdevtoolkit-2.17.1.dist-info}/METADATA +30 -37
  41. {microsdevtoolkit-2.13.1.dist-info → microsdevtoolkit-2.17.1.dist-info}/RECORD +200 -190
  42. toolkit/DevEnvCompile.py +21 -12
  43. toolkit/DevEnvOTA.py +27 -16
  44. toolkit/DevEnvUSB.py +35 -21
  45. toolkit/LM_to_compile.dat +3 -1
  46. toolkit/MicrOSDevEnv.py +37 -21
  47. toolkit/dashboard_apps/QMI8685_GYRO.py +1 -1
  48. toolkit/dashboard_apps/SystemTest.py +8 -5
  49. toolkit/{MicrosFiles.py → lib/MicrosFiles.py} +24 -4
  50. toolkit/micrOSdashboard.py +2 -2
  51. toolkit/micrOSlint.py +17 -7
  52. toolkit/simulator_lib/__pycache__/simulator.cpython-312.pyc +0 -0
  53. toolkit/simulator_lib/__pycache__/uos.cpython-312.pyc +0 -0
  54. toolkit/simulator_lib/mqtt_as/Note.md +15 -0
  55. toolkit/simulator_lib/mqtt_as/__init__.py +950 -0
  56. toolkit/simulator_lib/mqtt_as/__pycache__/__init__.cpython-312.pyc +0 -0
  57. toolkit/simulator_lib/mqtt_as/clean.py +69 -0
  58. toolkit/simulator_lib/mqtt_as/mqtt_v5_properties.py +239 -0
  59. toolkit/simulator_lib/mqtt_as/range.py +90 -0
  60. toolkit/simulator_lib/mqtt_as/range_ex.py +119 -0
  61. toolkit/simulator_lib/simulator.py +14 -1
  62. toolkit/simulator_lib/uos.py +2 -0
  63. toolkit/workspace/precompiled/Common.mpy +0 -0
  64. toolkit/workspace/precompiled/Config.mpy +0 -0
  65. toolkit/workspace/precompiled/Espnow.mpy +0 -0
  66. toolkit/workspace/precompiled/Files.mpy +0 -0
  67. toolkit/workspace/precompiled/Hooks.mpy +0 -0
  68. toolkit/workspace/precompiled/Logger.mpy +0 -0
  69. toolkit/workspace/precompiled/Network.mpy +0 -0
  70. toolkit/workspace/precompiled/Server.mpy +0 -0
  71. toolkit/workspace/precompiled/Shell.mpy +0 -0
  72. toolkit/workspace/precompiled/Tasks.mpy +0 -0
  73. toolkit/workspace/precompiled/Web.mpy +0 -0
  74. toolkit/workspace/precompiled/config/_git.keep +0 -0
  75. toolkit/workspace/precompiled/micrOS.mpy +0 -0
  76. toolkit/workspace/precompiled/micrOSloader.mpy +0 -0
  77. toolkit/workspace/precompiled/microIO.mpy +0 -0
  78. toolkit/workspace/precompiled/{IO_esp32.mpy → modules/IO_esp32.mpy} +0 -0
  79. toolkit/workspace/precompiled/{IO_esp32c3.mpy → modules/IO_esp32c3.mpy} +0 -0
  80. toolkit/workspace/precompiled/modules/IO_esp32c6.mpy +0 -0
  81. toolkit/workspace/precompiled/{IO_esp32s2.mpy → modules/IO_esp32s2.mpy} +0 -0
  82. toolkit/workspace/precompiled/{IO_esp32s3.mpy → modules/IO_esp32s3.mpy} +0 -0
  83. toolkit/workspace/precompiled/{IO_m5stamp.mpy → modules/IO_m5stamp.mpy} +0 -0
  84. toolkit/workspace/precompiled/{IO_qtpy.mpy → modules/IO_qtpy.mpy} +0 -0
  85. toolkit/workspace/precompiled/modules/IO_rp2.mpy +0 -0
  86. toolkit/workspace/precompiled/modules/IO_s3matrix.mpy +0 -0
  87. toolkit/workspace/precompiled/{IO_tinypico.mpy → modules/IO_tinypico.mpy} +0 -0
  88. toolkit/workspace/precompiled/modules/LM_L298N.mpy +0 -0
  89. toolkit/workspace/precompiled/{LM_OV2640.mpy → modules/LM_OV2640.mpy} +0 -0
  90. toolkit/workspace/precompiled/{LM_aht10.mpy → modules/LM_aht10.mpy} +0 -0
  91. toolkit/workspace/precompiled/{LM_bme280.mpy → modules/LM_bme280.mpy} +0 -0
  92. toolkit/workspace/precompiled/{LM_buzzer.mpy → modules/LM_buzzer.mpy} +0 -0
  93. toolkit/workspace/precompiled/{LM_cct.mpy → modules/LM_cct.mpy} +0 -0
  94. toolkit/workspace/precompiled/modules/LM_cluster.mpy +0 -0
  95. toolkit/workspace/precompiled/{LM_co2.mpy → modules/LM_co2.mpy} +0 -0
  96. toolkit/workspace/precompiled/{LM_dht11.mpy → modules/LM_dht11.mpy} +0 -0
  97. toolkit/workspace/precompiled/{LM_dht22.mpy → modules/LM_dht22.mpy} +0 -0
  98. toolkit/workspace/precompiled/{LM_dimmer.mpy → modules/LM_dimmer.mpy} +0 -0
  99. toolkit/workspace/precompiled/{LM_distance.mpy → modules/LM_distance.mpy} +0 -0
  100. toolkit/workspace/precompiled/{LM_ds18.mpy → modules/LM_ds18.mpy} +0 -0
  101. {micrOS/source → toolkit/workspace/precompiled/modules}/LM_esp32.py +5 -0
  102. toolkit/workspace/precompiled/modules/LM_espnow.py +36 -0
  103. toolkit/workspace/precompiled/{LM_gameOfLife.mpy → modules/LM_gameOfLife.mpy} +0 -0
  104. toolkit/workspace/precompiled/{LM_genIO.mpy → modules/LM_genIO.mpy} +0 -0
  105. toolkit/workspace/precompiled/{LM_haptic.mpy → modules/LM_haptic.mpy} +0 -0
  106. toolkit/workspace/precompiled/{LM_i2c.py → modules/LM_i2c.py} +1 -1
  107. toolkit/workspace/precompiled/{LM_i2s_mic.mpy → modules/LM_i2s_mic.mpy} +0 -0
  108. toolkit/workspace/precompiled/{LM_keychain.mpy → modules/LM_keychain.mpy} +0 -0
  109. toolkit/workspace/precompiled/{LM_ld2410.mpy → modules/LM_ld2410.mpy} +0 -0
  110. toolkit/workspace/precompiled/modules/LM_light_sensor.mpy +0 -0
  111. toolkit/workspace/precompiled/modules/LM_mqtt_client.mpy +0 -0
  112. toolkit/workspace/precompiled/{LM_neoeffects.mpy → modules/LM_neoeffects.mpy} +0 -0
  113. toolkit/workspace/precompiled/modules/LM_neomatrix.mpy +0 -0
  114. toolkit/workspace/precompiled/{LM_neopixel.mpy → modules/LM_neopixel.mpy} +0 -0
  115. toolkit/workspace/precompiled/{LM_oled.mpy → modules/LM_oled.mpy} +0 -0
  116. toolkit/workspace/precompiled/{LM_oled_sh1106.mpy → modules/LM_oled_sh1106.mpy} +0 -0
  117. toolkit/workspace/precompiled/modules/LM_oled_ui.mpy +0 -0
  118. toolkit/workspace/precompiled/modules/LM_oledui.mpy +0 -0
  119. toolkit/workspace/precompiled/modules/LM_pacman.mpy +0 -0
  120. toolkit/workspace/precompiled/modules/LM_presence.mpy +0 -0
  121. toolkit/workspace/precompiled/{LM_rest.mpy → modules/LM_rest.mpy} +0 -0
  122. toolkit/workspace/precompiled/{LM_rgb.mpy → modules/LM_rgb.mpy} +0 -0
  123. toolkit/workspace/precompiled/{LM_rgbcct.mpy → modules/LM_rgbcct.mpy} +0 -0
  124. toolkit/workspace/precompiled/{LM_roboarm.mpy → modules/LM_roboarm.mpy} +0 -0
  125. toolkit/workspace/precompiled/{LM_robustness.py → modules/LM_robustness.py} +49 -2
  126. toolkit/workspace/precompiled/{LM_servo.mpy → modules/LM_servo.mpy} +0 -0
  127. toolkit/workspace/precompiled/{LM_sound_event.mpy → modules/LM_sound_event.mpy} +0 -0
  128. toolkit/workspace/precompiled/{LM_stepper.mpy → modules/LM_stepper.mpy} +0 -0
  129. toolkit/workspace/precompiled/{LM_switch.mpy → modules/LM_switch.mpy} +0 -0
  130. toolkit/workspace/precompiled/{LM_system.mpy → modules/LM_system.mpy} +0 -0
  131. toolkit/workspace/precompiled/{LM_tcs3472.py → modules/LM_tcs3472.py} +4 -6
  132. toolkit/workspace/precompiled/{LM_telegram.mpy → modules/LM_telegram.mpy} +0 -0
  133. toolkit/workspace/precompiled/{LM_tinyrgb.mpy → modules/LM_tinyrgb.mpy} +0 -0
  134. toolkit/workspace/precompiled/{LM_trackball.mpy → modules/LM_trackball.mpy} +0 -0
  135. toolkit/workspace/precompiled/{LM_veml7700.mpy → modules/LM_veml7700.mpy} +0 -0
  136. toolkit/workspace/precompiled/web/dashboard.html +2 -0
  137. toolkit/workspace/precompiled/web/matrix_draw.html +390 -0
  138. toolkit/workspace/precompiled/web/uapi.js +9 -6
  139. micrOS/source/IO_esp32c6.py +0 -16
  140. micrOS/source/LM_L298N_DCmotor.py +0 -86
  141. micrOS/source/LM_espnow.py +0 -57
  142. micrOS/source/LM_mqtt_pro.py +0 -211
  143. toolkit/lib/file_extensions.py +0 -22
  144. toolkit/workspace/precompiled/Common.cpython-312.pyc +0 -0
  145. toolkit/workspace/precompiled/IO_esp32c6.mpy +0 -0
  146. toolkit/workspace/precompiled/IO_rp2.mpy +0 -0
  147. toolkit/workspace/precompiled/IO_s3matrix.mpy +0 -0
  148. toolkit/workspace/precompiled/LM_L298N_DCmotor.mpy +0 -0
  149. toolkit/workspace/precompiled/LM_espnow.py +0 -57
  150. toolkit/workspace/precompiled/LM_light_sensor.mpy +0 -0
  151. toolkit/workspace/precompiled/LM_mqtt_pro.py +0 -211
  152. toolkit/workspace/precompiled/LM_neomatrix.mpy +0 -0
  153. toolkit/workspace/precompiled/LM_oled_ui.mpy +0 -0
  154. toolkit/workspace/precompiled/LM_oledui.mpy +0 -0
  155. toolkit/workspace/precompiled/LM_pacman.mpy +0 -0
  156. toolkit/workspace/precompiled/LM_presence.mpy +0 -0
  157. toolkit/workspace/precompiled/Logger.cpython-312.pyc +0 -0
  158. toolkit/workspace/precompiled/Server.cpython-312.pyc +0 -0
  159. /micrOS/source/{IO_esp32.py → modules/IO_esp32.py} +0 -0
  160. /micrOS/source/{IO_esp32c3.py → modules/IO_esp32c3.py} +0 -0
  161. /micrOS/source/{IO_esp32s2.py → modules/IO_esp32s2.py} +0 -0
  162. /micrOS/source/{IO_esp32s3.py → modules/IO_esp32s3.py} +0 -0
  163. /micrOS/source/{IO_m5stamp.py → modules/IO_m5stamp.py} +0 -0
  164. /micrOS/source/{IO_qtpy.py → modules/IO_qtpy.py} +0 -0
  165. /micrOS/source/{IO_rp2.py → modules/IO_rp2.py} +0 -0
  166. /micrOS/source/{IO_s3matrix.py → modules/IO_s3matrix.py} +0 -0
  167. /micrOS/source/{IO_tinypico.py → modules/IO_tinypico.py} +0 -0
  168. /micrOS/source/{LM_L9110_DCmotor.py → modules/LM_L9110_DCmotor.py} +0 -0
  169. /micrOS/source/{LM_OV2640.py → modules/LM_OV2640.py} +0 -0
  170. /micrOS/source/{LM_VL53L0X.py → modules/LM_VL53L0X.py} +0 -0
  171. /micrOS/source/{LM_aht10.py → modules/LM_aht10.py} +0 -0
  172. /micrOS/source/{LM_bme280.py → modules/LM_bme280.py} +0 -0
  173. /micrOS/source/{LM_buzzer.py → modules/LM_buzzer.py} +0 -0
  174. /micrOS/source/{LM_cct.py → modules/LM_cct.py} +0 -0
  175. /micrOS/source/{LM_co2.py → modules/LM_co2.py} +0 -0
  176. /micrOS/source/{LM_dashboard_be.py → modules/LM_dashboard_be.py} +0 -0
  177. /micrOS/source/{LM_dht11.py → modules/LM_dht11.py} +0 -0
  178. /micrOS/source/{LM_dht22.py → modules/LM_dht22.py} +0 -0
  179. /micrOS/source/{LM_dimmer.py → modules/LM_dimmer.py} +0 -0
  180. /micrOS/source/{LM_distance.py → modules/LM_distance.py} +0 -0
  181. /micrOS/source/{LM_ds18.py → modules/LM_ds18.py} +0 -0
  182. /micrOS/source/{LM_gameOfLife.py → modules/LM_gameOfLife.py} +0 -0
  183. /micrOS/source/{LM_genIO.py → modules/LM_genIO.py} +0 -0
  184. /micrOS/source/{LM_haptic.py → modules/LM_haptic.py} +0 -0
  185. /micrOS/source/{LM_i2s_mic.py → modules/LM_i2s_mic.py} +0 -0
  186. /micrOS/source/{LM_keychain.py → modules/LM_keychain.py} +0 -0
  187. /micrOS/source/{LM_ld2410.py → modules/LM_ld2410.py} +0 -0
  188. /micrOS/source/{LM_neopixel.py → modules/LM_neopixel.py} +0 -0
  189. /micrOS/source/{LM_oled.py → modules/LM_oled.py} +0 -0
  190. /micrOS/source/{LM_oled_sh1106.py → modules/LM_oled_sh1106.py} +0 -0
  191. /micrOS/source/{LM_pet_feeder.py → modules/LM_pet_feeder.py} +0 -0
  192. /micrOS/source/{LM_qmi8658.py → modules/LM_qmi8658.py} +0 -0
  193. /micrOS/source/{LM_rencoder.py → modules/LM_rencoder.py} +0 -0
  194. /micrOS/source/{LM_rest.py → modules/LM_rest.py} +0 -0
  195. /micrOS/source/{LM_rgb.py → modules/LM_rgb.py} +0 -0
  196. /micrOS/source/{LM_rgbcct.py → modules/LM_rgbcct.py} +0 -0
  197. /micrOS/source/{LM_roboarm.py → modules/LM_roboarm.py} +0 -0
  198. /micrOS/source/{LM_rp2w.py → modules/LM_rp2w.py} +0 -0
  199. /micrOS/source/{LM_sdcard.py → modules/LM_sdcard.py} +0 -0
  200. /micrOS/source/{LM_servo.py → modules/LM_servo.py} +0 -0
  201. /micrOS/source/{LM_sound_event.py → modules/LM_sound_event.py} +0 -0
  202. /micrOS/source/{LM_stepper.py → modules/LM_stepper.py} +0 -0
  203. /micrOS/source/{LM_switch.py → modules/LM_switch.py} +0 -0
  204. /micrOS/source/{LM_system.py → modules/LM_system.py} +0 -0
  205. /micrOS/source/{LM_telegram.py → modules/LM_telegram.py} +0 -0
  206. /micrOS/source/{LM_tinyrgb.py → modules/LM_tinyrgb.py} +0 -0
  207. /micrOS/source/{LM_trackball.py → modules/LM_trackball.py} +0 -0
  208. /micrOS/source/{LM_veml7700.py → modules/LM_veml7700.py} +0 -0
  209. {microsdevtoolkit-2.13.1.data → microsdevtoolkit-2.17.1.data}/scripts/devToolKit.py +0 -0
  210. {microsdevtoolkit-2.13.1.dist-info → microsdevtoolkit-2.17.1.dist-info}/WHEEL +0 -0
  211. {microsdevtoolkit-2.13.1.dist-info → microsdevtoolkit-2.17.1.dist-info}/licenses/LICENSE +0 -0
  212. {microsdevtoolkit-2.13.1.dist-info → microsdevtoolkit-2.17.1.dist-info}/top_level.txt +0 -0
  213. /toolkit/workspace/precompiled/{LM_L9110_DCmotor.py → modules/LM_L9110_DCmotor.py} +0 -0
  214. /toolkit/workspace/precompiled/{LM_VL53L0X.py → modules/LM_VL53L0X.py} +0 -0
  215. /toolkit/workspace/precompiled/{LM_dashboard_be.py → modules/LM_dashboard_be.py} +0 -0
  216. /toolkit/workspace/precompiled/{LM_pet_feeder.py → modules/LM_pet_feeder.py} +0 -0
  217. /toolkit/workspace/precompiled/{LM_qmi8658.py → modules/LM_qmi8658.py} +0 -0
  218. /toolkit/workspace/precompiled/{LM_rencoder.py → modules/LM_rencoder.py} +0 -0
  219. /toolkit/workspace/precompiled/{LM_rp2w.py → modules/LM_rp2w.py} +0 -0
  220. /toolkit/workspace/precompiled/{LM_sdcard.py → modules/LM_sdcard.py} +0 -0
@@ -0,0 +1,69 @@
1
+ # clean.py Test of asynchronous mqtt client with clean session.
2
+ # (C) Copyright Peter Hinch 2017-2019.
3
+ # Released under the MIT licence.
4
+
5
+ # Public brokers https://github.com/mqtt/mqtt.github.io/wiki/public_brokers
6
+
7
+ # The use of clean_session means that after a connection failure subscriptions
8
+ # must be renewed (MQTT spec 3.1.2.4). This is done by the connect handler.
9
+ # Note that publications issued during the outage will be missed. If this is
10
+ # an issue see unclean.py.
11
+
12
+ # red LED: ON == WiFi fail
13
+ # blue LED heartbeat: demonstrates scheduler is running.
14
+
15
+ from mqtt_as import MQTTClient
16
+ from mqtt_local import wifi_led, blue_led, config
17
+ import uasyncio as asyncio
18
+
19
+ # Subscription callback
20
+ def sub_cb(topic, msg, retained):
21
+ print(f'Topic: "{topic.decode()}" Message: "{msg.decode()}" Retained: {retained}')
22
+
23
+ # Demonstrate scheduler is operational.
24
+ async def heartbeat():
25
+ s = True
26
+ while True:
27
+ await asyncio.sleep_ms(500)
28
+ blue_led(s)
29
+ s = not s
30
+
31
+ async def wifi_han(state):
32
+ wifi_led(not state)
33
+ print('Wifi is ', 'up' if state else 'down')
34
+ await asyncio.sleep(1)
35
+
36
+ # If you connect with clean_session True, must re-subscribe (MQTT spec 3.1.2.4)
37
+ async def conn_han(client):
38
+ await client.subscribe('foo_topic', 1)
39
+
40
+ async def main(client):
41
+ try:
42
+ await client.connect()
43
+ except OSError:
44
+ print('Connection failed.')
45
+ return
46
+ n = 0
47
+ while True:
48
+ await asyncio.sleep(5)
49
+ print('publish', n)
50
+ # If WiFi is down the following will pause for the duration.
51
+ await client.publish('result', '{} {}'.format(n, client.REPUB_COUNT), qos = 1)
52
+ n += 1
53
+
54
+ # Define configuration
55
+ config['subs_cb'] = sub_cb
56
+ config['wifi_coro'] = wifi_han
57
+ config['connect_coro'] = conn_han
58
+ config['clean'] = True
59
+
60
+ # Set up client
61
+ MQTTClient.DEBUG = True # Optional
62
+ client = MQTTClient(config)
63
+
64
+ asyncio.create_task(heartbeat())
65
+ try:
66
+ asyncio.run(main(client))
67
+ finally:
68
+ client.close() # Prevent LmacRxBlk:1 errors
69
+ asyncio.new_event_loop()
@@ -0,0 +1,239 @@
1
+ # mqtt_v5_properties.py Add MQTT V5 extensions to mqtt_as
2
+
3
+ # (C) Copyright Bob Veringa 2024-2025.
4
+ # Released under the MIT licence.
5
+
6
+
7
+ import struct
8
+
9
+
10
+ def encode_byte(value):
11
+ # It takes in a byte and returns a byte
12
+ return value
13
+
14
+
15
+ def encode_two_byte_int(value):
16
+ return struct.pack("!H", value)
17
+
18
+
19
+ def encode_four_byte_int(value):
20
+ return struct.pack("!I", value)
21
+
22
+
23
+ def encode_string(value):
24
+ value = value.encode("utf-8")
25
+ return struct.pack("!H", len(value)) + value
26
+
27
+
28
+ def encode_string_pair(value):
29
+ # just get the first key and value
30
+ key, value = list(value.items())[0]
31
+ return encode_string(key) + encode_string(value)
32
+
33
+
34
+ def encode_binary(value):
35
+ return struct.pack("!H", len(value)) + value
36
+
37
+
38
+ def encode_variable_byte_int(value):
39
+ out = bytearray(4)
40
+ i = 0
41
+ for i in range(4):
42
+ b = value & 0x7F
43
+ value >>= 7
44
+ if value > 0:
45
+ b |= 0x80
46
+ out[i] = b
47
+ if value == 0:
48
+ break
49
+ return out[: i + 1]
50
+
51
+
52
+ # This table does not contain all properties (unlike the decode table)
53
+ # as not all properties can be sent by the client.
54
+ ENCODE_TABLE = {
55
+ 0x01: encode_byte, # Payload Format Indicator
56
+ 0x02: encode_four_byte_int, # Message Expiry Interval
57
+ 0x03: encode_string, # Content Type
58
+ 0x08: encode_string, # Response Topic
59
+ 0x09: encode_binary, # Correlation Data
60
+ 0x0B: encode_variable_byte_int, # Subscription Identifier
61
+ 0x11: encode_four_byte_int, # Session Expiry Interval
62
+ 0x15: encode_string, # Authentication Method
63
+ 0x16: encode_binary, # Authentication Data
64
+ 0x17: encode_byte, # Request Problem Information
65
+ 0x18: encode_four_byte_int, # Will Delay Interval
66
+ 0x19: encode_byte, # Request Response Information
67
+ 0x1C: encode_string, # Server Reference
68
+ 0x1F: encode_string, # Reason String
69
+ 0x21: encode_two_byte_int, # Receive Maximum
70
+ 0x22: encode_two_byte_int, # Topic Alias Maximum
71
+ 0x23: encode_two_byte_int, # Topic Alias
72
+ 0x26: encode_string_pair, # User Property
73
+ 0x27: encode_four_byte_int, # Maximum Packet Size
74
+ }
75
+
76
+
77
+ # MQTT_base class. Handles MQTT protocol on the basis of a good connection.
78
+ # Exceptions from connectivity failures are handled by MQTTClient subclass.
79
+ def encode_properties(properties: dict):
80
+ # If properties are empty or None, we can just return a single byte (0)
81
+ if properties in (None, {}):
82
+ return bytes(1)
83
+
84
+ # We can't modify the properties dict, as user might want to use it later
85
+ # So we will create a new dict with the encoded values.
86
+ # This causes a slight increase in memory usage. But this is acceptable.
87
+ pre_encoded_properties = {}
88
+
89
+ # We keep track of the length of the properties
90
+ properties_length = 0
91
+
92
+ # Preprocess properties to encode everything as bytes.
93
+ for key, value in properties.items():
94
+ encode_func = ENCODE_TABLE.get(key)
95
+ if encode_func is None:
96
+ # We can just leave that data as is and assume that it is valid.
97
+ tmp_value = value
98
+ else:
99
+ tmp_value = encode_func(value)
100
+ pre_encoded_properties[key] = tmp_value
101
+
102
+ # Pre-calculate the length of the properties
103
+ properties_length += 1 # key
104
+ properties_length += len(tmp_value)
105
+
106
+ # Mark properties as deleted
107
+ del properties
108
+
109
+ variable_length = 1
110
+ if properties_length > 127:
111
+ variable_length += 1
112
+ if properties_length > 16383:
113
+ variable_length += 1
114
+ if properties_length > 2097151:
115
+ variable_length += 1
116
+
117
+ # Now we can allocate the byte array
118
+ properties_bytes = bytearray(variable_length + properties_length)
119
+ view = memoryview(properties_bytes)
120
+
121
+ i = 0
122
+ while properties_length > 0x7F:
123
+ view[i] = (properties_length & 0x7F) | 0x80
124
+ properties_length >>= 7
125
+ i += 1
126
+
127
+ view[i] = properties_length
128
+ i += 1
129
+
130
+ for key, value in pre_encoded_properties.items():
131
+ view[i] = key
132
+ i += 1
133
+ view[i : i + len(value)] = value
134
+ i += len(value)
135
+
136
+ return properties_bytes
137
+
138
+
139
+ def decode_byte(props, offset):
140
+ value = props[offset]
141
+ offset += 1
142
+ return value, offset
143
+
144
+
145
+ def decode_two_byte_int(props, offset):
146
+ value = struct.unpack_from("!H", props, offset)[0]
147
+ offset += 2
148
+ return value, offset
149
+
150
+
151
+ def decode_four_byte_int(props, offset):
152
+ value = struct.unpack_from("!I", props, offset)[0]
153
+ offset += 4
154
+ return value, offset
155
+
156
+
157
+ def decode_string(props, offset):
158
+ str_length = struct.unpack_from("!H", props, offset)[0]
159
+ offset += 2
160
+ value = props[offset : offset + str_length].decode("utf-8")
161
+ offset += str_length
162
+ return value, offset
163
+
164
+
165
+ def decode_string_pair(props, offset):
166
+ key, offset = decode_string(props, offset)
167
+ value, offset = decode_string(props, offset)
168
+ item = {key: value}
169
+ return item, offset
170
+
171
+
172
+ def decode_binary(props, offset):
173
+ data_length = struct.unpack_from("!H", props, offset)[0]
174
+ offset += 2
175
+ value = props[offset : offset + data_length]
176
+ offset += data_length
177
+ return value, offset
178
+
179
+
180
+ def decode_variable_byte_int(props, offset):
181
+ value = 0
182
+ for i in range(4):
183
+ b = props[offset]
184
+ value |= (b & 0x7F) << (7 * i)
185
+ offset += 1
186
+ if not b & 0x80:
187
+ break
188
+ return value, offset
189
+
190
+
191
+ decode_property_lookup = {
192
+ 0x01: decode_byte, # Payload Format Indicator
193
+ 0x02: decode_four_byte_int, # Message Expiry Interval
194
+ 0x03: decode_string, # Content Type
195
+ 0x08: decode_string, # Response Topic
196
+ 0x09: decode_binary, # Correlation Data
197
+ 0x0B: decode_variable_byte_int, # Subscription Identifier
198
+ 0x11: decode_four_byte_int, # Session Expiry Interval
199
+ 0x12: decode_string, # Assigned Client Identifier
200
+ 0x13: decode_two_byte_int, # Server Keep Alive
201
+ 0x15: decode_string, # Authentication Method
202
+ 0x16: decode_binary, # Authentication Data
203
+ 0x17: decode_byte, # Request Problem Information
204
+ 0x18: decode_four_byte_int, # Will Delay Interval
205
+ 0x19: decode_byte, # Request Response Information
206
+ 0x1A: decode_string, # Response Information
207
+ 0x1C: decode_string, # Server Reference
208
+ 0x1F: decode_string, # Reason String
209
+ 0x21: decode_two_byte_int, # Receive Maximum
210
+ 0x22: decode_two_byte_int, # Topic Alias Maximum
211
+ 0x23: decode_two_byte_int, # Topic Alias
212
+ 0x24: decode_byte, # Maximum QoS
213
+ 0x25: decode_byte, # Retain Available
214
+ 0x26: decode_string_pair, # User Property
215
+ 0x27: decode_four_byte_int, # Maximum Packet Size
216
+ 0x28: decode_byte, # Wildcard Subscription Available
217
+ 0x29: decode_byte, # Subscription Identifiers Available
218
+ 0x2A: decode_byte, # Shared Subscription Available
219
+ }
220
+
221
+
222
+ def decode_properties(props, properties_length):
223
+ if isinstance(props, memoryview):
224
+ props = bytes(props) # If a memoryview is passed, make a copy
225
+ offset = 0
226
+ properties = {}
227
+
228
+ while offset < properties_length:
229
+ property_identifier = props[offset]
230
+ offset += 1
231
+
232
+ if property_identifier in decode_property_lookup:
233
+ decode_function = decode_property_lookup[property_identifier]
234
+ value, offset = decode_function(props, offset)
235
+ properties[property_identifier] = value
236
+ else:
237
+ raise ValueError(f"Unknown property identifier: {property_identifier}")
238
+
239
+ return properties
@@ -0,0 +1,90 @@
1
+ # range.py Test of asynchronous mqtt client with clean session False.
2
+ # (C) Copyright Peter Hinch 2017-2024.
3
+ # Released under the MIT licence.
4
+
5
+ # Now uses the event interface
6
+
7
+ # Public brokers https://github.com/mqtt/mqtt.github.io/wiki/public_brokers
8
+
9
+ # This demo is for wireless range tests. If OOR the red WiFi ON LED will go out.
10
+ # In range the blue LED will pulse for each received message.
11
+ # Uses clean sessions to avoid backlog when OOR.
12
+
13
+ # red LED: ON == WiFi OK
14
+ # blue LED pulse == message received
15
+ # Publishes connection statistics.
16
+
17
+ from mqtt_as import MQTTClient
18
+ from mqtt_local import wifi_led, blue_led, config
19
+ import uasyncio as asyncio
20
+
21
+ TOPIC = "shed" # For demo publication and last will use same topic
22
+
23
+ outages = 0
24
+
25
+
26
+ async def pulse(): # This demo pulses blue LED each time a subscribed msg arrives.
27
+ blue_led(True)
28
+ await asyncio.sleep(1)
29
+ blue_led(False)
30
+
31
+
32
+ async def messages(client):
33
+ async for topic, msg, retained in client.queue:
34
+ print(f'Topic: "{topic.decode()}" Message: "{msg.decode()}" Retained: {retained}')
35
+ asyncio.create_task(pulse())
36
+
37
+
38
+ async def down(client):
39
+ global outages
40
+ while True:
41
+ await client.down.wait() # Pause until connectivity changes
42
+ client.down.clear()
43
+ wifi_led(False)
44
+ outages += 1
45
+ print("WiFi or broker is down.")
46
+
47
+
48
+ async def up(client):
49
+ while True:
50
+ await client.up.wait()
51
+ client.up.clear()
52
+ wifi_led(True)
53
+ print("We are connected to broker.")
54
+ await client.subscribe("foo_topic", 1)
55
+
56
+
57
+ async def main(client):
58
+ try:
59
+ await client.connect(quick=True)
60
+ except OSError:
61
+ print("Connection failed.")
62
+ return
63
+ for task in (up, down, messages):
64
+ asyncio.create_task(task(client))
65
+ n = 0
66
+ while True:
67
+ await asyncio.sleep(5)
68
+ print("publish", n)
69
+ # If WiFi is down the following will pause for the duration.
70
+ await client.publish(
71
+ TOPIC, "{} repubs: {} outages: {}".format(n, client.REPUB_COUNT, outages), qos=1
72
+ )
73
+ n += 1
74
+
75
+
76
+ # Define configuration
77
+ config["will"] = (TOPIC, "Goodbye cruel world!", False, 0)
78
+ config["keepalive"] = 120
79
+ config["queue_len"] = 1 # Use event interface with default queue
80
+
81
+ # Set up client. Enable optional debug statements.
82
+ MQTTClient.DEBUG = True
83
+ client = MQTTClient(config)
84
+
85
+ try:
86
+ asyncio.run(main(client))
87
+ finally: # Prevent LmacRxBlk:1 errors.
88
+ client.close()
89
+ blue_led(True)
90
+ asyncio.new_event_loop()
@@ -0,0 +1,119 @@
1
+ # range_ex.py Test of asynchronous mqtt client with clean session False.
2
+ # Extended version publishes SSID
3
+ # (C) Copyright Peter Hinch 2017-2024.
4
+ # Released under the MIT licence.
5
+
6
+ # Now uses the event interface
7
+
8
+ # Public brokers https://github.com/mqtt/mqtt.github.io/wiki/public_brokers
9
+
10
+ # This demo is for wireless range tests. If OOR the red LED will light.
11
+ # In range the blue LED will pulse for each received message.
12
+ # Uses clean sessions to avoid backlog when OOR.
13
+
14
+ # red LED: ON == WiFi fail
15
+ # blue LED pulse == message received
16
+ # Publishes connection statistics.
17
+
18
+ from mqtt_as import MQTTClient, RP2
19
+
20
+ if RP2:
21
+ from sys import implementation
22
+ from mqtt_local import wifi_led, blue_led, config
23
+ import uasyncio as asyncio
24
+ import network
25
+ import gc
26
+
27
+ TOPIC = "shed" # For demo publication and last will use same topic
28
+
29
+ outages = 0
30
+ rssi = -199 # Effectively zero signal in dB.
31
+
32
+
33
+ async def pulse(): # This demo pulses blue LED each time a subscribed msg arrives.
34
+ blue_led(True)
35
+ await asyncio.sleep(1)
36
+ blue_led(False)
37
+
38
+
39
+ # The only way to measure RSSI is via scan(). Alas scan() blocks so the code
40
+ # causes the obvious uasyncio issues.
41
+ async def get_rssi():
42
+ global rssi
43
+ s = network.WLAN()
44
+ ssid = config["ssid"].encode("UTF8")
45
+ while True:
46
+ try:
47
+ rssi = [x[3] for x in s.scan() if x[0] == ssid][0]
48
+ except IndexError: # ssid not found.
49
+ rssi = -199
50
+ await asyncio.sleep(30)
51
+
52
+
53
+ async def messages(client):
54
+ async for topic, msg, retained in client.queue:
55
+ print(f'Topic: "{topic.decode()}" Message: "{msg.decode()}" Retained: {retained}')
56
+ asyncio.create_task(pulse())
57
+
58
+
59
+ async def down(client):
60
+ global outages
61
+ while True:
62
+ await client.down.wait() # Pause until connectivity changes
63
+ client.down.clear()
64
+ wifi_led(False)
65
+ outages += 1
66
+ print("WiFi or broker is down.")
67
+
68
+
69
+ async def up(client):
70
+ while True:
71
+ await client.up.wait()
72
+ client.up.clear()
73
+ wifi_led(True)
74
+ print("We are connected to broker.")
75
+ await client.subscribe("foo_topic", 1)
76
+
77
+
78
+ async def main(client):
79
+ try:
80
+ await client.connect()
81
+ except OSError:
82
+ print("Connection failed.")
83
+ return
84
+ asyncio.create_task(up(client))
85
+ asyncio.create_task(down(client))
86
+ asyncio.create_task(messages(client))
87
+ n = 0
88
+ s = "{} repubs: {} outages: {} rssi: {}dB free: {}bytes discards: {}"
89
+ while True:
90
+ await asyncio.sleep(5)
91
+ gc.collect()
92
+ m = gc.mem_free()
93
+ print("publish", n)
94
+ # If WiFi is down the following will pause for the duration.
95
+ await client.publish(
96
+ TOPIC, s.format(n, client.REPUB_COUNT, outages, rssi, m, client.queue.discards), qos=1
97
+ )
98
+ n += 1
99
+
100
+
101
+ # Define configuration
102
+ config["will"] = (TOPIC, "Goodbye cruel world!", False, 0)
103
+ config["keepalive"] = 120
104
+ config["queue_len"] = 4 # Use event interface
105
+
106
+ # Set up client. Enable optional debug statements.
107
+ MQTTClient.DEBUG = True
108
+ client = MQTTClient(config)
109
+
110
+ # Currently (Apr 22) this task causes connection periodically to be dropped on Arduino Nano Connect
111
+ # It does work on Pico W
112
+ if not RP2 or "Pico W" in implementation._machine:
113
+ asyncio.create_task(get_rssi())
114
+ try:
115
+ asyncio.run(main(client))
116
+ finally: # Prevent LmacRxBlk:1 errors.
117
+ client.close()
118
+ blue_led(True)
119
+ asyncio.new_event_loop()
@@ -29,6 +29,7 @@ class micrOSIM():
29
29
  def __init__(self, doc_resolve=False):
30
30
  if doc_resolve:
31
31
  console("[micrOSIM] Create micrOS LM doc (env proc)")
32
+ self._init_sim_doc_resolve()
32
33
  # json_structure, html_structure
33
34
  self.doc_output = (None, None)
34
35
  else:
@@ -38,7 +39,19 @@ class micrOSIM():
38
39
  self.pid = None
39
40
  micrOSIM.SIM_PROCESS_LIST.append(self.process)
40
41
 
42
+ def _init_sim_doc_resolve(self):
43
+ """
44
+ Init micrOS in simulator - folder structure creation
45
+ """
46
+ sim_path = LocalMachine.SimplePopPushd()
47
+ sim_path.pushd(SIM_PATH)
48
+ import micrOS # Init micrOS - DO NOT REMOVE
49
+ sim_path.popd()
50
+
41
51
  def micrOS_sim_worker(self, trace=False):
52
+ """
53
+ Start micrOS in python simulator
54
+ """
42
55
  sim_path = LocalMachine.SimplePopPushd()
43
56
  sim_path.pushd(SIM_PATH)
44
57
  console("[micrOSIM] Start micrOS loader in: {}".format(SIM_PATH))
@@ -130,7 +143,7 @@ class micrOSIM():
130
143
  console(f"[micrOSIM][Extract doc-str] LM_{mod}.{func}.__doc__")
131
144
  try:
132
145
  # Get function doc string
133
- exec(f"import LM_{mod}")
146
+ exec(f"from modules import LM_{mod}")
134
147
  doc_str = eval(f"LM_{mod}.{func}.__doc__")
135
148
  # Get function pin map
136
149
  if func == 'pinmap':
@@ -68,6 +68,7 @@ def rename(old_path, new_path):
68
68
  print(f"[uos.SIM] rename: {old_path} -> {new_path}")
69
69
  os.rename(old_path, new_path)
70
70
 
71
+
71
72
  def _stat_eval(stat_result):
72
73
  """
73
74
  micropython converter
@@ -82,6 +83,7 @@ def _stat_eval(stat_result):
82
83
  return (micropython_file_identifier['dir'],)
83
84
  return (0x0,)
84
85
 
86
+
85
87
  def stat(path):
86
88
  path = __mock_sim_dir(path)
87
89
  stat_result = os.stat(path)
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
File without changes
Binary file
Binary file
@@ -18,6 +18,11 @@ def temp():
18
18
  """
19
19
  Measure CPU temperature
20
20
  """
21
+ try:
22
+ cpu_temp = esp32.mcu_temperature()
23
+ return {'MCU temp [C]': int(cpu_temp)}
24
+ except:
25
+ pass
21
26
  try:
22
27
  raw_temp = esp32.raw_temperature()
23
28
  except Exception as e: