scirodev 0.2.1__tar.gz → 0.3.1__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scirodev
3
- Version: 0.2.1
3
+ Version: 0.3.1
4
4
  Summary: PeakHub / sciro extensions to Pybricks: typed API stubs (sciro.*) and hub tooling on top of pybricksdev
5
5
  Author: Thomas Schank
6
6
  License: MIT
@@ -41,7 +41,7 @@ Then your IDE/type checker knows these, which the upstream `pybricks` stubs don'
41
41
  ```python
42
42
  from sciro.parameters import Port # Port.A .. Port.H (PeakHub has 8 ports)
43
43
  from sciro.iodevices import PUMPDevice # generic PUMP device access
44
- from sciro.floorpro import FloorPro # LP-FloorPro convenience class
44
+ from sciro.pump import FloorPro # PUMP devices (LP-FloorPro, ...)
45
45
  from sciro.hubs import PeakHub # hub class incl. display.device()
46
46
 
47
47
  hub = PeakHub()
@@ -50,6 +50,10 @@ cog_dark, cog_bright, brightness, darkness, mask, calibrating = fp.line.read()
50
50
  hub.display.device(fp, brightness=50) # mirror the sensor's LED strip on the 5x5
51
51
  ```
52
52
 
53
+ Full demo programs for the LP FloorPro (both for LEGO hubs and the PeakHub) live in
54
+ [sciurus-robotics/FloorPro-CodeDemos](https://github.com/sciurus-robotics/FloorPro-CodeDemos);
55
+ `examples/` here stays minimal.
56
+
53
57
  On the hub these modules are frozen into the PeakHub firmware:
54
58
  `sciro.parameters` and `sciro.iodevices` re-export the same runtime objects as
55
59
  their `pybricks.*` counterparts, so `sciro.parameters.Port is
@@ -21,7 +21,7 @@ Then your IDE/type checker knows these, which the upstream `pybricks` stubs don'
21
21
  ```python
22
22
  from sciro.parameters import Port # Port.A .. Port.H (PeakHub has 8 ports)
23
23
  from sciro.iodevices import PUMPDevice # generic PUMP device access
24
- from sciro.floorpro import FloorPro # LP-FloorPro convenience class
24
+ from sciro.pump import FloorPro # PUMP devices (LP-FloorPro, ...)
25
25
  from sciro.hubs import PeakHub # hub class incl. display.device()
26
26
 
27
27
  hub = PeakHub()
@@ -30,6 +30,10 @@ cog_dark, cog_bright, brightness, darkness, mask, calibrating = fp.line.read()
30
30
  hub.display.device(fp, brightness=50) # mirror the sensor's LED strip on the 5x5
31
31
  ```
32
32
 
33
+ Full demo programs for the LP FloorPro (both for LEGO hubs and the PeakHub) live in
34
+ [sciurus-robotics/FloorPro-CodeDemos](https://github.com/sciurus-robotics/FloorPro-CodeDemos);
35
+ `examples/` here stays minimal.
36
+
33
37
  On the hub these modules are frozen into the PeakHub firmware:
34
38
  `sciro.parameters` and `sciro.iodevices` re-export the same runtime objects as
35
39
  their `pybricks.*` counterparts, so `sciro.parameters.Port is
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "scirodev"
7
- version = "0.2.1"
7
+ version = "0.3.1"
8
8
  description = "PeakHub / sciro extensions to Pybricks: typed API stubs (sciro.*) and hub tooling on top of pybricksdev"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -2,5 +2,5 @@
2
2
 
3
3
  These are typing stubs (like the `pybricks` package): the real modules are frozen
4
4
  into the PeakHub firmware. Import from `sciro.parameters`, `sciro.iodevices` and
5
- `sciro.floorpro`.
5
+ `sciro.pump`.
6
6
  """
@@ -0,0 +1,13 @@
1
+ """sciro.floorpro -- deprecated alias of :mod:`sciro.pump` (where the FloorPro
2
+ class lives now). Kept so older programs keep type-checking.
3
+ """
4
+
5
+ from .pump import ( # noqa: F401 (re-exports)
6
+ IMU as IMU,
7
+ ColorSensor as ColorSensor,
8
+ FloorPro as FloorPro,
9
+ IRCalib as IRCalib,
10
+ IRRaw as IRRaw,
11
+ Line as Line,
12
+ Pixels as Pixels,
13
+ )
@@ -38,7 +38,7 @@ class LightMatrix(_common.LightMatrix):
38
38
  the program ends.
39
39
 
40
40
  Arguments:
41
- device (FloorPro): The device to mirror.
41
+ device (FloorPro): The device to mirror (any ``sciro.pump`` device with a display stream).
42
42
  brightness (Number, %): Brightness of the mirrored pixels, 0 .. 1000.
43
43
  Above 100 the picture is amplified (clipping at full), since
44
44
  the matrix is far dimmer than a sensor's own LED strip.
@@ -21,7 +21,7 @@ class PUMPDevice:
21
21
  """Generic access to a PUMP device (Power UART Multiplex Protocol) on a
22
22
  PeakHub port. Streams are addressed by id (1..N); state and data are raw
23
23
  ``bytes`` decoded by the user or a convenience class such as
24
- :class:`sciro.floorpro.FloorPro`. Spec: ``PUMP-Protocol.md``.
24
+ :class:`sciro.pump.FloorPro`. Spec: ``PUMP-Protocol.md``.
25
25
  """
26
26
 
27
27
  OFF: int = 0
@@ -49,6 +49,15 @@ class PUMPDevice:
49
49
  ``{"url": str, "serial": str, "streams": ((id, url, ext_port, state_len), ...)}``
50
50
  """
51
51
 
52
+ def stats(self) -> Dict[str, Union[int, Tuple[Tuple[int, int, int], ...]]]:
53
+ """stats() -> Dict
54
+
55
+ Link counters since the session started, for load tests and diagnostics:
56
+ ``{"frames": good frames received, "crc_errors", "cobs_errors",
57
+ "short_frames", "overflows", "streams": ((id, frames, gaps), ...)}``
58
+ where ``gaps`` counts frames of that stream the hub never received.
59
+ """
60
+
52
61
  def state(self, stream: int) -> Optional[bytes]:
53
62
  """state(stream) -> bytes | None
54
63
 
@@ -75,5 +84,6 @@ class PUMPDevice:
75
84
  """subscribe(stream, mode, rate=0)
76
85
 
77
86
  Changes only the stream-control word (keeps the device-specific state
78
- bytes). ``rate`` is in units of 10 Hz, 0 = every sample.
87
+ bytes). ``rate`` is in Hz (1 .. 255; higher values are clamped to 255),
88
+ 0 = every sample.
79
89
  """
@@ -28,3 +28,14 @@ class Port(_PybricksEnum):
28
28
  F: Port = ord("F")
29
29
  G: Port = ord("G")
30
30
  H: Port = ord("H")
31
+
32
+
33
+ class ExtPort:
34
+ """Extension port of a PUMP device (1-based, as in its stream table)."""
35
+
36
+ EXT1: int = 1
37
+ EXT2: int = 2
38
+ EXT3: int = 3
39
+ EXT4: int = 4
40
+ EXT5: int = 5
41
+ EXT6: int = 6
@@ -1,4 +1,6 @@
1
- """sciro.floorpro -- the LP-FloorPro line sensor over PUMP (PeakHub).
1
+ """sciro.pump -- PUMP devices on the PeakHub, the PUMP counterpart of
2
+ ``pybricks.pupdevices``: the generic :class:`PUMPDevice` plus one class per
3
+ device (currently the LP-FloorPro line sensor).
2
4
 
3
5
  Stub for the frozen module of the same name. Every reading method returns the
4
6
  value directly, or an awaitable under multitasking.
@@ -6,10 +8,10 @@ value directly, or an awaitable under multitasking.
6
8
 
7
9
  from __future__ import annotations
8
10
 
9
- from typing import TYPE_CHECKING, Optional, Tuple
11
+ from typing import TYPE_CHECKING, Iterable, Optional, Tuple, Union
10
12
 
11
13
  if TYPE_CHECKING:
12
- from pybricks._common import MaybeAwaitable, MaybeAwaitableFloat
14
+ from pybricks._common import MaybeAwaitable, MaybeAwaitableColor, MaybeAwaitableFloat
13
15
 
14
16
  from ._common import (
15
17
  MaybeAwaitableEuler,
@@ -20,7 +22,10 @@ if TYPE_CHECKING:
20
22
  MaybeAwaitableRGBC,
21
23
  )
22
24
 
23
- from .iodevices import PUMPDevice, StreamInfo
25
+ from .iodevices import PUMPDevice as PUMPDevice # noqa: F401 (re-export)
26
+ from .iodevices import StreamInfo
27
+ from pybricks.parameters import Color
28
+
24
29
  from .parameters import Port as _Port
25
30
 
26
31
 
@@ -29,7 +34,7 @@ class _Stream:
29
34
  id: int
30
35
 
31
36
  def subscribe(self, mode: int, rate: int = 0) -> MaybeAwaitable:
32
- """subscribe(mode, rate=0) -- see :meth:`PUMPDevice.subscribe`."""
37
+ """subscribe(mode, rate=0) -- rate in Hz, 0 = every sample; see :meth:`PUMPDevice.subscribe`."""
33
38
 
34
39
  def state(self) -> Optional[bytes]:
35
40
  """state() -> bytes | None -- the stream's current state prefix."""
@@ -80,7 +85,7 @@ class Pixels(_Stream):
80
85
  """The sensor's own LED strip picture, rendered on the device at full scale:
81
86
  18 ``(r, g, b)`` triplets = IR channels 0..14, EXT1, EXT2, battery. Off by
82
87
  default. A PeakHub mirrors it on its 5x5 matrix with
83
- :meth:`sciro.hubs.PeakHub.display.device`.
88
+ :meth:`sciro.hubs.LightMatrix.device`.
84
89
  """
85
90
 
86
91
  def read(self) -> MaybeAwaitablePixels:
@@ -91,15 +96,49 @@ class Pixels(_Stream):
91
96
 
92
97
 
93
98
  class ColorSensor(_Stream):
94
- """TCS3400 on an extension port: raw R, G, B, C at device resolution.
99
+ """TCS3400 colour sensor on an extension port of a PUMP device.
100
+
101
+ ``ColorSensor(port, ext_port)`` opens it directly; :meth:`FloorPro.color_sensor`
102
+ returns the same class. ``hsv()`` and ``color()`` follow
103
+ ``pybricks.pupdevices.ColorSensor``.
95
104
 
96
105
  Every sample is tagged with the settings it was measured under, so a read
97
106
  after a settings change waits for the first sample taken with the new
98
107
  settings.
99
108
  """
100
109
 
110
+ ext_port: int
111
+
112
+ def __init__(self, port: Union[_Port, PUMPDevice], ext_port: int = 1):
113
+ """ColorSensor(port, ext_port=ExtPort.EXT1)
114
+
115
+ Arguments:
116
+ port (Port): Hub port of the PUMP device carrying the sensor (or the
117
+ opened ``PUMPDevice`` itself).
118
+ ext_port (ExtPort): Extension port the sensor is plugged into.
119
+ Raises ``OSError`` if there is no colour sensor there.
120
+ """
121
+
101
122
  def read(self) -> MaybeAwaitableRGBC:
102
- """read() -> Tuple[int, int, int, int, int] -- (red, green, blue, clear, status)."""
123
+ """read() -> Tuple[int, int, int, int, int] -- raw (red, green, blue, clear, status) at device resolution."""
124
+
125
+ def hsv(self) -> MaybeAwaitableColor:
126
+ """hsv() -> Color
127
+
128
+ Hue (0 .. 359), saturation (0 .. 100) and value (0 .. 100) of the
129
+ surface, as a ``Color``. Standard HSV of the raw reading; value is
130
+ relative to the full scale of the current integration time.
131
+ """
132
+
133
+ def color(self) -> MaybeAwaitableColor:
134
+ """color() -> Color
135
+
136
+ The nearest of the detectable colours (default: red, yellow, green,
137
+ blue, white, none), matched like ``pybricks.pupdevices.ColorSensor``.
138
+ """
139
+
140
+ def detectable_colors(self, colors: Optional[Iterable[Color]] = None) -> Optional[Tuple[Color, ...]]:
141
+ """detectable_colors(colors) -- set the colours color() chooses from; with no argument, get them."""
103
142
 
104
143
  def settings(self) -> Tuple[int, int, int]:
105
144
  """settings() -> Tuple[int, int, int] -- (led_percent, gain_x, atime) in effect."""
@@ -115,12 +154,25 @@ class ColorSensor(_Stream):
115
154
 
116
155
 
117
156
  class IMU(_Stream):
118
- """BNO086 on an extension port: roll, pitch, yaw in degrees.
157
+ """BNO086 IMU on an extension port of a PUMP device: roll, pitch, yaw in degrees.
119
158
 
120
- The heading offset lives on the hub: :meth:`reset_heading` makes the current
121
- yaw read as the given angle.
159
+ ``IMU(port, ext_port)`` opens it directly; :meth:`FloorPro.imu` returns the
160
+ same class. The heading offset lives on the hub: :meth:`reset_heading` makes
161
+ the current yaw read as the given angle.
122
162
  """
123
163
 
164
+ ext_port: int
165
+
166
+ def __init__(self, port: Union[_Port, PUMPDevice], ext_port: int = 2):
167
+ """IMU(port, ext_port=ExtPort.EXT2)
168
+
169
+ Arguments:
170
+ port (Port): Hub port of the PUMP device carrying the IMU (or the
171
+ opened ``PUMPDevice`` itself).
172
+ ext_port (ExtPort): Extension port the IMU is plugged into. Raises
173
+ ``OSError`` if there is no IMU there.
174
+ """
175
+
124
176
  def read(self) -> MaybeAwaitableEuler:
125
177
  """read() -> Tuple -- (roll, pitch, yaw, status), degrees; yaw includes the offset."""
126
178
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scirodev
3
- Version: 0.2.1
3
+ Version: 0.3.1
4
4
  Summary: PeakHub / sciro extensions to Pybricks: typed API stubs (sciro.*) and hub tooling on top of pybricksdev
5
5
  Author: Thomas Schank
6
6
  License: MIT
@@ -41,7 +41,7 @@ Then your IDE/type checker knows these, which the upstream `pybricks` stubs don'
41
41
  ```python
42
42
  from sciro.parameters import Port # Port.A .. Port.H (PeakHub has 8 ports)
43
43
  from sciro.iodevices import PUMPDevice # generic PUMP device access
44
- from sciro.floorpro import FloorPro # LP-FloorPro convenience class
44
+ from sciro.pump import FloorPro # PUMP devices (LP-FloorPro, ...)
45
45
  from sciro.hubs import PeakHub # hub class incl. display.device()
46
46
 
47
47
  hub = PeakHub()
@@ -50,6 +50,10 @@ cog_dark, cog_bright, brightness, darkness, mask, calibrating = fp.line.read()
50
50
  hub.display.device(fp, brightness=50) # mirror the sensor's LED strip on the 5x5
51
51
  ```
52
52
 
53
+ Full demo programs for the LP FloorPro (both for LEGO hubs and the PeakHub) live in
54
+ [sciurus-robotics/FloorPro-CodeDemos](https://github.com/sciurus-robotics/FloorPro-CodeDemos);
55
+ `examples/` here stays minimal.
56
+
53
57
  On the hub these modules are frozen into the PeakHub firmware:
54
58
  `sciro.parameters` and `sciro.iodevices` re-export the same runtime objects as
55
59
  their `pybricks.*` counterparts, so `sciro.parameters.Port is
@@ -7,6 +7,7 @@ sciro/floorpro.py
7
7
  sciro/hubs.py
8
8
  sciro/iodevices.py
9
9
  sciro/parameters.py
10
+ sciro/pump.py
10
11
  sciro/py.typed
11
12
  scirodev/__init__.py
12
13
  scirodev/cli.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes