Skip to content

Convert spectro.sh to Python#399

Merged
makermelissa merged 2 commits into
adafruit:mainfrom
makermelissa-piclaw:convert-spectro
Jun 16, 2026
Merged

Convert spectro.sh to Python#399
makermelissa merged 2 commits into
adafruit:mainfrom
makermelissa-piclaw:convert-spectro

Conversation

@makermelissa-piclaw

Copy link
Copy Markdown
Contributor

Converts spectro.sh to spectro.py, modernized for current Raspberry Pi OS.

Changes

  • Drop Python 2 support. The original installed both py2 and py3 prerequisites; py2 is EOL and the py2 apt packages no longer exist on Bookworm/Trixie. The .sh remains in the repo for anyone on older systems.
  • Virtual-environment install. Python modules install into the active venv via the standard sudo -E env PATH=$PATH python3 spectro.py invocation — no --break-system-packages.
  • systemd autostart. /etc/rc.local is deprecated on Bookworm/Trixie, so selector.py is now auto-started from a spectro.service systemd unit instead of editing rc.local.
  • Uses get_boot_config() for the boot config path.

Testing

Tested end-to-end on a Raspberry Pi 5 (Trixie):

  • Both select menus (matrix size, GPIO slowdown) and the mic/accel prompts
  • pip3 installs landed in the venv (psutil, RPi.GPIO, busdevice, lis3dh)
  • Config edits verified: selector.py FLAGS line, config.txt hdmi_force_hotplug=1, alsa.conf card remap (mic branch), i2c enabled (accel branch)
  • Spectro repo downloaded + chowned, /boot/gifs created
  • spectro.service installed and enabled

System was then reverted to baseline (config.txt md5 confirmed identical).

Modernized 1:1 port of spectro.sh for current Raspberry Pi OS:
- Drop Python 2 support (py2 is EOL; the original .sh remains for
  older systems)
- Python modules install into the active venv via the standard
  sudo -E env PATH=$PATH invocation (no --break-system-packages)
- Replace the deprecated /etc/rc.local autostart with a
  spectro.service systemd unit
- Use get_boot_config() for the boot config path

Tested end-to-end on a Pi 5 (Trixie): both select menus, mic and
accel branches, config edits (selector.py FLAGS, config.txt
hdmi_force_hotplug, alsa.conf, i2c), Spectro repo download, and the
systemd service all verified, then reverted to baseline.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR replaces the legacy spectro.sh installer with a modern spectro.py installer targeting current Raspberry Pi OS, including a switch from rc.local autostart to a systemd unit and updated boot config handling.

Changes:

  • Adds a new Python-based Spectro installer (spectro.py) using adafruit_shell.
  • Installs/overwrites a spectro.service systemd unit to autostart selector.py at boot.
  • Updates installation/config steps for current Raspberry Pi OS (e.g., get_boot_config() usage, optional mic/accelerometer branches).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread spectro.py
Comment on lines +32 to +43
shell.write_text_file(
"/etc/systemd/system/spectro.service",
f"""[Unit]
Description=Adafruit Spectro display daemon
After=multi-user.target

[Service]
Type=simple
User=pi
WorkingDirectory={SPECTRO_DIR}
ExecStart=/usr/bin/python3 {SPECTRO_DIR}/selector.py
Restart=on-failure

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — ExecStart now uses sys.executable (falling back to /usr/bin/python3) so the service runs the same interpreter/venv the installer used. Fixed in 73d97bc.

Comment thread spectro.py Outdated
Comment on lines +155 to +163
print("Downloading Spectro software...")
shell.run_command(
"curl -L https://github.com/adafruit/Adafruit_Spectro_Pi/archive/master.zip "
"-o Adafruit_Spectro_Pi.zip"
)
shell.run_command("unzip -q -o Adafruit_Spectro_Pi.zip")
shell.remove("Adafruit_Spectro_Pi.zip")
shell.run_command("mv Adafruit_Spectro_Pi-master Adafruit_Spectro_Pi")
shell.run_command("chown -R pi:pi Adafruit_Spectro_Pi")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — the installer now chdirs to ~pi, removes any existing SPECTRO_DIR first, and mvs/chowns into SPECTRO_DIR explicitly, so the unit path is correct regardless of CWD. Fixed in 73d97bc.

Comment thread spectro.py Outdated
Comment on lines +186 to +199
# Make default GIFs directory
shell.run_command("mkdir /boot/gifs")

# Set up LED columns, rows and slowdown in selector.py script
flags = (
f'FLAGS = ["--led-cols={MATRIX_WIDTHS[matrix_size]}", '
f'"--led-rows={MATRIX_HEIGHTS[matrix_size]}", '
f'"--led-slowdown-gpio={SLOWDOWN_OPTS[slowdown_gpio]}"]'
)
shell.pattern_replace("./Adafruit_Spectro_Pi/selector.py", "^FLAGS.*$", flags)

# Force HDMI out so /dev/fb0 exists
config = shell.get_boot_config()
shell.reconfig(config, "^.*hdmi_force_hotplug.*$", "hdmi_force_hotplug=1")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — GIFs dir is now derived from get_boot_config() (/boot vs /boot/firmware), created with mkdir -p for idempotency, and the installer bails cleanly if no boot config is found. Fixed in 73d97bc.

Comment thread spectro.py
Comment on lines +201 to +203
# Auto-start selector.py on boot via a systemd service
print("Installing spectro.service systemd unit...")
write_spectro_service()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — added a legacy /etc/rc.local cleanup that strips any selector.py autostart line, matching the retrogame.py pattern, so we don't double-launch alongside the systemd unit. Fixed in 73d97bc.

- ExecStart uses sys.executable so the service runs the same interpreter
  (and venv) the installer used, instead of hardcoded /usr/bin/python3.
- Install the repo into SPECTRO_DIR explicitly (chdir ~pi, overwrite if
  present) so the systemd unit path is correct regardless of CWD.
- Make the GIFs dir on the active boot partition via get_boot_config()
  (/boot vs /boot/firmware), mkdir -p for idempotency, bail if no config.
- Clean up any legacy selector.py line in /etc/rc.local to avoid
  double-launching alongside the systemd unit (matches retrogame.py).

@makermelissa makermelissa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the conversion.

@makermelissa makermelissa merged commit c1e0ef5 into adafruit:main Jun 16, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants