micrOSDevToolKit 2.10.6__py3-none-any.whl → 2.13.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 (151) hide show
  1. env/driver_cp210x/macOS_VCP_Driver/SiLabsUSBDriverDisk.dmg +0 -0
  2. env/driver_cp210x/macOS_VCP_Driver/macOS_VCP_Driver_Release_Notes.txt +17 -1
  3. micrOS/micropython/esp32c6-GENERIC-20250415-v1.25.0.bin +0 -0
  4. micrOS/micropython/esp32s3-4MBflash-20241129-v1.24.1.bin +0 -0
  5. micrOS/release_info/micrOS_ReleaseInfo/system_analysis_sum.json +57 -61
  6. micrOS/source/Common.py +286 -91
  7. micrOS/source/Config.py +7 -7
  8. micrOS/source/Debug.py +50 -94
  9. micrOS/source/Espnow.py +7 -7
  10. micrOS/source/Files.py +23 -2
  11. micrOS/source/Hooks.py +62 -19
  12. micrOS/source/IO_esp32c6.py +16 -0
  13. micrOS/source/IO_esp32s3.py +37 -1
  14. micrOS/source/IO_m5stamp.py +35 -1
  15. micrOS/source/IO_qtpy.py +22 -17
  16. micrOS/source/IO_s3matrix.py +21 -0
  17. micrOS/source/IO_tinypico.py +38 -0
  18. micrOS/source/InterConnect.py +5 -5
  19. micrOS/source/Interrupts.py +2 -2
  20. micrOS/source/LM_VL53L0X.py +1 -1
  21. micrOS/source/LM_buzzer.py +6 -7
  22. micrOS/source/LM_cct.py +6 -5
  23. micrOS/source/LM_dashboard_be.py +2 -2
  24. micrOS/source/LM_dimmer.py +6 -5
  25. micrOS/source/LM_espnow.py +15 -10
  26. micrOS/source/LM_i2c.py +3 -2
  27. micrOS/source/LM_neoeffects.py +173 -230
  28. micrOS/source/LM_neomatrix.py +335 -0
  29. micrOS/source/LM_neopixel.py +10 -10
  30. micrOS/source/LM_pacman.py +40 -23
  31. micrOS/source/LM_qmi8658.py +204 -0
  32. micrOS/source/LM_rgb.py +6 -6
  33. micrOS/source/LM_roboarm.py +5 -4
  34. micrOS/source/LM_switch.py +6 -4
  35. micrOS/source/LM_tcs3472.py +75 -0
  36. micrOS/source/LM_telegram.py +5 -4
  37. micrOS/source/Logger.py +47 -33
  38. micrOS/source/Network.py +6 -6
  39. micrOS/source/Notify.py +2 -2
  40. micrOS/source/Scheduler.py +5 -5
  41. micrOS/source/Server.py +6 -6
  42. micrOS/source/Shell.py +4 -4
  43. micrOS/source/Tasks.py +20 -17
  44. micrOS/source/Time.py +12 -10
  45. micrOS/source/Types.py +2 -2
  46. micrOS/source/Web.py +20 -13
  47. micrOS/source/__pycache__/Common.cpython-312.pyc +0 -0
  48. micrOS/source/__pycache__/Debug.cpython-312.pyc +0 -0
  49. micrOS/source/__pycache__/Logger.cpython-312.pyc +0 -0
  50. micrOS/source/__pycache__/Server.cpython-312.pyc +0 -0
  51. micrOS/source/micrOS.py +10 -7
  52. micrOS/source/micrOSloader.py +6 -6
  53. micrOS/source/microIO.py +8 -6
  54. micrOS/source/urequests.py +4 -4
  55. {microsdevtoolkit-2.10.6.dist-info → microsdevtoolkit-2.13.0.dist-info}/METADATA +24 -22
  56. {microsdevtoolkit-2.10.6.dist-info → microsdevtoolkit-2.13.0.dist-info}/RECORD +142 -132
  57. toolkit/DevEnvCompile.py +20 -15
  58. toolkit/DevEnvOTA.py +29 -8
  59. toolkit/DevEnvUSB.py +52 -10
  60. toolkit/LM_to_compile.dat +1 -0
  61. toolkit/MicrOSDevEnv.py +10 -2
  62. toolkit/MicrosFiles.py +26 -0
  63. toolkit/dashboard_apps/NeoEffectsDemo.py +8 -15
  64. toolkit/dashboard_apps/QMI8685_GYRO.py +68 -0
  65. toolkit/dashboard_apps/_app_base.py +2 -2
  66. toolkit/dashboard_apps/_gyro_visualizer.py +78 -0
  67. toolkit/lib/LocalMachine.py +6 -1
  68. toolkit/lib/file_extensions.py +9 -3
  69. toolkit/micrOSlint.py +3 -1
  70. toolkit/simulator_lib/__pycache__/IO_darwin.cpython-312.pyc +0 -0
  71. toolkit/simulator_lib/__pycache__/machine.cpython-312.pyc +0 -0
  72. toolkit/simulator_lib/__pycache__/neopixel.cpython-312.pyc +0 -0
  73. toolkit/simulator_lib/machine.py +0 -1
  74. toolkit/simulator_lib/neopixel.py +3 -2
  75. toolkit/socketClient.py +3 -2
  76. toolkit/workspace/precompiled/Common.cpython-312.pyc +0 -0
  77. toolkit/workspace/precompiled/Common.mpy +0 -0
  78. toolkit/workspace/precompiled/Config.mpy +0 -0
  79. toolkit/workspace/precompiled/Debug.mpy +0 -0
  80. toolkit/workspace/precompiled/Espnow.mpy +0 -0
  81. toolkit/workspace/precompiled/Files.mpy +0 -0
  82. toolkit/workspace/precompiled/Hooks.mpy +0 -0
  83. toolkit/workspace/precompiled/IO_esp32c6.mpy +0 -0
  84. toolkit/workspace/precompiled/IO_esp32s3.mpy +0 -0
  85. toolkit/workspace/precompiled/IO_m5stamp.mpy +0 -0
  86. toolkit/workspace/precompiled/IO_qtpy.mpy +0 -0
  87. toolkit/workspace/precompiled/IO_s3matrix.mpy +0 -0
  88. toolkit/workspace/precompiled/IO_tinypico.mpy +0 -0
  89. toolkit/workspace/precompiled/InterConnect.mpy +0 -0
  90. toolkit/workspace/precompiled/Interrupts.mpy +0 -0
  91. toolkit/workspace/precompiled/LM_VL53L0X.py +1 -1
  92. toolkit/workspace/precompiled/LM_buzzer.mpy +0 -0
  93. toolkit/workspace/precompiled/LM_cct.mpy +0 -0
  94. toolkit/workspace/precompiled/LM_dashboard_be.py +2 -2
  95. toolkit/workspace/precompiled/LM_dimmer.mpy +0 -0
  96. toolkit/workspace/precompiled/LM_espnow.py +15 -10
  97. toolkit/workspace/precompiled/LM_i2c.py +3 -2
  98. toolkit/workspace/precompiled/LM_neoeffects.mpy +0 -0
  99. toolkit/workspace/precompiled/LM_neomatrix.mpy +0 -0
  100. toolkit/workspace/precompiled/LM_neopixel.mpy +0 -0
  101. toolkit/workspace/precompiled/LM_pacman.mpy +0 -0
  102. toolkit/workspace/precompiled/LM_qmi8658.py +204 -0
  103. toolkit/workspace/precompiled/LM_rgb.mpy +0 -0
  104. toolkit/workspace/precompiled/LM_roboarm.mpy +0 -0
  105. toolkit/workspace/precompiled/LM_switch.mpy +0 -0
  106. toolkit/workspace/precompiled/LM_tcs3472.py +75 -0
  107. toolkit/workspace/precompiled/LM_telegram.mpy +0 -0
  108. toolkit/workspace/precompiled/Logger.cpython-312.pyc +0 -0
  109. toolkit/workspace/precompiled/Logger.mpy +0 -0
  110. toolkit/workspace/precompiled/Network.mpy +0 -0
  111. toolkit/workspace/precompiled/Notify.mpy +0 -0
  112. toolkit/workspace/precompiled/Scheduler.mpy +0 -0
  113. toolkit/workspace/precompiled/Server.cpython-312.pyc +0 -0
  114. toolkit/workspace/precompiled/Server.mpy +0 -0
  115. toolkit/workspace/precompiled/Shell.mpy +0 -0
  116. toolkit/workspace/precompiled/Tasks.mpy +0 -0
  117. toolkit/workspace/precompiled/Time.mpy +0 -0
  118. toolkit/workspace/precompiled/Types.mpy +0 -0
  119. toolkit/workspace/precompiled/Web.mpy +0 -0
  120. toolkit/workspace/precompiled/micrOS.mpy +0 -0
  121. toolkit/workspace/precompiled/micrOSloader.mpy +0 -0
  122. toolkit/workspace/precompiled/microIO.mpy +0 -0
  123. toolkit/workspace/precompiled/urequests.mpy +0 -0
  124. micrOS/micropython/esp32s3-20240105-v1.22.1.bin +0 -0
  125. micrOS/source/LM_catgame.py +0 -75
  126. micrOS/source/LM_demo.py +0 -97
  127. micrOS/source/LM_intercon.py +0 -60
  128. micrOS/source/LM_ph_sensor.py +0 -51
  129. toolkit/workspace/precompiled/LM_catgame.py +0 -75
  130. toolkit/workspace/precompiled/LM_demo.py +0 -97
  131. toolkit/workspace/precompiled/LM_intercon.mpy +0 -0
  132. toolkit/workspace/precompiled/LM_ph_sensor.py +0 -51
  133. /micrOS/micropython/{esp32s3-20241129-v1.24.1.bin → esp32s3-8MBflash-20241129-v1.24.1.bin} +0 -0
  134. /micrOS/source/{dashboard.html → web/dashboard.html} +0 -0
  135. /micrOS/source/{index.html → web/index.html} +0 -0
  136. /micrOS/source/{uapi.js → web/uapi.js} +0 -0
  137. /micrOS/source/{udashboard.js → web/udashboard.js} +0 -0
  138. /micrOS/source/{ustyle.css → web/ustyle.css} +0 -0
  139. /micrOS/source/{uwidgets.js → web/uwidgets.js} +0 -0
  140. /micrOS/source/{uwidgets_pro.js → web/uwidgets_pro.js} +0 -0
  141. {microsdevtoolkit-2.10.6.data → microsdevtoolkit-2.13.0.data}/scripts/devToolKit.py +0 -0
  142. {microsdevtoolkit-2.10.6.dist-info → microsdevtoolkit-2.13.0.dist-info}/WHEEL +0 -0
  143. {microsdevtoolkit-2.10.6.dist-info → microsdevtoolkit-2.13.0.dist-info}/licenses/LICENSE +0 -0
  144. {microsdevtoolkit-2.10.6.dist-info → microsdevtoolkit-2.13.0.dist-info}/top_level.txt +0 -0
  145. /toolkit/workspace/precompiled/{dashboard.html → web/dashboard.html} +0 -0
  146. /toolkit/workspace/precompiled/{index.html → web/index.html} +0 -0
  147. /toolkit/workspace/precompiled/{uapi.js → web/uapi.js} +0 -0
  148. /toolkit/workspace/precompiled/{udashboard.js → web/udashboard.js} +0 -0
  149. /toolkit/workspace/precompiled/{ustyle.css → web/ustyle.css} +0 -0
  150. /toolkit/workspace/precompiled/{uwidgets.js → web/uwidgets.js} +0 -0
  151. /toolkit/workspace/precompiled/{uwidgets_pro.js → web/uwidgets_pro.js} +0 -0
@@ -1,7 +1,7 @@
1
1
  from time import localtime
2
2
  from re import compile
3
3
  from Tasks import exec_lm_pipe_schedule
4
- from Debug import console_write, errlog_add
4
+ from Debug import console_write, syslog
5
5
  from Time import Sun, suntime, ntp_time
6
6
 
7
7
  """
@@ -101,7 +101,7 @@ def __resolve_time_tag(check_time, crontask):
101
101
  # Resolve tag
102
102
  value = Sun.TIME.get(tag, None)
103
103
  if value is None or len(value) < 3:
104
- errlog_add(f'[ERR] cron syntax error: {tag}:{value}')
104
+ syslog(f'[ERR] cron syntax error: {tag}:{value}')
105
105
  return ()
106
106
 
107
107
  # Update check_time with resolved value by tag
@@ -186,7 +186,7 @@ def __scheduler_trigger(cron_time_now, crontask, deltasec=2):
186
186
  console_write(f"[builtin cron] {crontask[1]()}")
187
187
  lm_state = True
188
188
  except Exception as e:
189
- errlog_add(f"[ERR] cron function exec error: {e}")
189
+ syslog(f"[ERR] cron function exec error: {e}")
190
190
  if not lm_state:
191
191
  console_write(f"[cron]now[{cron_time_now}] \
192
192
  {__convert_sec_to_time(tolerance_min_sec)} <-> {__convert_sec_to_time(tolerance_max_sec)} \
@@ -224,7 +224,7 @@ def deserialize_raw_input(cron_data):
224
224
  sep = ';;' if ';;' in cd else ';' # support multi command with ;;
225
225
  return (tuple(cron.split('!')) for cron in cd.split(sep))
226
226
  except Exception as e:
227
- errlog_add(f"[ERR] cron deserialize - syntax error: {e}")
227
+ syslog(f"[ERR] cron deserialize - syntax error: {e}")
228
228
  return ()
229
229
 
230
230
 
@@ -256,5 +256,5 @@ def scheduler(cron_data, irqperiod):
256
256
  state |= __scheduler_trigger(cron_time_now, cron, deltasec=irqperiod)
257
257
  return state
258
258
  except Exception as e:
259
- errlog_add(f'[ERR] cron callback error: {e}')
259
+ syslog(f'[ERR] cron callback error: {e}')
260
260
  return False
micrOS/source/Server.py CHANGED
@@ -13,7 +13,7 @@ Designed by Marcell Ban aka BxNxM GitHub
13
13
  import uasyncio as asyncio
14
14
  from utime import ticks_ms, ticks_diff
15
15
  from Config import cfgget
16
- from Debug import console_write, errlog_add
16
+ from Debug import console_write, syslog
17
17
  from Network import ifconfig
18
18
  from Tasks import Manager
19
19
  from Shell import Shell
@@ -99,7 +99,7 @@ class Client:
99
99
  except Exception as e:
100
100
  # Maintain ACTIVE_CLIS - remove closed connection by peer.
101
101
  await self.close()
102
- errlog_add(f"[WARN] Client.a_send (auto-drop) {self.client_id}: {e}")
102
+ syslog(f"[WARN] Client.a_send (auto-drop) {self.client_id}: {e}")
103
103
  return # Abort async send (no drain)
104
104
  # Send buffered data with async task - hacky
105
105
  try:
@@ -169,7 +169,7 @@ class WebCli(Client, WebEngine):
169
169
  break
170
170
  await self.response(request)
171
171
  except Exception as e:
172
- errlog_add(f"[ERR] Client.run_web: {e}")
172
+ syslog(f"[ERR] Client.run_web: {e}")
173
173
  break
174
174
  # Close connection
175
175
  await self.close()
@@ -211,7 +211,7 @@ class ShellCli(Client, Shell):
211
211
  except:
212
212
  # Maintain ACTIVE_CLIS - remove closed connection by peer.
213
213
  Client.drop_client(self.client_id)
214
- errlog_add(f"[WARN] ShellCli.send (auto-drop) {self.client_id}")
214
+ syslog(f"[WARN] ShellCli.send (auto-drop) {self.client_id}")
215
215
  # Send buffered data with async task - hacky
216
216
  if self.drain_event.is_set():
217
217
  self.drain_event.clear() # set drain busy (False)
@@ -261,12 +261,12 @@ class ShellCli(Client, Shell):
261
261
  # Shell -> True (OK) or False (NOK) -> NOK->Close session (auth Failed, etc.)
262
262
  _exit = not await self.shell(request)
263
263
  except Exception as e:
264
- errlog_add(f"[ERR] Shell client: {e}")
264
+ syslog(f"[ERR] Shell client: {e}")
265
265
  if "ECONNRESET" in str(e):
266
266
  _exit = True # exit_loop
267
267
  else:
268
268
  await self.a_send("[HA] Critical error - disconnect & hard reset")
269
- errlog_add("[ERR] Socket critical error - reboot")
269
+ syslog("[ERR] Socket critical error - reboot")
270
270
  await self.reboot()
271
271
  if _exit:
272
272
  collect()
micrOS/source/Shell.py CHANGED
@@ -16,7 +16,7 @@ from machine import reset as hard_reset, soft_reset
16
16
  from Config import cfgget, cfgput
17
17
  from Files import ilist_fs
18
18
  from Tasks import lm_exec
19
- from Debug import errlog_add
19
+ from Debug import syslog
20
20
 
21
21
 
22
22
  #################################################################
@@ -25,7 +25,7 @@ from Debug import errlog_add
25
25
 
26
26
  class Shell:
27
27
  __slots__ = ['__devfid', '__auth_mode', '__hwuid', '__auth_ok', '__conf_mode']
28
- MICROS_VERSION = '2.10.5-1'
28
+ MICROS_VERSION = '2.13.0-0'
29
29
 
30
30
  def __init__(self):
31
31
  """
@@ -43,7 +43,7 @@ class Shell:
43
43
  try:
44
44
  cfgput('version', Shell.MICROS_VERSION)
45
45
  except Exception as e:
46
- errlog_add(f"[ERR] micrOS version export failed (config): {e}")
46
+ syslog(f"[ERR] micrOS version export failed (config): {e}")
47
47
 
48
48
  async def a_send(self, msg):
49
49
  """ Must be defined by child class... """
@@ -306,5 +306,5 @@ class Shell:
306
306
  except Exception as e:
307
307
  _err_msg = f"[ERR] while starting webrepl: {e}"
308
308
  await msg_obj(_err_msg)
309
- errlog_add(_err_msg)
309
+ syslog(_err_msg)
310
310
  return True
micrOS/source/Tasks.py CHANGED
@@ -13,7 +13,7 @@ from json import dumps
13
13
  import uasyncio as asyncio
14
14
  from micropython import schedule
15
15
  from utime import ticks_ms, ticks_diff
16
- from Debug import console_write, errlog_add
16
+ from Debug import console_write, syslog
17
17
  from Config import cfgget
18
18
  from Network import sta_high_avail
19
19
 
@@ -75,12 +75,12 @@ class TaskBase:
75
75
  self.task.cancel() # Try to cancel task by asyncio
76
76
  except Exception as e:
77
77
  if "can't cancel self" != str(e):
78
- errlog_add(f"[WARN] IRQ Task cancel: {e}")
78
+ syslog(f"[WARN] IRQ Task cancel: {e}")
79
79
  self.__task_del()
80
80
  else:
81
81
  return False
82
82
  except Exception as e:
83
- errlog_add(f"[ERR] Task kill: {e}")
83
+ syslog(f"[ERR] Task kill: {e}")
84
84
  return False
85
85
  return True
86
86
 
@@ -98,16 +98,18 @@ class TaskBase:
98
98
  async def feed(sleep_ms=1):
99
99
  """
100
100
  Feed event loop
101
- :param sleep_ms: in millisecond (min: 1)
101
+ :param sleep_ms: in millisecond
102
102
  """
103
103
  # TODO: feed WDT - preemptive cooperative multitasking aka reboot if no feed until X time period
104
+ if sleep_ms <= 0:
105
+ return await asyncio.sleep(0.000_000_1) # 0 means: 100ns (Absolute minimum)
104
106
  return await asyncio.sleep_ms(sleep_ms)
105
107
 
106
108
  def __del__(self):
107
109
  try:
108
110
  self.__task_del(keep_cache=True)
109
111
  except Exception as e:
110
- errlog_add(f"[ERR] TaskBase.__del__: {e}")
112
+ syslog(f"[ERR] TaskBase.__del__: {e}")
111
113
 
112
114
 
113
115
  class NativeTask(TaskBase):
@@ -116,7 +118,7 @@ class NativeTask(TaskBase):
116
118
  - could be built in function or custom code from load modules
117
119
  """
118
120
 
119
- def create(self, callback=None, tag=None):
121
+ def create(self, callback:callable=None, tag:str=None) -> bool:
120
122
  """
121
123
  Create async task with coroutine callback (no queue limit check!)
122
124
  + async socket server task
@@ -166,7 +168,7 @@ class MagicTask(TaskBase):
166
168
  self.__inloop = False # [LM] Task while loop for LM callback
167
169
  self.__sleep = 20 # [LM] Task while loop - async wait (proc feed) [ms]
168
170
 
169
- def create(self, callback=None, loop=None, sleep=None):
171
+ def create(self, callback:list=None, loop:bool=None, sleep:int=None) -> bool:
170
172
  """
171
173
  Create async task with function callback (with queue limit check)
172
174
  - wrap (sync) function into async task (task_wrapper)
@@ -238,7 +240,7 @@ class Manager:
238
240
  cls.INSTANCE._initialized = False
239
241
  # Set async event loop exception handler
240
242
  asyncio.get_event_loop().set_exception_handler(lambda loop=None, context=None:
241
- errlog_add(f"[aio] exception: {loop}:{context}"))
243
+ syslog(f"[aio] exception: {loop}:{context}"))
242
244
  return cls.INSTANCE
243
245
 
244
246
  def __init__(self):
@@ -263,7 +265,7 @@ class Manager:
263
265
  """
264
266
  if Manager._queue_len() >= TaskBase.QUEUE_SIZE:
265
267
  msg = f"[aio] Task queue full: {TaskBase.QUEUE_SIZE}"
266
- errlog_add(msg)
268
+ syslog(msg)
267
269
  raise Exception(msg)
268
270
 
269
271
  async def idle_task(self):
@@ -291,15 +293,16 @@ class Manager:
291
293
  sta_high_avail()
292
294
  self.idle_counter += 1 # Increase counter
293
295
  except Exception as e:
294
- errlog_add(f"[ERR] Idle task exists: {e}")
296
+ syslog(f"[ERR] Idle task exists: {e}")
295
297
  my_task.done.set()
296
298
 
297
299
  @staticmethod
298
- def create_task(callback, tag=None, loop=False, delay=None):
300
+ def create_task(callback, tag:str=None, loop:bool=False, delay:int=None):
299
301
  """
300
302
  Primary interface
301
303
  Generic task creator method
302
304
  Create async Task with coroutine/list(lm call) callback
305
+ :param callback: list|callable
303
306
  """
304
307
  if isinstance(callback, list):
305
308
  # Check queue if task is Load Module
@@ -371,7 +374,7 @@ class Manager:
371
374
  try:
372
375
  return False if to_kill is None else to_kill.cancel()
373
376
  except Exception as e:
374
- errlog_add(f"[ERR] Task kill: {e}")
377
+ syslog(f"[ERR] Task kill: {e}")
375
378
  return False
376
379
 
377
380
  # Handle task group kill (module.*)
@@ -397,7 +400,7 @@ class Manager:
397
400
  try:
398
401
  asyncio.get_event_loop().run_forever()
399
402
  except Exception as e:
400
- errlog_add(f"[aio] loop stopped: {e}")
403
+ syslog(f"[aio] loop stopped: {e}")
401
404
  asyncio.get_event_loop().close()
402
405
 
403
406
  @staticmethod
@@ -438,7 +441,7 @@ def exec_builtins(func):
438
441
  out = Manager.INTERCON(host=intercon_target, cmd=arg_list)
439
442
  except Exception as e:
440
443
  out = {}
441
- errlog_add(f"[ERR] Intercon: {e}")
444
+ syslog(f"[ERR] Intercon: {e}")
442
445
  return True, out
443
446
 
444
447
  # MODULES
@@ -599,9 +602,9 @@ def exec_lm_pipe(taskstr):
599
602
  console_write(f"[SKIP] exec_lm_pipe: {' '.join(cmd)}")
600
603
  continue
601
604
  if not lm_exec(cmd)[0]:
602
- errlog_add(f"[WARN] exec_lm_pipe: {cmd}")
605
+ syslog(f"[WARN] exec_lm_pipe: {cmd}")
603
606
  except Exception as e:
604
- errlog_add(f"[ERR] exec_lm_pipe {taskstr}: {e}")
607
+ syslog(f"[ERR] exec_lm_pipe {taskstr}: {e}")
605
608
  return False
606
609
  return True
607
610
 
@@ -614,5 +617,5 @@ def exec_lm_pipe_schedule(taskstr):
614
617
  schedule(exec_lm_pipe, taskstr)
615
618
  return True
616
619
  except Exception as e:
617
- errlog_add(f"[ERR] exec_lm_pipe_schedule: {e}")
620
+ syslog(f"[ERR] exec_lm_pipe_schedule: {e}")
618
621
  return False
micrOS/source/Time.py CHANGED
@@ -14,14 +14,16 @@ from network import WLAN, STA_IF
14
14
  from utime import sleep_ms, time, mktime, localtime
15
15
 
16
16
  from Config import cfgput, cfgget
17
- from Debug import errlog_add, console_write
17
+ from Debug import syslog, console_write
18
18
  from urequests import get as http_get
19
+ from Files import OSPath, path_join
19
20
 
20
21
 
21
22
  class Sun:
22
23
  TIME = {}
23
24
  UTC = cfgget('utc') # STORED IN MINUTE
24
25
  BOOTIME = None # Initialize BOOTIME: Not SUN, but for system uptime
26
+ FILE_CACHE = path_join(OSPath.DATA, 'sun.cache')
25
27
 
26
28
 
27
29
  def set_time(year, month, mday, hour, minute, sec):
@@ -47,7 +49,7 @@ def ntp_time():
47
49
  :return: ntp date struct
48
50
  """
49
51
  if not WLAN(STA_IF).isconnected():
50
- errlog_add("STA not connected: ntptime")
52
+ syslog("[WARN] STA not connected: ntptime")
51
53
  return False
52
54
 
53
55
  def get_ntp():
@@ -83,28 +85,28 @@ def ntp_time():
83
85
  console_write(f"ntptime error.:{e}")
84
86
  err = e
85
87
  sleep_ms(100)
86
- errlog_add(f"[ERR] ntptime: {err}")
88
+ syslog(f"[ERR] ntptime: {err}")
87
89
  return False
88
90
 
89
91
 
90
92
  def __sun_cache(mode):
91
93
  """
92
- pds - persistent data structure
94
+ File cache
93
95
  modes:
94
96
  r - recover, s - save
95
97
  """
96
98
  if mode == 's':
97
99
  # SAVE CACHE
98
100
  try:
99
- with open('sun.pds', 'w') as f:
101
+ with open(Sun.FILE_CACHE, 'w') as f:
100
102
  cache = {k:tuple([str(t) for t in v]) for k, v in Sun.TIME.items()}
101
103
  f.write(';'.join([f'{k}:{"-".join(v)}' for k, v in cache.items()]))
102
104
  except:
103
- errlog_add("[ERR] Cannot write sun cache")
105
+ syslog("[ERR] Cannot write sun cache")
104
106
  return
105
107
  try:
106
108
  # RESTORE CACHE
107
- with open('sun.pds', 'r') as f:
109
+ with open(Sun.FILE_CACHE, 'r') as f:
108
110
  buff = {data.split(':')[0]: data.split(':')[1].split('-')
109
111
  for data in f.read().strip().split(';')}
110
112
  for k, v in buff.items():
@@ -139,7 +141,7 @@ def suntime():
139
141
  Sun.UTC = int(response.get('offset') / 60) # IN MINUTE
140
142
  cfgput('utc', Sun.UTC, True)
141
143
  except Exception as e:
142
- errlog_add(f'[ERR] ip-api: {e} data: {response}')
144
+ syslog(f'[ERR] ip-api: {e} data: {response}')
143
145
  return Sun.TIME
144
146
 
145
147
  # SUNSET-SUNRISE API REQUEST HANDLING
@@ -154,7 +156,7 @@ def suntime():
154
156
  sun = {'sunrise': time_regex.search(results.get('sunrise')).group(1).split(':'),
155
157
  'sunset': time_regex.search(results.get('sunset')).group(1).split(':')}
156
158
  except Exception as e:
157
- errlog_add(f'[ERR] sunrise-api: {e} data: {response}')
159
+ syslog(f'[ERR] sunrise-api: {e} data: {response}')
158
160
  # Try to parse response by expected sun_keys
159
161
  try:
160
162
  for key in sun:
@@ -162,7 +164,7 @@ def suntime():
162
164
  sun[key][0] += int(Sun.UTC / 60)
163
165
  sun[key] = tuple(sun[key])
164
166
  except Exception as e:
165
- errlog_add(f'sunrise-api parse error: {e} sun: {sun}')
167
+ syslog(f'[WARN] sunrise-api parse error: {e} sun: {sun}')
166
168
  # Retrieve cached data and return
167
169
  __sun_cache('r') # Using Sun.TIME
168
170
  console_write('[suntime] loaded from cache')
micrOS/source/Types.py CHANGED
@@ -12,7 +12,7 @@ USAGE:
12
12
  SLIDER brightness br=<0-100-5>
13
13
  """
14
14
  from json import dumps
15
- from Debug import errlog_add
15
+ from Debug import syslog
16
16
 
17
17
  ########################################################
18
18
  # HELP TUPLE RESOLVER #
@@ -90,7 +90,7 @@ def resolve(help_data, widgets=False):
90
90
  try:
91
91
  help_msg.append(_generate(resolved_tag, msg))
92
92
  except Exception as e:
93
- errlog_add(f"[ERR] resolve {tag} help msg: {e}")
93
+ syslog(f"[ERR] resolve {tag} help msg: {e}")
94
94
  continue
95
95
  help_msg.append(msg.replace(tag, '').strip())
96
96
  elif not widgets:
micrOS/source/Web.py CHANGED
@@ -15,8 +15,9 @@ Designed by Marcell Ban aka BxNxM
15
15
  from json import dumps, loads
16
16
  import uasyncio as asyncio
17
17
  from Tasks import lm_exec, NativeTask, lm_is_loaded
18
- from Debug import errlog_add, console_write
18
+ from Debug import syslog, console_write
19
19
  from Config import cfgget
20
+ from Files import OSPath, path_join
20
21
 
21
22
 
22
23
  class WebEngine:
@@ -27,6 +28,14 @@ class WebEngine:
27
28
  REQ200 = "HTTP/1.1 200 OK\r\nContent-Type: {dtype}\r\nContent-Length:{len}\r\n\r\n{data}"
28
29
  REQ400 = "HTTP/1.1 400 Bad Request\r\nContent-Type: text/plain\r\nContent-Length: {len}\r\n\r\n{data}"
29
30
  REQ404 = "HTTP/1.1 404 Not Found\r\nContent-Type: text/plain\r\nContent-Length: {len}\r\n\r\n{data}"
31
+ CONTENT_TYPES = {"html": "text/html",
32
+ "css": "text/css",
33
+ "js": "application/javascript",
34
+ "json": "application/json",
35
+ "ico": "image/x-icon", # favicon
36
+ "jpeg": "image/jpeg",
37
+ "png": "image/png",
38
+ "gif": "image/gif"}
30
39
 
31
40
  def __init__(self, client, version):
32
41
  self.client = client
@@ -35,14 +44,11 @@ class WebEngine:
35
44
  @staticmethod
36
45
  def file_type(path):
37
46
  """File dynamic Content-Type handling"""
38
- content_types = {".html": "text/html",
39
- ".css": "text/css",
40
- ".js": "application/javascript",
41
- ".jpeg": "image/jpeg"}
47
+ default_type = "text/plain"
42
48
  # Extract the file extension
43
49
  ext = path.rsplit('.', 1)[-1]
44
50
  # Return the content type based on the file extension
45
- return content_types.get(f".{ext}", "text/plain")
51
+ return WebEngine.CONTENT_TYPES.get(ext, default_type)
46
52
 
47
53
  async def response(self, request):
48
54
  """HTTP GET REQUEST - WEB INTERFACE"""
@@ -68,13 +74,14 @@ class WebEngine:
68
74
  # [3] HOME/PAGE ENDPOINT(s) [default: / -> /index.html]
69
75
  if url.startswith('/'):
70
76
  resource = 'index.html' if url == '/' else url.replace('/', '')
71
- self.client.console(f"[WebCli] --- {url} ACCEPT")
72
- if resource.split('.')[-1] not in ('html', 'js', 'css'):
77
+ web_resource = path_join(OSPath.WEB, resource) # Redirect path to web folder
78
+ self.client.console(f"[WebCli] --- {url} ACCEPT -> {web_resource}")
79
+ if resource.split('.')[-1] not in tuple(self.CONTENT_TYPES.keys()):
73
80
  await self.client.a_send(self.REQ404.format(len=27, data='404 Not supported file type'))
74
81
  return
75
82
  try:
76
- # SEND RESOURCE CONTENT: HTML, JS, CSS
77
- with open(resource, 'r') as file:
83
+ # SEND RESOURCE CONTENT: HTML, JS, CSS (WebEngine.CONTENT_TYPES)
84
+ with open(web_resource, 'r') as file:
78
85
  data = file.read()
79
86
  response = self.REQ200.format(dtype=WebEngine.file_type(resource), len=len(data), data=data)
80
87
  # Send entire response data
@@ -90,7 +97,7 @@ class WebEngine:
90
97
  # position += next_chunk_size
91
98
  except Exception as e:
92
99
  if 'memory allocation failed' in str(e):
93
- errlog_add(f"[ERR] WebCli {resource}: {e}")
100
+ syslog(f"[ERR] WebCli {resource}: {e}")
94
101
  await self.client.a_send(self.REQ404.format(len=13, data='404 Not Found'))
95
102
  return
96
103
  # INVALID/BAD REQUEST
@@ -98,7 +105,7 @@ class WebEngine:
98
105
 
99
106
  @staticmethod
100
107
  def rest(url):
101
- resp_schema = {'result': None, 'state': False}
108
+ resp_schema = {'result': {}, 'state': False}
102
109
  cmd = url.replace('/rest', '')
103
110
  if len(cmd) > 1:
104
111
  # REST sub-parameter handling (rest commands)
@@ -149,7 +156,7 @@ class WebEngine:
149
156
  await self.client.a_send(WebEngine.REQ200.format(dtype=dtype, len=len(data), data=data))
150
157
  except Exception as e:
151
158
  await self.client.a_send(self.REQ404.format(len=len(str(e)), data=e))
152
- errlog_add(f"[ERR] WebCli endpoints {url}: {e}")
159
+ syslog(f"[ERR] WebCli endpoints {url}: {e}")
153
160
  return True # Registered endpoint was found and executed
154
161
  return False # Not registered endpoint
155
162
 
micrOS/source/micrOS.py CHANGED
@@ -9,11 +9,11 @@ Designed by Marcell Ban aka BxNxM
9
9
  #################################################################
10
10
  from Time import ntp_time, suntime
11
11
  from Tasks import Manager
12
- from Hooks import bootup, profiling_info
12
+ from Hooks import bootup, profiling_info, enableESPNow
13
13
  from Network import auto_nw_config
14
14
  from Server import Server
15
15
  from Interrupts import enableInterrupt, enableCron, initEventIRQs
16
- from Debug import errlog_add
16
+ from Debug import syslog
17
17
 
18
18
 
19
19
  #################################################################
@@ -26,7 +26,7 @@ def irq_handler():
26
26
  enableCron()
27
27
  except Exception as e:
28
28
  print(f"[micrOS main] InterruptHandler.enableInterrupt/CronInterrupt error: {e}")
29
- errlog_add(f"[ERR] irq_handler error: {e}")
29
+ syslog(f"[ERR] irq_handler error: {e}")
30
30
 
31
31
 
32
32
  def external_irq_handler():
@@ -34,7 +34,7 @@ def external_irq_handler():
34
34
  initEventIRQs()
35
35
  except Exception as e:
36
36
  print(f"[micrOS main] InterruptHandler.initEventIRQs error: {e}")
37
- errlog_add(f"[ERR] external_irq_handler error: {e}")
37
+ syslog(f"[ERR] external_irq_handler error: {e}")
38
38
 
39
39
 
40
40
  #################################################################
@@ -53,7 +53,7 @@ def micrOS():
53
53
  bootup()
54
54
  except Exception as e:
55
55
  print(f"[micrOS main] Hooks.boot() error: {e}")
56
- errlog_add(f"[ERR] safe_boot: {e}")
56
+ syslog(f"[ERR] safe_boot: {e}")
57
57
 
58
58
  # NETWORK setup
59
59
  nwmd = auto_nw_config()
@@ -74,10 +74,13 @@ def micrOS():
74
74
 
75
75
  # [Server] as async task
76
76
  aio.create_task(Server().run_server(), tag='server')
77
- profiling_info(label='[memUsage] SYSTEM IS UP')
77
+
78
+ # [ESPNow] server as async task
79
+ enableESPNow()
80
+ profiling_info(label='[memUsage] SYSTEM IS UP AND RUNNING')
78
81
 
79
82
  # [EVENT LOOP] Start async event loop
80
83
  aio.run_forever()
81
84
 
82
85
  # UNEXPECTED RESTART ???
83
- errlog_add("[ERR] !!! Unexpected micrOS restart")
86
+ syslog("[ERR] !!! Unexpected micrOS restart")
@@ -12,10 +12,10 @@ try:
12
12
  except:
13
13
  traceback = None
14
14
  try:
15
- from Debug import errlog_add
15
+ from Debug import syslog
16
16
  except Exception as e:
17
17
  print(f"[loader] Import error: {e}")
18
- errlog_add = None
18
+ syslog = None
19
19
  from machine import reset
20
20
 
21
21
 
@@ -70,8 +70,8 @@ def __recovery_mode():
70
70
  import webrepl
71
71
  webrepl.start(password=pwd)
72
72
  except Exception as e:
73
- if callable(errlog_add):
74
- errlog_add(f"[ERR][micrOSloader] webrepl failed: {e}")
73
+ if callable(syslog):
74
+ syslog(f"[ERR][micrOSloader] webrepl failed: {e}")
75
75
  print("[loader] Reset .if_mode to micros and reboot")
76
76
  with open('.if_mode', 'w') as f:
77
77
  f.write("micros")
@@ -126,8 +126,8 @@ def main():
126
126
  # Handle micrOS system crash (never happened...but) -> webrepl mode default pwd: ADmin123
127
127
  print(f"[loader][main mode] micrOS start failed: {e}")
128
128
  print("[loader][main mode] -> [recovery mode]")
129
- if callable(errlog_add):
130
- errlog_add(f"[ERR][micrOSloader] start failed: {e}")
129
+ if callable(syslog):
130
+ syslog(f"[ERR][micrOSloader] start failed: {e}")
131
131
  # Recovery aka webrepl mode
132
132
  __recovery_mode()
133
133
  __auto_restart_event()
micrOS/source/microIO.py CHANGED
@@ -30,17 +30,19 @@ def detect_platform():
30
30
  """
31
31
  Unified platform detection for micrOS
32
32
  """
33
- if 'esp32' in platform:
33
+ if 'esp32' in platform: # esp32 family
34
34
  board = str(uname()[-1]).lower()
35
35
  if 'tinypico' in board:
36
- return 'tinypico' # esp32 family - tinypico
36
+ return 'tinypico'
37
37
  if 'esp32s2' in board:
38
- return 'esp32s2' # esp32 family - esp32S2
38
+ return 'esp32s2'
39
39
  if 'esp32s3' in board:
40
- return 'esp32s3' # esp32 family - esp32s3
40
+ return 'esp32s3'
41
41
  if 'esp32c3' in board:
42
- return 'esp32c3' # esp32 family - esp32c3
43
- return 'esp32' # esp32 family - general
42
+ return 'esp32c3'
43
+ if 'esp32c6' in board:
44
+ return 'esp32c6'
45
+ return 'esp32' # esp32 family: general
44
46
  return platform # esp8266 or something else
45
47
 
46
48
 
@@ -11,7 +11,7 @@ try:
11
11
  from ussl import wrap_socket # Legacy micropython ssl usage (+simulator mode)
12
12
  except ImportError:
13
13
  from ssl import wrap_socket # From micropython 1.23...
14
- from Debug import errlog_add
14
+ from Debug import syslog
15
15
  import uasyncio as asyncio
16
16
 
17
17
 
@@ -147,7 +147,7 @@ def request(method:str, url:str, data:str=None, json=None, headers:dict=None, so
147
147
  try:
148
148
  sock = wrap_socket(sock) if proto == 'https:' else sock
149
149
  except Exception as e:
150
- errlog_add(f'[ERR] https soc-wrap: {e}')
150
+ syslog(f'[ERR] https soc-wrap: {e}')
151
151
 
152
152
  # [1] BUILD REQUEST
153
153
  http_request = _build_request(host, method, path, headers, data, json)
@@ -206,7 +206,7 @@ async def arequest(method:str, url:str, data:str=None, json=None, headers:dict=N
206
206
  addr = _host_to_addr(host, port, force=True)
207
207
  reader, writer = await asyncio.open_connection(addr[0], port, ssl=(proto == 'https:'))
208
208
  else:
209
- errlog_add(f"[ERR] arequest connection: {e}")
209
+ syslog(f"[ERR] arequest connection: {e}")
210
210
 
211
211
  # Send request + Wait for the response
212
212
  try:
@@ -236,7 +236,7 @@ async def arequest(method:str, url:str, data:str=None, json=None, headers:dict=N
236
236
  body = f"[WARN] arequest: {e}"
237
237
  else:
238
238
  body = f"[ERR] arequest: {e}"
239
- errlog_add(body)
239
+ syslog(body)
240
240
  finally:
241
241
  if writer:
242
242
  writer.close()