Gcode Shell Command required permissions to play a sound? (pipewire, speaker-test)

Printer Model: Ender 3 v2
MCU / Printerboard: Creality 4.2.2
Host / SBC: Acer Switch 12 running Linux Mint 22 (Wilma)
klippy.log
klippy.log (168.3 KB)

I’ve got a shell script to emulate a PC speaker beep by running speaker-test that works when I run it from terminal locally or over SSH, but it won’t run properly from the console in Klipper as called by a macro using Gcode Shell Command. For background, I’m a Windows admin and an Azure engineer with a nearly forgotten history in Linux web admin for Hostgator and Softlayer, so I know exactly enough to be dangerous in bash. I even know enough to recognize this isn’t really a Klipper question, but by science it sure is dressed up like one.

My method is sloppy, but it works in everything but Klipper. Broadly, it works like this:

  1. Define a function to send a sine wave to the audio service and then kill the process after a set time instead of figuring out how to stop the sound properly, piping stdout and stderr to /dev/null so it doesn’t fill Klipper’s console
  2. Call that function exactly once, specifying frequency and duration as parameters
  3. Force restart the audio service to avoid hearing the remainder of the already piped audio

This is clunky, to be very generous.

The macro, followed by the script, for those interested:

SCRIPT

#!/bin/sh
export AUDIODRIVER=alsa
_alarm() {
  ( \speaker-test -f $1 -t sine -c 2 -s 1 ) > /dev/null &
  pid=$!
  \sleep 0.${2}s
  \kill -9 $pid > /dev/null 2>&1
  systemctl --user restart pipewire.service
}
_alarm 440 250

MACRO

[gcode_shell_command A440Hz]
command: sh /home/twoscoopsofpig/beep.sh
timeout: 2.
verbose: True

[gcode_macro beep]
gcode:
    RUN_SHELL_COMMAND CMD=A440Hz

I’m assuming this is down to the klippy service not having access to something, but I’m not sure what it would be. Any guidance would be greatly appreciated.

Hello @twoscoopsofpig !

Klipper is meant to have access to the MCU (printer) not the SBC.

If you want to have access the SBC, you have to do it with a macro that is part of the frontend (Mainsail/Fluidd/OctoPrint)

Have you tried set -x on top of your script? With verbose: True you should get some output.

I did, but I wasn’t getting anything useful - just the stdout from speaker-test and an error from systemctl that I expected because I was sloppy. Thanks for the suggestion though!

EDIT: I should clarify - set -x matched the exact output from the shell but where I get the tone to sound off in the shell, it didn’t from the macro:

08:57:53
Failed to connect to bus: No medium found

That’s the error from systemctl. I’m expecting this. I still have an inkling that it’s pointing at the lack of a connection to the audio subsystem, but I can’t turn anything else up about it.

08:57:53
+ kill -9 2625783
/home/twoscoopsofpig/beep.sh: 9: kill: No such process
+ systemctl --user restart pipewire.service

The very sloppy kill -9 failing is weird too, but again, I’ve chalked it up to being some sort of persistence issue or session handling thing. There’s no other indication that it’s affecting the script run.

08:57:53
+ dur=.200
+ sleep .200

08:57:53
+ echo scale=3; 200/1000
+ bc

08:57:53
+ speaker-test -f 440 -t sine -c 2 -s 1

08:57:53
+ export AUDIODRIVER=alsa
+ _alarm 440 200
+ pid=2625783

All the rest of this is totally normal.

Ah! That makes sense. I’d kind of glossed over that in my troubleshooting -since I installed GCode Shell Command as an extension from KIAUH, it got muddied in my mental model. I’ve been assuming that when Klipper runs the macro it would ALSO run the script because I’ve been assuming the session context carries through the whole stack.

Does GCode Shell Command run from Mainsail’s context instead of Klipper’s?

I think we are mixing things up here:

  • gcode_shell_command is a Klipper extension
  • It uses python to create a subprocess that is executing the given command
  • It should run in the same context and with the same permissions as the user that is running Klipper

At least this is my understanding. IMO it should work unless there is some strange bash interaction.

1 Like

Python may be the missing link here. If Klipper isn’t not invoking the script directly, that may be where the chain breaks down. Windows has a problem with credentials being passed from one context to another (CredSSP is a mess) so I can imagine this being somewhat similar.

I’ll see what I can find in the logs when the macro runs. I really appreciate the insight!

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.