Python API for the Formula AllCode robot.
pyallcode is a testable, and extensible Python API for the Formula AllCode robot manufactured by Matrix Tsl. It may be used as an alternative to the python API provided by Matrix Tsl.
pyallcode applies SOLID principles by separating responsibilities, using small focused interfaces, and inverting the serial dependency for easier testing.
Install from PyPI (recommended):
pip install pyallcodeLatest from source for development:
pip install -e .[dev]- The
FA.pyapi provided by Matrix Tsl contains a monolithic class(Create) that bundles many responsibilities. Pyallcode refactors the functionality ofFA.pyinto a modular framework and a newRobotAPI. - Introduced a
pyallcodepackage with clear layers:- Transport (serial I/O abstraction)
- Connection (command/response mechanics)
- Subsystems: LEDs, speaker, servo, LCD, SDCard etc.
- Aggregator
Robotcomposing all subsystems
- Cross-platform port discovery utilities moved to
pyallcode.portsand exposed viaRobot.
from pyallcode import Robot
# Connect
# # attempts to autoconnect, falls back to a simulated robot
bot = Robot()
# Use subsystems
api = bot.sensors.get_api_version()
print("API:", api)
bot.forward(200)
bot.left(90)
bot.leds.on(0) # switch on a led
bot.audio.play_note(440, 300)
front_ir = bot.ir_sensors.read(2)
print("Front IR value: ",front_ir)
bot.close()- Python 3.8 – 3.12
- Single Responsibility: Each subsystem handles one domain (e.g.,
leds,lcd,light sensor). - Open/Closed: New commands/subsystems can be added without modifying existing ones.
- Liskov: Subsystems expose stable, substitutable behavior; higher-level code does not rely on concrete transport.
- Interface Segregation: Small, cohesive classes; consumers use only what they need.
- Dependency Inversion: High-level code depends on
Transport(an interface protocol), notserial.Serialdirectly.
from pyallcode import Robot
print(Robot.list_available_ports())
print(Robot.list_ports_detailed())
print(Robot.find_robot_ports())If no serial hardware is detected (or pyserial isn't installed), the API automatically falls back to a simulated robot. This simulated robot:
- Prints acknowledgements for fire-and-forget commands (e.g.,
LEDOn,LCDPrint,SetMotors). - Returns plausible random integers for sensor reads (e.g.,
ReadIR,ReadLight,ReadMic,ReadAxis,ReadLine), and success codes for movement/SD operations. - Requires no hardware and no serial ports.
Optional: you can still force simulated mode explicitly by setting an environment variable before running your program (only the value 'simulated' is accepted):
Windows PowerShell:
$env:PYALLCODE_TRANSPORT = "simulated"
python your_script.pyWindows Command Prompt:
set PYALLCODE_TRANSPORT=simulated
python your_script.pyLinux/macOS (Bash/Zsh):
export PYALLCODE_TRANSPORT=simulated
python your_script.pyOr run inline:
PYALLCODE_TRANSPORT=simulated python your_script.pyEach device class can now open its own serial connection. You can pass an existing Connection (from Robot) as before, or let the device auto-connect by port (or auto-detect):
from pyallcode.devices.leds import LEDs
from pyallcode.devices.light import LightSensor
# Auto-detect a robot port and connect
leds = LEDs(verbose=1) # autodetects and connects (or uses simulation)
leds.on(0)
leds.off(0)
# Connect to an explicit port
light = LightSensor(port='COM7') # Windows; use '/dev/ttyUSB0' on Linux, '/dev/tty.usbmodem*' on macOS
print('Light:', light.read())
# Or reuse a Connection from Robot (legacy-compatible)
from pyallcode.robot import Robot
bot = Robot(autoconn=True)
mic = pyallcode.devices.mic.Mic(bot.conn)
print('Mic:', mic.read())Notes:
- When no hardware is found or a port fails to open, devices fall back to the simulated transport and continue to operate for learning/testing.
- You can control verbosity by passing
verbose=0|1|2to the device constructor.
pip install -e .[dev]
pytest -qSphinx docs live in docs/. Build them locally with:
pip install -e .[dev]
make -C docs html- Bump the version in
pyproject.tomland commit. - Create a GitHub Release (tag matching the version).
- GitHub Actions will build and publish to PyPI using the
PYPI_API_TOKENsecret.