Python – System Beep from rc.local-Scheduled Python Script

init.dpythonsystem

I managed to create a Python script to accept magnetic card swipes from a USB-based reader. It seems to work as expected. Part of the routine is a curl command to push the data to another server. Since the Ubuntu server won't have a monitor/keyboard/mouse my only way of responding to the user is with sound from the server's speaker.

Usually, the curl command gets a standard 200 response from the other application server. Sometimes, however, it gets a 500 error response and I need to communicate something back to the user to alert them that "this time didn't work, please scan your card again".

A simple mechanism is to beep once for success and nothing for failure. As written and run from a terminal, it works. As scheduled from rc.local, the system beep doesn't sound.

...
args = 'card=' + trackone.group(2)
r = requests.get('http://apiserver/api/', args)
if r.status_code == 200:
    # First attempt which doesn't work from rc.local
    # print("\a")
    # Second attempt, wrap the beep in a shell script
    os.system("sh /home/myuser/beep.sh")
else
    print(r.status_code)

And I attempted to create a simple shell script beep.sh:

#!/bin/bash
echo "\a"

As mentioned, both attempts work from the terminal but not as run from root under rc.local control. And I know that the API is being called since I can see the log entries.

The line in rc.local looks like this:

python '/home/myuser/scancards.py'

Is there a way to allow this command–as run within the init.d process–to be able to beep the speaker?

Best Answer

Install beep with sudo apt install beep (use apt-get instead of apt for earlier versions than 16.04)

Since beep supports different frequencies you could simply beep -f "$r.statuscode" or beep once for yesbeep -r1and twice for nobeep -r2`.

If for some unknown reason you are unable to get more than one beep you can utilize the -f switch to adjust the frequency to get for instance a lower tone for no and a higher tone for yes.

Examples:

No: beep -f 250

Yes: beep -f 2500

Yes, I know it's a short answer, but sometimes that's all that is required.

further research indicates that you will have to comment out blacklist pcspkr in /etc/modprobe.d/blacklist.conf to get this to work. you may also have to set the suid bit on beep to get this to work (I used sudo chmod 4755 /usr/bin/beep as I don't have concerns about others playing with beep on this system) you may wish to use groups to adjust permissions so that only worthy users can execute beep.

Note: As @JdeBP points out in his answer you may have to open a file descriptor to a terminal device

Sources: man beep

Getting the PC speaker to beep

http://pubs.opengroup.org/onlinepubs/9699919799/

Related Question