micrOSDevToolKit 2.10.5__py3-none-any.whl → 2.11.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 (110) 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 +47 -51
  6. micrOS/source/Common.py +262 -87
  7. micrOS/source/Debug.py +44 -88
  8. micrOS/source/Espnow.py +1 -1
  9. micrOS/source/Files.py +21 -2
  10. micrOS/source/Hooks.py +60 -17
  11. micrOS/source/IO_esp32c6.py +16 -0
  12. micrOS/source/IO_esp32s3.py +37 -1
  13. micrOS/source/IO_m5stamp.py +35 -1
  14. micrOS/source/IO_qtpy.py +22 -17
  15. micrOS/source/IO_s3matrix.py +21 -0
  16. micrOS/source/IO_tinypico.py +38 -0
  17. micrOS/source/LM_VL53L0X.py +1 -1
  18. micrOS/source/LM_buzzer.py +6 -7
  19. micrOS/source/LM_cct.py +6 -5
  20. micrOS/source/LM_dimmer.py +6 -5
  21. micrOS/source/LM_espnow.py +15 -10
  22. micrOS/source/LM_i2c.py +3 -2
  23. micrOS/source/LM_neoeffects.py +173 -230
  24. micrOS/source/LM_neomatrix.py +305 -0
  25. micrOS/source/LM_neopixel.py +10 -10
  26. micrOS/source/LM_oled_ui.py +18 -5
  27. micrOS/source/LM_pacman.py +25 -21
  28. micrOS/source/LM_qmi8658.py +204 -0
  29. micrOS/source/LM_rest.py +3 -3
  30. micrOS/source/LM_rgb.py +6 -6
  31. micrOS/source/LM_roboarm.py +5 -4
  32. micrOS/source/LM_switch.py +6 -4
  33. micrOS/source/LM_tcs3472.py +75 -0
  34. micrOS/source/LM_telegram.py +5 -4
  35. micrOS/source/Logger.py +46 -32
  36. micrOS/source/Shell.py +11 -10
  37. micrOS/source/Tasks.py +7 -4
  38. micrOS/source/Time.py +5 -3
  39. micrOS/source/__pycache__/Common.cpython-312.pyc +0 -0
  40. micrOS/source/__pycache__/Logger.cpython-312.pyc +0 -0
  41. micrOS/source/micrOS.py +5 -2
  42. micrOS/source/microIO.py +8 -6
  43. {microsdevtoolkit-2.10.5.dist-info → microsdevtoolkit-2.11.0.dist-info}/METADATA +2 -1
  44. {microsdevtoolkit-2.10.5.dist-info → microsdevtoolkit-2.11.0.dist-info}/RECORD +101 -96
  45. toolkit/DevEnvUSB.py +5 -0
  46. toolkit/Gateway.py +3 -3
  47. toolkit/LM_to_compile.dat +1 -0
  48. toolkit/dashboard_apps/NeoEffectsDemo.py +8 -15
  49. toolkit/dashboard_apps/QMI8685_GYRO.py +68 -0
  50. toolkit/dashboard_apps/_app_base.py +2 -2
  51. toolkit/dashboard_apps/_gyro_visualizer.py +78 -0
  52. toolkit/simulator_lib/__pycache__/IO_darwin.cpython-312.pyc +0 -0
  53. toolkit/simulator_lib/__pycache__/machine.cpython-312.pyc +0 -0
  54. toolkit/simulator_lib/__pycache__/neopixel.cpython-312.pyc +0 -0
  55. toolkit/simulator_lib/__pycache__/sim_console.cpython-312.pyc +0 -0
  56. toolkit/simulator_lib/machine.py +0 -1
  57. toolkit/simulator_lib/neopixel.py +3 -2
  58. toolkit/socketClient.py +3 -2
  59. toolkit/user_data/webhooks/generic.py +1 -1
  60. toolkit/user_data/webhooks/macro.py +1 -1
  61. toolkit/user_data/webhooks/template.py +1 -1
  62. toolkit/workspace/precompiled/Common.mpy +0 -0
  63. toolkit/workspace/precompiled/Debug.mpy +0 -0
  64. toolkit/workspace/precompiled/Espnow.mpy +0 -0
  65. toolkit/workspace/precompiled/Files.mpy +0 -0
  66. toolkit/workspace/precompiled/Hooks.mpy +0 -0
  67. toolkit/workspace/precompiled/IO_esp32c6.mpy +0 -0
  68. toolkit/workspace/precompiled/IO_esp32s3.mpy +0 -0
  69. toolkit/workspace/precompiled/IO_m5stamp.mpy +0 -0
  70. toolkit/workspace/precompiled/IO_qtpy.mpy +0 -0
  71. toolkit/workspace/precompiled/IO_s3matrix.mpy +0 -0
  72. toolkit/workspace/precompiled/IO_tinypico.mpy +0 -0
  73. toolkit/workspace/precompiled/LM_VL53L0X.py +1 -1
  74. toolkit/workspace/precompiled/LM_buzzer.mpy +0 -0
  75. toolkit/workspace/precompiled/LM_cct.mpy +0 -0
  76. toolkit/workspace/precompiled/LM_dimmer.mpy +0 -0
  77. toolkit/workspace/precompiled/LM_espnow.py +15 -10
  78. toolkit/workspace/precompiled/LM_i2c.py +3 -2
  79. toolkit/workspace/precompiled/LM_neoeffects.mpy +0 -0
  80. toolkit/workspace/precompiled/LM_neomatrix.mpy +0 -0
  81. toolkit/workspace/precompiled/LM_neopixel.mpy +0 -0
  82. toolkit/workspace/precompiled/LM_oled_ui.mpy +0 -0
  83. toolkit/workspace/precompiled/LM_pacman.mpy +0 -0
  84. toolkit/workspace/precompiled/LM_qmi8658.py +204 -0
  85. toolkit/workspace/precompiled/LM_rest.mpy +0 -0
  86. toolkit/workspace/precompiled/LM_rgb.mpy +0 -0
  87. toolkit/workspace/precompiled/LM_roboarm.mpy +0 -0
  88. toolkit/workspace/precompiled/LM_switch.mpy +0 -0
  89. toolkit/workspace/precompiled/LM_tcs3472.py +75 -0
  90. toolkit/workspace/precompiled/LM_telegram.mpy +0 -0
  91. toolkit/workspace/precompiled/Logger.mpy +0 -0
  92. toolkit/workspace/precompiled/Shell.mpy +0 -0
  93. toolkit/workspace/precompiled/Tasks.mpy +0 -0
  94. toolkit/workspace/precompiled/Time.mpy +0 -0
  95. toolkit/workspace/precompiled/micrOS.mpy +0 -0
  96. toolkit/workspace/precompiled/microIO.mpy +0 -0
  97. micrOS/micropython/esp32s3-20240105-v1.22.1.bin +0 -0
  98. micrOS/source/LM_catgame.py +0 -75
  99. micrOS/source/LM_demo.py +0 -97
  100. micrOS/source/LM_intercon.py +0 -60
  101. micrOS/source/LM_ph_sensor.py +0 -51
  102. toolkit/workspace/precompiled/LM_catgame.py +0 -75
  103. toolkit/workspace/precompiled/LM_demo.py +0 -97
  104. toolkit/workspace/precompiled/LM_intercon.mpy +0 -0
  105. toolkit/workspace/precompiled/LM_ph_sensor.py +0 -51
  106. /micrOS/micropython/{esp32s3-20241129-v1.24.1.bin → esp32s3-8MBflash-20241129-v1.24.1.bin} +0 -0
  107. {microsdevtoolkit-2.10.5.data → microsdevtoolkit-2.11.0.data}/scripts/devToolKit.py +0 -0
  108. {microsdevtoolkit-2.10.5.dist-info → microsdevtoolkit-2.11.0.dist-info}/WHEEL +0 -0
  109. {microsdevtoolkit-2.10.5.dist-info → microsdevtoolkit-2.11.0.dist-info}/licenses/LICENSE +0 -0
  110. {microsdevtoolkit-2.10.5.dist-info → microsdevtoolkit-2.11.0.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  from sys import platform
2
2
  from microIO import bind_pin, pinmap_search
3
- from Common import transition_gen, micro_task
3
+ from Common import transition_gen, micro_task, data_dir
4
4
  from utime import sleep_ms
5
5
  from Types import resolve
6
6
 
@@ -15,6 +15,7 @@ class Data:
15
15
  PERSISTENT_CACHE = False
16
16
  DIMM_TASK_TAG = "dimmer._tran"
17
17
  TASK_STATE = False
18
+ FILE_CACHE = data_dir('dimmer.cache')
18
19
 
19
20
 
20
21
  #########################################
@@ -34,7 +35,7 @@ def __dimmer_init():
34
35
 
35
36
  def __persistent_cache_manager(mode='r'):
36
37
  """
37
- pds - persistent data structure
38
+ File cache
38
39
  modes:
39
40
  r - recover, s - save
40
41
  """
@@ -42,12 +43,12 @@ def __persistent_cache_manager(mode='r'):
42
43
  return
43
44
  if mode == 's':
44
45
  # SAVE CACHE
45
- with open('dimmer.pds', 'w') as f:
46
+ with open(Data.FILE_CACHE, 'w') as f:
46
47
  f.write(','.join([str(k) for k in Data.DIMMER_CACHE]))
47
48
  return
48
49
  try:
49
50
  # RESTORE CACHE
50
- with open('dimmer.pds', 'r') as f:
51
+ with open(Data.FILE_CACHE, 'r') as f:
51
52
  Data.DIMMER_CACHE = [int(data) for data in f.read().strip().split(',')]
52
53
  except:
53
54
  pass
@@ -71,7 +72,7 @@ def load(cache=None):
71
72
  """
72
73
  Initialize dimmer module
73
74
  :param cache bool: file state machine cache: True/False/None(default: automatic True)
74
- - Load .pds (state machine cache) for this load module
75
+ - Load .cache (state machine cache) for this load module
75
76
  - Apply loaded states to gpio pins (boot function)
76
77
  :return str: Cache state
77
78
  """
@@ -2,10 +2,24 @@ import Espnow
2
2
 
3
3
  def load():
4
4
  """
5
- Initialize ESPNOW protocal
5
+ OBSOLETE - remove
6
+ [DEBUG ONLY] ENABLE ESPNOW IN NODE CONFIG INSTEAD OF HERE!
7
+ Initialize ESPNOW protocal
6
8
  """
7
9
  return Espnow.initialize()
8
10
 
11
+ def start_server():
12
+ """
13
+ OBSOLETE - remove
14
+ [DEBUG ONLY] ENABLE ESPNOW IN NODE CONFIG INSTEAD OF HERE!
15
+ Start ESPNOW server/listener
16
+ - this can receive espnow messages
17
+ - it includes Load Module execution logic (beta)
18
+ """
19
+ now = Espnow.initialize()
20
+ return now.start_server()
21
+
22
+
9
23
  def send(peer:bytes|str, msg:str='modules'):
10
24
  """
11
25
  Send message to peer (by mac address)
@@ -15,15 +29,6 @@ def send(peer:bytes|str, msg:str='modules'):
15
29
  now = Espnow.initialize()
16
30
  return now.send(peer, msg)
17
31
 
18
- def start_server():
19
- """
20
- Start ESPNOW server/listener
21
- - this can receive espnow messages
22
- - it includes Load Module execution logic (beta)
23
- """
24
- now = Espnow.initialize()
25
- return now.start_server()
26
-
27
32
  def stats():
28
33
  """
29
34
  Get ESPNOW stats
micrOS/source/LM_i2c.py CHANGED
@@ -24,8 +24,9 @@ def discover():
24
24
  """
25
25
  Discover devices
26
26
  """
27
- known_addresses = {hex(0x0A): "trackball", hex(0x3c): "oled",
28
- hex(0x76): "bme280", hex(0x10): 'veml7700'}
27
+ known_addresses = {hex(0x0A): "TRACKBALL", hex(0x3c): "OLED",
28
+ hex(0x76): "BME280", hex(0x10): 'VEML7700',
29
+ hex(0x6b): "QMI8658"}
29
30
  devices = scan()
30
31
  output = {"unknown": []}
31
32
  for k in devices:
@@ -1,167 +1,107 @@
1
- from LM_neopixel import load, segment, Data, status, pinmap as pm
1
+ from LM_neopixel import load as neoload, segment, Data, status, pinmap as pm
2
2
  from random import randint
3
3
  from Types import resolve
4
- from Common import manage_task
4
+ from Common import manage_task, AnimationPlayer
5
5
 
6
6
 
7
7
  #################################
8
8
  # NEOPIXEL EFFECT DRAWER CLASS #
9
9
  #################################
10
10
 
11
- class DrawEffect:
12
- __instance = None
13
-
14
- def __new__(cls, pixcnt=24):
15
- if DrawEffect.__instance is None:
16
- DrawEffect.__instance = super().__new__(cls)
17
- DrawEffect.__instance.pix_cnt = None
18
- DrawEffect.__instance.index_offset = 0
19
- DrawEffect.__instance.color_wheel = 0
20
- DrawEffect.__instance.__init_effect(pixcnt)
21
- DrawEffect.__instance.offset_gen = None
22
- DrawEffect.__instance.auto_shift = False
23
- return DrawEffect.__instance
24
-
25
- def __init_effect(cls, ledcnt):
26
- """
27
- Set neopixel object & store pixel cnt
28
- """
29
- if Data.NEOPIXEL_OBJ is None:
30
- load(ledcnt=ledcnt)
31
- cls.pix_cnt = Data.NEOPIXEL_OBJ.n
32
- if cls.pix_cnt is None:
33
- cls.pix_cnt = Data.NEOPIXEL_OBJ.n
34
- return cls.pix_cnt
35
-
36
- def __offset(cls, shift):
37
- def _gen():
38
- while True:
39
- if cls.auto_shift:
40
- # Step rotation cycle - shift True
41
- cls.index_offset += 1
42
- if cls.index_offset > cls.pix_cnt - 1:
43
- cls.index_offset = 0
44
- for k in range(cls.index_offset, cls.pix_cnt):
45
- yield k
46
- for k in range(0, cls.index_offset):
47
- yield k
48
- cls.auto_shift = shift
49
- if cls.offset_gen is None:
50
- cls.offset_gen = _gen()
51
- return cls.offset_gen
52
-
53
- def draw(cls, iterable, shift=False):
54
- """
55
- DRAW GENERATED COLORS (RGB)
56
- HELPER FUNCTION with auto shift (offset) sub function
57
- :param iterable: Colors generator object / iterable
58
- :param shift: automatic color map rotation
59
- :return: None
60
- """
61
- offset_gen = cls.__offset(shift=shift)
62
- r, g, b, i = 0, 0, 0, 0
63
- for r, g, b in iterable:
64
- # Handle index offset - rotate effect
65
- i = next(offset_gen)
66
- # Write data to neopixel - write / segment :)
67
- segment(int(r), int(g), int(b), s=i, cache=False, write=False)
68
- segment(int(r), int(g), int(b), s=i, cache=False, write=True)
69
- return True
70
-
71
-
72
- def __color_input(r, g, b):
73
- _r, _g, _b, _ = Data.DCACHE
74
- r = _r if r is None else r
75
- g = _g if g is None else g
76
- b = _b if b is None else b
77
- return r, g, b
78
-
79
-
80
- #################################
81
- # DEFINE EFFECTS #
82
- #################################
83
-
84
- def meteor(r=None, g=None, b=None, shift=True, ledcnt=24):
11
+ class DrawEffectV2(AnimationPlayer):
12
+ INSTANCE = None
13
+
14
+ def __init__(self, pix_cnt=24):
15
+ super().__init__(tag="neoeffects")
16
+ neoload(ledcnt=pix_cnt)
17
+ DrawEffectV2.INSTANCE = self
18
+
19
+ @staticmethod
20
+ def normalize_index(value) -> int:
21
+ return value % Data.NEOPIXEL_OBJ.n
22
+
23
+ @staticmethod
24
+ def color_code(r:int=None, g:int=None, b:int=None) -> tuple[float, float, float]:
25
+ _r, _g, _b, _ = Data.DCACHE
26
+ r = _r if r is None else r
27
+ g = _g if g is None else g
28
+ b = _b if b is None else b
29
+ return r, g, b
30
+
31
+ def update(self, index:int, r:int|float, g:int|float, b:int|float):
32
+ # Animation player will call this method to update pixels.
33
+ segment(r=int(r), g=int(g), b=int(b), s=index, cache=False, write=False)
34
+
35
+ def draw(self):
36
+ # Animation player will call this method to update pixels.
37
+ Data.NEOPIXEL_OBJ.write()
38
+
39
+ def clear(self):
40
+ # Animation player will call this method to update pixels.
41
+ for i in range(0, Data.NEOPIXEL_OBJ.n):
42
+ self.update(i, 0, 0, 0)
43
+ self.draw()
44
+
45
+ ##################################################################################
46
+ # EFFECTS #
47
+ ##################################################################################
48
+
49
+ def meteor(speed_ms:int=60, shift:bool=True, batch:bool=True):
85
50
  """
86
51
  Meteor effect
87
- :param r int: red value 0-1000
88
- :param g int: green value 0-1000
89
- :param b int: blue value 0-1000
90
- :param shift bool: automatic effect shifting
91
- :param ledcnt int: number of neopixel elements in chain (default: 24)
52
+ :param speed_ms: animation speed in milliseconds
53
+ :param shift: automatic effect rotation
54
+ :param batch: batch mode
92
55
  :return str: verdict
93
56
  """
94
- def __effect(r, g, b, pixel):
57
+ def effect_meteor():
95
58
  """
96
59
  Describe one full length color map
97
- :param r: red target color
98
- :param g: green target color
99
- :param b: blue target color
100
- :param pixel: number of led segments
101
60
  :return: yield tuple with r,g,b
102
61
  """
103
- step = float(0.9 / pixel)
104
- for k in range(0, pixel):
105
- fade = (k+1) * step
106
- data = round(r * fade), round(g * fade), round(b * fade)
107
- yield data
62
+ nonlocal shift, pix_cnt
63
+ max_offset = pix_cnt if shift else 1
64
+ for offset in range(0, max_offset):
65
+ r, g, b = DrawEffectV2.color_code()
66
+ for pixel in range(0, pix_cnt):
67
+ br, norm = 0.6, pixel/pix_cnt
68
+ fade = br * norm ** 0.9 # exponent < 1 simulates log-like curve
69
+ yield DrawEffectV2.normalize_index(pixel+offset), r*fade, g*fade, b*fade
108
70
 
109
- # Conditional value load - with neopixel cache
110
- r, g, b = __color_input(r, g, b)
111
-
112
- # Init custom params
113
- effect = DrawEffect(pixcnt=ledcnt)
114
- # Create effect data
115
- cgen = __effect(r, g, b, effect.pix_cnt)
116
- # Draw effect data
117
- effect.draw(cgen, shift=shift)
118
- return 'Meteor R{}:G{}:B{} N:{}'.format(r, g, b, effect.pix_cnt)
71
+ neoeffect = load()
72
+ pix_cnt = Data.NEOPIXEL_OBJ.n
73
+ return neoeffect.play(effect_meteor, speed_ms=speed_ms, bt_draw=batch, bt_size=pix_cnt)
119
74
 
120
75
 
121
- def cycle(r=None, g=None, b=None, shift=True, ledcnt=24):
76
+ def cycle(speed_ms:int=60, shift:bool=True, batch:bool=True):
122
77
  """
123
78
  Cycle effect
124
- :param r int: red value 0-1000
125
- :param g int: green value 0-1000
126
- :param b int: blue value 0-1000
127
- :param shift bool: automatic effect shifting
128
- :param ledcnt int: number of neopixel elements in chain (default: 24)
129
- :return str: verdict
79
+ :param speed_ms: animation speed in milliseconds
80
+ :param shift: automatic effect rotation
81
+ :param batch: enable/disable batch update mode
130
82
  """
131
- def __effect(r, g, b, pixel):
83
+ def effect_cycle():
132
84
  """
133
85
  Describe one full length color map
134
- :param r: red target color
135
- :param g: green target color
136
- :param b: blue target color
137
- :param pixel: number of led segments
138
- :return: yield tuple with r,g,b
86
+ :return: yield tuple with index, r,g,b
139
87
  """
140
- lightrgb = round(r*0.1), round(g*0.1), round(b*0.1)
141
- yield lightrgb
142
- yield r, g, b
143
- yield lightrgb
144
- for i in range(3, pixel):
145
- yield 0, 0, 0
146
-
147
- # Conditional value load - with neopixel cache
148
- r, g, b = __color_input(r, g, b)
149
-
150
- effect = DrawEffect(pixcnt=ledcnt)
151
- cgen = __effect(r, g, b, effect.pix_cnt)
152
- effect.draw(cgen, shift=shift)
153
- return 'Cycle R{}:G{}:B{} N:{}'.format(r, g, b, effect.pix_cnt)
154
-
155
-
156
- def rainbow(step=1, br=50, ledcnt=24):
157
- """
158
- Rainbow effect
159
- :param step int: color weel resolution in step (default: 1)
160
- :param br int: brightness in percentage
161
- :param ledcnt int: number of neopixel elements in chain (default: 24)
162
- :return str: verdict
163
- """
164
- def __wheel(pos):
88
+ nonlocal shift
89
+ max_offset = Data.NEOPIXEL_OBJ.n if shift else 1
90
+ for offset in range(0, max_offset):
91
+ r, g, b = DrawEffectV2.color_code()
92
+ lr, lg, lb = int(r * 0.1), int(g * 0.1), int(b * 0.1)
93
+ # Clean last pixel
94
+ yield DrawEffectV2.normalize_index(offset-1), 0, 0, 0
95
+ # Draw pattern
96
+ yield DrawEffectV2.normalize_index(offset), lr, lg, lb
97
+ yield DrawEffectV2.normalize_index(offset + 1), r, g, b
98
+ yield DrawEffectV2.normalize_index(offset + 2), lr, lg, lb
99
+
100
+ return load().play(effect_cycle, speed_ms=speed_ms, bt_draw=batch, bt_size=4)
101
+
102
+
103
+ def rainbow(speed_ms=20, br=15, batch=True):
104
+ def _wheel(pos):
165
105
  # Input a value 0 to 255 to get a color value.
166
106
  # The colours are a transition r - g - b - back to r.
167
107
  if pos < 0 or pos > 255:
@@ -174,59 +114,84 @@ def rainbow(step=1, br=50, ledcnt=24):
174
114
  pos -= 170
175
115
  return pos * 3, 0, 255 - pos * 3
176
116
 
177
- def __effect(cnt, step, br):
117
+ def effect_rainbow():
178
118
  """
179
119
  :param cnt: led segment count
180
120
  :param br: max brightness 0-100%
181
121
  :param step: step size
182
122
  """
183
- cw = DrawEffect().color_wheel
184
- DrawEffect().color_wheel = 0 if cw >= 255 else cw+step
185
- for i in range(0, cnt):
186
- rc_index = (i * 256 // cnt) + DrawEffect().color_wheel
187
- r, g, b = __wheel(rc_index & 255)
188
- yield round(r*br*0.01), round(g*br*0.01), round(b*br*0.01)
123
+ nonlocal pix_cnt, br
124
+ color_step = 3
125
+ for color_wheel in range(0, 255, color_step):
126
+ for index in range(0, pix_cnt):
127
+ rc_index = (index * 256 // pix_cnt) + color_wheel
128
+ r, g, b = _wheel(rc_index & 255)
129
+ yield DrawEffectV2.normalize_index(index+color_wheel), round(r*br*0.01), round(g*br*0.01), round(b*br*0.01)
189
130
 
190
- effect = DrawEffect(pixcnt=ledcnt)
191
- cgen = __effect(effect.pix_cnt, step=step, br=br)
192
- effect.draw(cgen, shift=True)
193
- return 'Rainbow'
131
+ neoeffect = load()
132
+ pix_cnt = Data.NEOPIXEL_OBJ.n
133
+ return neoeffect.play(effect_rainbow, speed_ms=speed_ms, bt_draw=batch, bt_size=pix_cnt)
194
134
 
195
135
 
196
- def shader(size=6, offset=0, shift=False, ledcnt=24):
136
+ def fire(speed_ms:int=150, br:int=30, batch:bool=True):
197
137
  """
198
- Shader for ring lamp
199
- :param size int: shader size (disabled LEDs)
200
- :param offset int: rotate shader 0-(ledcnt-1)
201
- :param shift bool: auto shift shader effect (False)
202
- :param ledcnt int: number of neopixel elements in chain (default: 24)
203
- :return str: verdict
138
+ Fire effect
139
+ :param speed_ms: animation speed in milliseconds
140
+ :param br: max brightness 0-100%
141
+ :param batch: batch update
204
142
  """
205
- def __effect(size, offset, pixcnt):
143
+ def effect_fire():
144
+ nonlocal pix_cnt, br
145
+ max_value = int(255 * (br/100))
146
+ for index in range(pix_cnt):
147
+ r, g, b = DrawEffectV2.color_code()
148
+ rand_percent = float(round(randint(1, max_value)/max_value, 2))
149
+ new_r = min(max(int(r * rand_percent), 0), max_value)
150
+ new_g = min(max(int(g * rand_percent), 0), max_value)
151
+ new_b = min(max(int(b * rand_percent), 0), max_value)
152
+ yield index, new_r, new_g, new_b
153
+
154
+ neoeffect = load()
155
+ pix_cnt = Data.NEOPIXEL_OBJ.n
156
+ return neoeffect.play(effect_fire, speed_ms=speed_ms, bt_draw=batch, bt_size=pix_cnt)
157
+
158
+
159
+ def shader(offset=0, size=6):
160
+ def effect_shader():
161
+ nonlocal size, offset, neoeffect
162
+ pix_cnt = Data.NEOPIXEL_OBJ.n
206
163
  # Conditional value load - with neopixel cache
207
- r, g, b, _ = Data.DCACHE
164
+ r, g, b = DrawEffectV2.color_code()
208
165
  # calculate 0->24 range
209
- _slice1 = pixcnt if size + offset > pixcnt else size + offset
166
+ _slice1 = pix_cnt if size + offset > pix_cnt else size + offset
210
167
  # calculate 24->0-> range (overflow)
211
- _slice2 = size + offset - pixcnt if size + offset > pixcnt else 0
212
- for i in range(0, pixcnt):
213
- if offset < i < _slice1:
214
- yield 0, 0, 0
215
- elif 0 <= i < _slice2:
216
- yield 0, 0, 0
168
+ _slice2 = size + offset - pix_cnt if size + offset > pix_cnt else 0
169
+ for i in range(0, pix_cnt):
170
+ if offset <= i < _slice1 or 0 <= i < _slice2:
171
+ neoeffect.update(i, 0, 0, 0)
217
172
  else:
218
- yield r, g, b
173
+ neoeffect.update(i, r, g, b)
174
+ neoeffect.draw()
219
175
 
220
- # Init custom params
221
- effect = DrawEffect(pixcnt=ledcnt)
222
- # Create effect data
223
- if size < effect.pix_cnt:
224
- cgen = __effect(size, offset, effect.pix_cnt)
225
- # Draw effect data
226
- effect.index_offset = 0 # reset auto shift offset
227
- effect.draw(cgen, shift=shift)
228
- return 'Shader size: {} ->{} ({})'.format(size, offset, effect.pix_cnt)
229
- return 'Shader invalid size: {} ({})'.format(size, effect.pix_cnt)
176
+ neoeffect = load()
177
+ effect_shader()
178
+ return "Shader was set."
179
+
180
+
181
+ def color(r:int=None, g:int=None, b:int=None):
182
+ """
183
+ Set color buffer - for runtime effect color change
184
+ :param r: red channel 0-255 (default: None - cached value)
185
+ :param g: green channel 0-255 (default: None - cached value)
186
+ :param b: blue channel 0-255 (default: None - cached value)
187
+ :return dict: rgb status - states: R, G, B, S
188
+ """
189
+ # Conditional value load - with neopixel cache
190
+ r, g, b = DrawEffectV2.color_code(r, g, b)
191
+ Data.DCACHE[0] = r
192
+ Data.DCACHE[1] = g
193
+ Data.DCACHE[2] = b
194
+ return status()
230
195
 
231
196
 
232
197
  def random(max_val=255):
@@ -244,55 +209,30 @@ def random(max_val=255):
244
209
  return "Set random: R:{} G: B:{}".format(r, g, b)
245
210
 
246
211
 
247
- def color(r=None, g=None, b=None):
212
+ def stop():
248
213
  """
249
- Set color buffer - for runtime effect color change
250
- :param r int: red channel 0-255 (default: None - cached value)
251
- :param g int: green channel 0-255 (default: None - cached value)
252
- :param b int: blue channel 0-255 (default: None - cached value)
253
- :return dict: rgb status - states: R, G, B, S
214
+ Stop all running (neo)effects tasks
254
215
  """
255
- # Conditional value load - with neopixel cache
256
- r, g, b = __color_input(r, g, b)
257
- Data.DCACHE[0] = r
258
- Data.DCACHE[1] = g
259
- Data.DCACHE[2] = b
260
- return status()
261
-
262
-
263
- def fire(r=None, g=None, b=None, ledcnt=24):
264
-
265
- def __effect(r, g, b, pixcnt):
266
- for _ in range(pixcnt):
267
- rand_percent = round(randint(1, 200)/100, 2)
268
-
269
- rgb = [
270
- r * rand_percent,
271
- g * rand_percent,
272
- b * rand_percent
273
- ]
216
+ player_info = load().stop()
217
+ random_task = manage_task("neoeffects.random", "kill")
218
+ return f"{player_info}\n{random_task}"
274
219
 
275
- for i, color in enumerate(rgb):
276
- if color > 255:
277
- rgb[i] = 255
278
- if color < 0:
279
- rgb[i] = 0
280
- yield rgb
281
-
282
- # Conditional value load - with neopixel cache
283
- r, g, b = __color_input(r, g, b)
284
-
285
- effect = DrawEffect(pixcnt=ledcnt)
286
- cgen = __effect(r, g, b, effect.pix_cnt)
287
- effect.draw(cgen, shift=False)
288
- return 'fire R{}:G{}:B{} N:{}'.format(r, g, b, effect.pix_cnt)
220
+ def control(speed_ms=None, batch:bool=None):
221
+ """
222
+ Change the speed of frame generation for animations.
223
+ """
224
+ data = load().control(play_speed_ms=speed_ms, bt_draw=batch)
225
+ _speed_ms = data.get("player_speed", None)
226
+ return f"Control state: {data} (speed: {_speed_ms}ms)"
289
227
 
290
228
 
291
- def stop_effects():
229
+ def load(pixel_cnt=24):
292
230
  """
293
- Stop all running (neo)effects tasks
231
+ Load LM_neopixel and DrawEffectV2
294
232
  """
295
- return manage_task("neoeffects.*", "kill")
233
+ if DrawEffectV2.INSTANCE is None:
234
+ DrawEffectV2(pix_cnt=pixel_cnt)
235
+ return DrawEffectV2.INSTANCE
296
236
 
297
237
  #######################
298
238
  # LM helper functions #
@@ -316,16 +256,19 @@ def help(widgets=False):
316
256
  (widgets=False) list of functions implemented by this application
317
257
  (widgets=True) list of widget json for UI generation
318
258
  """
319
- return resolve(('meteor r=<0-255> g=<0-255> b=<0-255> shift=True ledcnt=24',
320
- 'BUTTON meteor &&',
321
- 'cycle r g b shift=True ledcnt=24',
322
- 'BUTTON cycle &&50',
323
- 'rainbow step=1 br=<5-100> ledcnt=24 &&',
324
- 'BUTTON rainbow br=50 &&',
325
- 'fire r=None g=None b=None ledcnt=24',
326
- 'BUTTON fire &&200',
327
- 'BUTTON stop_effects',
328
- 'shader size=4 offset=0 shift=True ledcnt=24',
259
+ return resolve(('load pixel_cnt=24',
260
+ 'meteor speed_ms=60 shift=True batch=True',
261
+ 'BUTTON meteor speed_ms=60',
262
+ 'cycle speed_ms=60 shift=True batch=True',
263
+ 'BUTTON cycle speed_ms=60',
264
+ 'rainbow speed_ms=20 br=15 batch=True',
265
+ 'BUTTON rainbow',
266
+ 'fire speed_ms=150 br=30 batch=True',
267
+ 'BUTTON fire speed_ms=150',
268
+ 'BUTTON stop',
269
+ 'shader offset=0 size=6',
270
+ 'control speed_ms=None batch=None',
329
271
  'random max_val=255',
330
272
  'pinmap',
331
- 'COLOR color r=<0-255-10> g b'), widgets=widgets)
273
+ 'COLOR color r=<0-255-10> g b'
274
+ ), widgets=widgets)