sciro.hubs

sciro.hubs – the PeakHub.

On the hub this module re-exports pybricks.hubs unchanged; the stub adds what the upstream stubs lack: the PeakHub class, its display.device(), and the ThisHub alias.

class sciro.hubs.DisplaySource(*args, **kwargs)

Bases: Protocol

Anything LightMatrix.device() can show: an object whose _display_source() returns (PUMPDevice, stream id, map).

class sciro.hubs.LightMatrix(rows: int, columns: int)

Bases: LightMatrix

The PeakHub’s 5x5 RGB matrix: everything pybricks offers, plus a background mirror of a PUMP device’s display stream.

device(device, brightness=100)

Shows the device’s own display (e.g. the LP-FloorPro’s LED strip) on the matrix, updated in the background at the device’s rate until off() or any other drawing call. The device stops streaming when the program ends.

Parameters:
  • device (FloorPro) – The device to mirror (any sciro.pump device with a display stream).

  • brightness (Number, %) – Brightness of the mirrored pixels, 0 .. 1000. Above 100 the picture is amplified (clipping at full), since the matrix is far dimmer than a sensor’s own LED strip.

on(brightness=100)

Turns all pixels on at brightness percent (0 .. 100), stopping a running device() mirror or animation. Declared here because the firmware has it while the published pybricks stubs do not.

animate(matrices, interval)

Displays an animation made using a list of images.

Each image has the same format as above. Each image is shown for the given interval. The animation repeats forever while the rest of your program keeps running.

Parameters:
  • matrices (iter) – Sequence of Matrix of intensities.

  • interval (Number, ms) – Time to display each image in the list.

char(char)

Displays a character or symbol on the light grid. This may be any letter (a–z), capital letter (A–Z) or one of the following symbols: !"#$%&'()*+,-./:;<=>?@[\]^_`{|}.

Parameters:

character (str) – The character or symbol to be displayed.

icon(icon)

Displays an icon, represented by a matrix of brightness values.

Parameters:

icon (Matrix) – Matrix of intensities (brightness). A 2D list is also accepted.

number(number)

Displays a number in the range -99 to 99.

A minus sign (-) is shown as a faint dot in the center of the display. Numbers greater than 99 are shown as >. Numbers less than -99 are shown as <.

Parameters:

number (int) – The number to be displayed.

off()

Turns off all the pixels.

orientation(up)

Sets the orientation of the light matrix display.

Only new displayed images and pixels are affected. The existing display contents remain unchanged.

Parameters:

up (Side) – Which side of the light matrix display is “up” in your design. Choose Side.TOP, Side.LEFT, Side.RIGHT, or Side.BOTTOM.

pixel(row, column, brightness=100)

Turns on one pixel at the specified brightness.

Parameters:
  • row (Number) – Vertical grid index, starting at 0 from the top.

  • column (Number) – Horizontal grid index, starting at 0 from the left.

  • brightness (Number brightness) – Brightness of the pixel.

text(text, on=500, off=50)

Displays a text string, one character at a time, with a pause between each character. After the last character is shown, all lights turn off.

Parameters:
  • text (str) – The text to be displayed.

  • on (Number, ms) – For how long a character is shown.

  • off (Number, ms) – For how long the display is off between characters.

class sciro.hubs.System

Bases: System

The PeakHub’s system object: everything pybricks offers, plus the board identity.

device_id() → str

The full factory unique ID of the hub’s MCU as a 24-character uppercase hex string. Stable per physical hub.

short_id() → str

The hub’s 8-character short ID (Crockford base32, derived from the device ID): the same value the boot console prints and the device inventory uses.

info() → dict

{"name", "device_id", "short_id", "reset_reason", "program_id", "program_start_type"} in one call.

name() → str

The hub name, as advertised over Bluetooth.

reset_reason() → int

Why the hub last reset: 0 power-on or unknown, 1 software reset, 2 watchdog.

low_power()

Ends the program and drops the hub into its wakeable low-power mode (device supply off, motors coasting, panel dimmed) instead of powering off; a short button press wakes it back to the idle menu. PeakHub only.

reset_storage()

Resets all user settings to default values and erases user programs.

set_stop_button(button)

Sets the button or button combination that stops a running script.

Normally, the center button is used to stop a running script. You can change or disable this behavior in order to use the button for other purposes.

Parameters:

button (Button) – A button such as Button.CENTER, or a tuple of multiple buttons. Choose None to disable the stop button altogether. If you do, you can still turn the hub off by holding the center button for three seconds.

shutdown()

Stops your program and shuts the hub down.

storage(offset: int, *, read: int) → bytes
storage(offset: int, *, write: bytes) → None

Reads or writes binary data to persistent storage.

This lets you store data that can be used the next time you run the program.

The data will be saved to flash memory when you turn the hub off normally. It will not be saved if the batteries are removed while the hub is still running.

Once saved, the data will remain available even after you remove the batteries.

Parameters:
  • offset (int) – The offset from the start of the user storage memory, in bytes.

  • read (int) – The number of bytes to read. Omit this argument when writing.

  • write (bytes) – The bytes to write. Omit this argument when reading.

Returns:

The bytes read if reading, otherwise None.

Raises:

ValueError – If you try to read or write data outside of the allowed range.

class sciro.hubs.Battery

Bases: Battery

The PeakHub’s battery, with the two readings the published pybricks stubs lack.

type() → str

The battery chemistry the hub was built for: "Li-ion", "Alkaline" or "Unknown".

temperature() → int

The battery pack temperature, in milli-degrees Celsius.

current() → int: mA

Gets the current supplied by the battery.

Returns:

Battery current.

voltage() → int: mV

Gets the voltage of the battery.

Returns:

Battery voltage.

class sciro.hubs.UsbPd

Bases: object

Experimental. The hub’s USB-PD input.

Reached as PeakHub.usb_pd. Lets a program read the measured input voltage and ask the USB-PD sink to renegotiate to a different one.

voltage(volts=None) → int

Without an argument, returns the measured USB-PD input voltage in millivolts. The sense sits before the ideal diode, so it reads the supply itself and is not masked by a connected battery. Returns 0 if the ADC has not sampled yet (only in the first few ms after boot).

With an argument, asks the sink to renegotiate to that voltage.

Parameters:

volts (int) – 5, 9, 12 or 15. Any other value raises ValueError.

Returns:

The measured voltage in mV when called with no argument, otherwise None.

Warning

Experimental, and it is a request rather than a command.

A supply that does not offer the requested voltage simply refuses. Nothing is raised in that case and the hub stays where it was, so read the voltage back to see what actually happened rather than assuming the call took effect.

Higher PD gears (20 V, 28 V) are deliberately unreachable: the hub’s voltage sense saturates at 18.81 V, so the firmware could not even measure what it had asked for.

Renegotiating itself is well behaved in practice: measured working even while driving motors on a small (2x18650-class) power bank, and on a bench supply switching 9 V to 12 V and back with the hub up throughout.

Some power banks that were already switched on when the cable went in feed plain 5 V first and then cycle VBUS by themselves a few seconds later to start PD; a hub running from USB alone restarts at 9 V then. That is the bank’s doing, not the request’s. Switching such a bank off and on before pressing PWR avoids it.

status() → Dict

What the USB-PD sink negotiated with the supply: {"pd": bool, "bc": bool, "qc2": bool, "qc3": bool, "epr": bool, "max_ma": int, "raw": int, "mv": int}. pd is True under a PD contract (the normal 9 V case). max_ma is the contract’s current limit (0 without PD), raw the sink’s status register, mv the measured input voltage.

Diagnostic: lets a program see whether a contract exists at all.

class sciro.hubs.PeakHub(top_side: Any = None, front_side: Any = None, broadcast_channel: int = 0, observe_channels: Any = ())

Bases: object

LEGO-compatible hub by Sciurus Robotics: 8 ports, 5x5 RGB matrix, IMU.

battery = <sciro.hubs.Battery object>
buttons = <pybricks._common.Keypad object>
display = <sciro.hubs.LightMatrix object>
imu = <pybricks._common.IMU object>
speaker = <pybricks._common.Speaker object>
system = <sciro.hubs.System object>
usb_pd = <sciro.hubs.UsbPd object>
sciro.hubs.ThisHub

The hub this program is running on.

Every Pybricks firmware compiles in exactly one hub class and exports it under several names: the generic ThisHub, the hub’s own name, and any aliases. On PeakHub firmware ThisHub, PeakHub, PrimeHub and InventorHub are therefore all the same class object – this is resolved when the firmware is built, not by detecting anything at run time.

Use it for code that should run unchanged on whichever hub is in front of you, which is mostly bench and test scripts:

from sciro.hubs import ThisHub

hub = ThisHub()
print(hub.imu.heading(), hub.imu.tilt())

Prefer PeakHub when a program is specific to this hub anyway: it says so, and it reads better than a generic name.

Note the difference between the REPL and a downloaded program. The REPL is started with everything auto-imported and with a ready-made hub instance already created, so there hub.imu.heading() just works. A downloaded program gets neither: it must import what it uses and construct the hub, as above, and print(hub) there raises NameError. (In the firmware this is pb_package_pybricks_init(true) for the REPL versus false for everything else.)