micrOSDevToolKit 2.17.2__py3-none-any.whl → 2.20.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 (73) hide show
  1. micrOS/release_info/micrOS_ReleaseInfo/system_analysis_sum.json +29 -33
  2. micrOS/source/Common.py +5 -13
  3. micrOS/source/Config.py +2 -2
  4. micrOS/source/Espnow.py +32 -18
  5. micrOS/source/InterConnect.py +106 -31
  6. micrOS/source/Server.py +2 -3
  7. micrOS/source/Shell.py +1 -1
  8. micrOS/source/Tasks.py +66 -62
  9. micrOS/source/micrOSloader.py +1 -1
  10. micrOS/source/modules/LM_buzzer.py +1 -4
  11. micrOS/source/modules/LM_cct.py +2 -4
  12. micrOS/source/modules/LM_dimmer.py +1 -2
  13. micrOS/source/modules/LM_distance.py +1 -3
  14. micrOS/source/modules/LM_espnow.py +18 -1
  15. micrOS/source/modules/LM_i2s_mic.py +1 -2
  16. micrOS/source/modules/LM_keychain.py +1 -2
  17. micrOS/source/modules/LM_light_sensor.py +1 -4
  18. micrOS/source/modules/LM_mqtt_client.py +13 -10
  19. micrOS/source/modules/LM_neoeffects.py +1 -1
  20. micrOS/source/modules/LM_neomatrix.py +1 -1
  21. micrOS/source/modules/LM_neopixel.py +1 -2
  22. micrOS/source/modules/LM_oled_ui.py +4 -3
  23. micrOS/source/modules/LM_oledui.py +6 -7
  24. micrOS/source/modules/LM_presence.py +1 -2
  25. micrOS/source/modules/LM_rest.py +1 -2
  26. micrOS/source/modules/LM_rgb.py +1 -2
  27. micrOS/source/modules/LM_roboarm.py +3 -4
  28. micrOS/source/modules/LM_robustness.py +1 -2
  29. micrOS/source/modules/LM_tcs3472.py +131 -17
  30. micrOS/source/modules/LM_telegram.py +17 -18
  31. {microsdevtoolkit-2.17.2.dist-info → microsdevtoolkit-2.20.0.dist-info}/METADATA +151 -215
  32. {microsdevtoolkit-2.17.2.dist-info → microsdevtoolkit-2.20.0.dist-info}/RECORD +69 -73
  33. toolkit/Gateway.py +1 -1
  34. toolkit/dashboard_apps/SystemTest.py +39 -32
  35. toolkit/micrOSdashboard.py +8 -13
  36. toolkit/socketClient.py +27 -7
  37. toolkit/workspace/precompiled/Common.mpy +0 -0
  38. toolkit/workspace/precompiled/Config.mpy +0 -0
  39. toolkit/workspace/precompiled/Espnow.mpy +0 -0
  40. toolkit/workspace/precompiled/InterConnect.mpy +0 -0
  41. toolkit/workspace/precompiled/Server.mpy +0 -0
  42. toolkit/workspace/precompiled/Shell.mpy +0 -0
  43. toolkit/workspace/precompiled/Tasks.mpy +0 -0
  44. toolkit/workspace/precompiled/micrOSloader.mpy +0 -0
  45. toolkit/workspace/precompiled/modules/LM_buzzer.mpy +0 -0
  46. toolkit/workspace/precompiled/modules/LM_cct.mpy +0 -0
  47. toolkit/workspace/precompiled/modules/LM_dimmer.mpy +0 -0
  48. toolkit/workspace/precompiled/modules/LM_distance.mpy +0 -0
  49. toolkit/workspace/precompiled/modules/LM_espnow.py +18 -1
  50. toolkit/workspace/precompiled/modules/LM_i2s_mic.mpy +0 -0
  51. toolkit/workspace/precompiled/modules/LM_keychain.mpy +0 -0
  52. toolkit/workspace/precompiled/modules/LM_light_sensor.mpy +0 -0
  53. toolkit/workspace/precompiled/modules/LM_mqtt_client.mpy +0 -0
  54. toolkit/workspace/precompiled/modules/LM_neoeffects.mpy +0 -0
  55. toolkit/workspace/precompiled/modules/LM_neomatrix.mpy +0 -0
  56. toolkit/workspace/precompiled/modules/LM_neopixel.mpy +0 -0
  57. toolkit/workspace/precompiled/modules/LM_oled_ui.mpy +0 -0
  58. toolkit/workspace/precompiled/modules/LM_oledui.mpy +0 -0
  59. toolkit/workspace/precompiled/modules/LM_presence.mpy +0 -0
  60. toolkit/workspace/precompiled/modules/LM_rest.mpy +0 -0
  61. toolkit/workspace/precompiled/modules/LM_rgb.mpy +0 -0
  62. toolkit/workspace/precompiled/modules/LM_roboarm.mpy +0 -0
  63. toolkit/workspace/precompiled/modules/LM_robustness.py +1 -2
  64. toolkit/workspace/precompiled/modules/LM_tcs3472.py +131 -17
  65. toolkit/workspace/precompiled/modules/LM_telegram.mpy +0 -0
  66. micrOS/micropython/esp32s2-LOLIN_MINI-20220618-v1.19.1.bin +0 -0
  67. micrOS/micropython/esp32s3_spiram_oct-20231005-v1.21.0.bin +0 -0
  68. micrOS/source/modules/LM_pet_feeder.py +0 -78
  69. toolkit/workspace/precompiled/modules/LM_pet_feeder.py +0 -78
  70. {microsdevtoolkit-2.17.2.data → microsdevtoolkit-2.20.0.data}/scripts/devToolKit.py +0 -0
  71. {microsdevtoolkit-2.17.2.dist-info → microsdevtoolkit-2.20.0.dist-info}/WHEEL +0 -0
  72. {microsdevtoolkit-2.17.2.dist-info → microsdevtoolkit-2.20.0.dist-info}/licenses/LICENSE +0 -0
  73. {microsdevtoolkit-2.17.2.dist-info → microsdevtoolkit-2.20.0.dist-info}/top_level.txt +0 -0
@@ -17,6 +17,13 @@ def stats():
17
17
  return ESPNOW.stats()
18
18
 
19
19
 
20
+ def members():
21
+ """
22
+ Get ESPNow devices
23
+ """
24
+ return ESPNOW.members()
25
+
26
+
20
27
  def handshake(peer:bytes|str):
21
28
  """
22
29
  Handshake with ESPNow Peer
@@ -27,10 +34,20 @@ def handshake(peer:bytes|str):
27
34
  return ESPNOW.handshake(peer)
28
35
 
29
36
 
37
+ def remove(peer:bytes):
38
+ """
39
+ Remove peer by binary mac address
40
+ :param peer: binary mac address of espnow device
41
+ """
42
+ return ESPNOW.remove_peer(peer)
43
+
44
+
30
45
  def help():
31
46
  """
32
47
  ESPNOW sender/receiver with LM execution
33
48
  """
34
49
  return ('handshake peer=<mac-address>',
35
50
  'send peer=<peer-name> cmd="hello"',
36
- 'stats')
51
+ 'remove peer=<binary-mac-address>',
52
+ 'stats',
53
+ 'members')
@@ -83,8 +83,7 @@ def create_task():
83
83
  """
84
84
  # [!] ASYNC TASK CREATION [1*] with async task callback + taskID (TAG) handling
85
85
  task_tag = "microtask.run"
86
- state = micro_task(tag=task_tag, task=__task(tag=task_tag, period_ms=5))
87
- return "Starting" if state else "Already running"
86
+ return micro_task(tag=task_tag, task=__task(tag=task_tag, period_ms=5))
88
87
 
89
88
 
90
89
  @micro_task("microtask", _wrap=True)
@@ -6,26 +6,54 @@ Copyright (c) 2021 tti0
6
6
  Licensed under the MIT License
7
7
  """
8
8
 
9
- from machine import I2C, Pin
9
+ from struct import unpack
10
+ from time import sleep
11
+ from machine import I2C, Pin, PWM
10
12
  from microIO import bind_pin, pinmap_search
11
- import struct
13
+ from Types import resolve
12
14
 
15
+ from LM_neopixel import load as neo_load, color as neo_color, toggle as neo_toggle # local neopixel light indicator
16
+ from LM_cluster import run as cluster_run # DEMO: neomatrix cluster
17
+
18
+ CURRENT_ANIMATION_INDEX = 0 # DEMO: neomatrix cluster animation
13
19
 
14
20
  class TCS3472:
15
21
  INSTANCE = None
16
22
 
17
- def __init__(self, bus, address=0x29):
18
- self._bus = bus
23
+ def __init__(self, address=0x29, led_pin=None):
24
+ self._bus = I2C(sda=Pin(bind_pin('i2c_sda')), scl=Pin(bind_pin('i2c_scl')))
19
25
  self._i2c_address = address
20
26
  self._bus.writeto(self._i2c_address, b'\x80\x03')
21
27
  self._bus.writeto(self._i2c_address, b'\x81\x2b')
28
+ self.led = PWM(Pin(bind_pin('led', led_pin), Pin.OUT), freq=20480)
29
+ self.led_brightness = 20
22
30
  TCS3472.INSTANCE = self
23
31
 
24
- def scaled(self):
25
- crgb = self.raw()
26
- if crgb[0] > 0:
27
- return tuple(float(x) / crgb[0] for x in crgb[1:])
28
- return 0, 0, 0
32
+ def scaled(self, saturation=1.5):
33
+ """
34
+ Normalize by strongest color, then adjust saturation.
35
+ saturation = 1.0 -> normal
36
+ saturation > 1.0 -> more vibrant
37
+ saturation < 1.0 -> more pastel
38
+ """
39
+ _, r, g, b = self.raw()
40
+ m = max(r, g, b)
41
+ if m == 0:
42
+ return 0.0, 0.0, 0.0
43
+
44
+ # Normalize by strongest channel
45
+ r, g, b = r / m, g / m, b / m
46
+
47
+ # Grayscale = average of channels
48
+ gray = (r + g + b) / 3
49
+
50
+ # Interpolate between gray and color
51
+ r = gray + (r - gray) * saturation
52
+ g = gray + (g - gray) * saturation
53
+ b = gray + (b - gray) * saturation
54
+
55
+ # Clamp to 0..1
56
+ return max(0, min(1, r)), max(0, min(1, g)), max(0, min(1, b))
29
57
 
30
58
  def rgb(self):
31
59
  return tuple(int(x * 255) for x in self.scaled())
@@ -42,32 +70,118 @@ class TCS3472:
42
70
 
43
71
  def raw(self):
44
72
  self._bus.writeto(self._i2c_address, b'\xb4')
45
- return struct.unpack("<HHHH", self._bus.readfrom(self._i2c_address, 8))
73
+ return unpack("<HHHH", self._bus.readfrom(self._i2c_address, 8))
46
74
 
47
75
 
48
76
  ############################ Exposed functions ############################
49
77
 
50
- def load():
78
+ def load(led_pin=20):
51
79
  """
52
80
  Load the TCS3472 Color sensor instance.
53
81
  """
54
82
  if TCS3472.INSTANCE is None:
55
- bus = I2C(sda=Pin(bind_pin('i2c_sda')), scl=Pin(bind_pin('i2c_scl')))
56
- TCS3472.INSTANCE = TCS3472(bus)
83
+ TCS3472(led_pin=led_pin)
84
+ neo_load(ledcnt=1)
85
+ led(False)
57
86
  return TCS3472.INSTANCE
58
87
 
59
88
 
60
89
  def pinmap():
61
- return pinmap_search(['i2c_scl', 'i2c_sda'])
90
+ """
91
+ Show used pin mapping for this module.
92
+ """
93
+ return pinmap_search(['i2c_scl', 'i2c_sda', 'led'])
62
94
 
63
95
 
64
96
  def measure():
97
+ """
98
+ MEASURE sensor
99
+ """
100
+ sensor = load()
101
+ measurement = {"rgb": sensor.rgb(), "light": sensor.light(), "brightness": sensor.brightness()}
102
+ return measurement
103
+
104
+
105
+ def led(state:bool=None, br:int=None):
106
+ """
107
+ SENSOR LED toggle
108
+ :param state: None-automatic, True-ON, False-OFF
109
+ :param br: brightness 0-100
110
+ """
111
+ def _set_duty(_br):
112
+ _br = sensor.led_brightness if _br is None else _br
113
+ sensor.led.duty(int(_br * 10))
114
+ if _br != 0:
115
+ sensor.led_brightness = _br
116
+
65
117
  sensor = load()
66
- return {"rgb": sensor.rgb(), "light": sensor.light(), "brightness": sensor.brightness()}
118
+ if state is None:
119
+ # INVERT STATE
120
+ led_current_state = sensor.led.duty() > 0
121
+ if led_current_state:
122
+ _set_duty(br)
123
+ _set_duty(0)
124
+ neo_toggle(False)
125
+ else:
126
+ _set_duty(br)
127
+ neo_toggle(True)
128
+ else:
129
+ # SET STATE: ON/OFF
130
+ if state:
131
+ _set_duty(br)
132
+ neo_toggle(True)
133
+ else:
134
+ _set_duty(br)
135
+ _set_duty(0)
136
+ neo_toggle(False)
137
+ return f"LED on, {sensor.led_brightness}%" if sensor.led.duty()>0 else f"LED off"
138
+
139
+
140
+ def indicator(br=5):
141
+ """
142
+ Color indicator Neopixel LED update
143
+ :param br: brightness 0-100
144
+ """
145
+ r, g, b = measure()['rgb']
146
+ br = float(br / 100)
147
+ _r, _g, _b = int(r*br), int(g*br), int(b*br)
148
+ neo_color(_r, _g, _b, smooth=False)
149
+ return r, g, b
150
+
151
+
152
+ def neomatrix_update():
153
+ """
154
+ DEMO - Send color codes for all neomatrix devices over espnow cluster
155
+ """
156
+ r, g, b = indicator()
157
+ command = f"neomatrix color_fill {r} {g} {b}"
158
+ cluster_run(command)
159
+ return {"cmd": command, "cluster": "task show con.espnow.*"}
160
+
161
+
162
+ def neomatrix_animation():
163
+ """
164
+ DEMO - Set random animation on neomatrix espnow cluster
165
+ """
166
+ global CURRENT_ANIMATION_INDEX
167
+ animations = ('spiral', 'snake', 'noise')
168
+
169
+ next_animation = CURRENT_ANIMATION_INDEX + 1
170
+ CURRENT_ANIMATION_INDEX = 0 if next_animation >= len(animations) else next_animation
171
+ command = f"neomatrix {animations[CURRENT_ANIMATION_INDEX]}"
172
+ cluster_run(command)
173
+ return {"cmd": command, "cluster": "task show con.espnow.*"}
67
174
 
68
175
 
69
- def help(widgest=False):
176
+ def help(widgets=False):
70
177
  """
71
178
  TCS3472 Color sensor
72
179
  """
73
- return 'load', 'measure'
180
+ return resolve(('load led_pin=20',
181
+ 'TEXTBOX measure',
182
+ 'BUTTON led state=<True,False>',
183
+ 'SLIDER led state=True br=<0-100-5>',
184
+ 'indicator br=<0-100>',
185
+ 'BUTTON neomatrix_update',
186
+ 'BUTTON neomatrix_animation',
187
+ 'pinmap'), widgets=widgets)
@@ -1,78 +0,0 @@
1
- from LM_servo import sduty, deinit, pinmap as servo_pinmap
2
- from LM_stepper import step, pinmap as stepper_pinmap
3
- from Common import micro_task
4
-
5
-
6
- class Data:
7
- TASK_TAG = "pet_feeder.portion"
8
-
9
-
10
- async def __portion_task(portion, posmin, posmax):
11
- # ASYNC TASK ADAPTER [*2] with automatic state management
12
- # [micro_task->Task] TaskManager access to task internals (out, done attributes)
13
- with micro_task(tag=Data.TASK_TAG) as my_task:
14
- for p in range(0, portion):
15
- # [1]Run pos fill up
16
- for pos in range(posmin, posmax):
17
- sduty(pos)
18
- await my_task.feed(sleep_ms=15)
19
- # [2]Wait between fill up / food out
20
- await my_task.feed(sleep_ms=500)
21
- # [3]Run pos food out
22
- for pos in range(posmax, posmin, -1):
23
- sduty(pos)
24
- await my_task.feed(sleep_ms=20)
25
- my_task.out = "{}/{} serving".format(p+1, portion)
26
- deinit()
27
- my_task.out += ": {} task done".format(Data.TASK_TAG)
28
-
29
-
30
- def serve(portion=1, posmin=65, posmax=97):
31
- """
32
- Pet feeder - with servo motor
33
- :param portion: number of portions (min/max positions to repeat)
34
- :param posmin: servo "start" position
35
- :param posmax: servo "stop" position
36
- """
37
- # [!] ASYNC TASK CREATION [1*] with async task callback + taskID (TAG) handling
38
- state = micro_task(tag=Data.TASK_TAG, task=__portion_task(portion=portion, posmin=posmin, posmax=posmax))
39
- return "Starting" if state else "Already running"
40
-
41
-
42
- def serve_w_stepper(portion=1, forward=135, back=10):
43
- """
44
- Pet feeder (beta) - with stepper motor
45
- :param count: number of portions
46
- :param forward: s
47
- :param back:
48
- """
49
- for _ in range(portion):
50
- # portion move
51
- step(forward)
52
- # Safety anti-block solution?
53
- step(-back)
54
- step(back)
55
- step(-back)
56
- step(back)
57
-
58
-
59
- def pinmap():
60
- """
61
- [i] micrOS LM naming convention
62
- Shows logical pins - pin number(s) used by this Load module
63
- - info which pins to use for this application
64
- :return dict: pin name (str) - pin value (int) pairs
65
- """
66
- p = servo_pinmap()
67
- p.update(stepper_pinmap())
68
- return p
69
-
70
-
71
- def help(widgets=False):
72
- """
73
- [i] micrOS LM naming convention - built-in help message
74
- :return tuple:
75
- (widgets=False) list of functions implemented by this application
76
- (widgets=True) list of widget json for UI generation
77
- """
78
- return 'serve portion=1 \t\t[info] servo control', 'serve_w_stepper portion=1 \t[info] stepper control'
@@ -1,78 +0,0 @@
1
- from LM_servo import sduty, deinit, pinmap as servo_pinmap
2
- from LM_stepper import step, pinmap as stepper_pinmap
3
- from Common import micro_task
4
-
5
-
6
- class Data:
7
- TASK_TAG = "pet_feeder.portion"
8
-
9
-
10
- async def __portion_task(portion, posmin, posmax):
11
- # ASYNC TASK ADAPTER [*2] with automatic state management
12
- # [micro_task->Task] TaskManager access to task internals (out, done attributes)
13
- with micro_task(tag=Data.TASK_TAG) as my_task:
14
- for p in range(0, portion):
15
- # [1]Run pos fill up
16
- for pos in range(posmin, posmax):
17
- sduty(pos)
18
- await my_task.feed(sleep_ms=15)
19
- # [2]Wait between fill up / food out
20
- await my_task.feed(sleep_ms=500)
21
- # [3]Run pos food out
22
- for pos in range(posmax, posmin, -1):
23
- sduty(pos)
24
- await my_task.feed(sleep_ms=20)
25
- my_task.out = "{}/{} serving".format(p+1, portion)
26
- deinit()
27
- my_task.out += ": {} task done".format(Data.TASK_TAG)
28
-
29
-
30
- def serve(portion=1, posmin=65, posmax=97):
31
- """
32
- Pet feeder - with servo motor
33
- :param portion: number of portions (min/max positions to repeat)
34
- :param posmin: servo "start" position
35
- :param posmax: servo "stop" position
36
- """
37
- # [!] ASYNC TASK CREATION [1*] with async task callback + taskID (TAG) handling
38
- state = micro_task(tag=Data.TASK_TAG, task=__portion_task(portion=portion, posmin=posmin, posmax=posmax))
39
- return "Starting" if state else "Already running"
40
-
41
-
42
- def serve_w_stepper(portion=1, forward=135, back=10):
43
- """
44
- Pet feeder (beta) - with stepper motor
45
- :param count: number of portions
46
- :param forward: s
47
- :param back:
48
- """
49
- for _ in range(portion):
50
- # portion move
51
- step(forward)
52
- # Safety anti-block solution?
53
- step(-back)
54
- step(back)
55
- step(-back)
56
- step(back)
57
-
58
-
59
- def pinmap():
60
- """
61
- [i] micrOS LM naming convention
62
- Shows logical pins - pin number(s) used by this Load module
63
- - info which pins to use for this application
64
- :return dict: pin name (str) - pin value (int) pairs
65
- """
66
- p = servo_pinmap()
67
- p.update(stepper_pinmap())
68
- return p
69
-
70
-
71
- def help(widgets=False):
72
- """
73
- [i] micrOS LM naming convention - built-in help message
74
- :return tuple:
75
- (widgets=False) list of functions implemented by this application
76
- (widgets=True) list of widget json for UI generation
77
- """
78
- return 'serve portion=1 \t\t[info] servo control', 'serve_w_stepper portion=1 \t[info] stepper control'