Each supported Hexpansion has a small Python class in app/hexpansion/. It declares the VID/PID for detection, the commands it can receive, and how to tell when a command has been carried out. Everything else is handled by the base class.
Extend HexpansionModule from app/hexpansion/base.py and define:
| Attribute / method | What to do |
|---|---|
| VID, PID | The vendor and product IDs from the Hexpansion's EEPROM. The base class uses these to detect that the hardware is plugged in and derives FRIENDLY_NAME automatically. |
| COMMAND_OPTIONS | A list of every command this Hexpansion can be asked to perform. |
And define at least one of:
| Attribute / method | What to do |
|---|---|
| on_button_down(event) | Called for every button event. When the event satisfies the current command, set self.last_status = CommandStatus.PASSED. Use when the relevant hardware fires button events. |
| check_command() | Called on every poll (~1 s). If the current command has been satisfied, set self.last_status = CommandStatus.PASSED. Use when relevant hardware doesn't fire events. |
The three modules that ship with the game - Tildagon2024, MegaDrive and GPS, in app/hexpansion/ - should be good references.
A Hexpansion with a single big red button:
from .base import HexpansionModule, CommandStatus
class BigRedButtonModule(HexpansionModule):
VID, PID = 0x????, 0x???? # from your hexpansion's EEPROM manifest
COMMAND_OPTIONS = ["press"]
def on_button_down(self, event):
button = getattr(event, "button", None)
if button is None:
return
if button.group != "BigRedButton":
return
if self.current_command == "press":
self.last_status = CommandStatus.PASSED
Because the button press sets self.last_status directly, nothing else needs overriding.
app/hexpansion/MyHexpansion.py.MODULE_TYPES in app/hexpansion/__init__.py:from .MyHexpansion import MyHexpansionModule
MODULE_TYPES = [
Tildagon2024Module,
MegaDriveModule,
GPSModule,
MyHexpansionModule, # add here
]
app/hexpansion_names.py is generated from the hexpansion-firmwares repo - run scripts/generate_hexpansion_names.py to regenerate it if your Hexpansion is added to the repo. Otherwise, add your VID/PID manually to MANUAL_FRIENDLY_NAME_OVERRIDES in the script.
Copy the app to the badge and reset it:
pipx run mpremote cp -r app/* :/apps/spaceteam/ && pipx run mpremote reset
Then, with your Hexpansion plugged in, open the Race Condition app and select Test modules from the main menu and pick your hexpansion. It will step through each detected command for the hexpansion; perform the action and it advances automatically (hold Cancel for 2 s to skip). If your module doesn't appear it wasn't detected - check that its VID/PID is in app/hexpansion_names.py and regenerate with scripts/generate_hexpansion_names.py if needed.