I recently acquired an Eaton 5E UPS. I like it. It keeps my Synology NAS up when power is out, but it has one annoyance: When the power goes out, the UPS starts beeping every couple of seconds. Unfortunately, I found this out the hard way, at 4AM. At that time I just wanted the beeping to stop, so I turned the UPS off and went back to sleep.

This UPS model has a USB connection. It allows the UPS to notify the connected device about several events: When mains power goes out, when the battery is low, etc. It also allows the UPS to be configured by the connected device. One of the configuration options is the beeper, which can be disabled or enabled.

In Linux, we use Network UPS Tools (NUT) to talk with UPS devices and other power controllers. NUT comes with several useful tools: upsc can query the UPS, and upscmd can modify its configuration. On a regular Linux system you can disable the beeper by running:

upscmd <ups_name> beeper.disable

(See this tutorial which applies to Debian-based systemd, including Ubuntu.)

However, the Synology DSM is not really a regular Linux system. While you can use upsc to query the UPS, you cannot use the upscmd command to change its configuration because upscmd is not provided with DSM.

The solution lies in how NUT works: It uses a client-server model, with a server called upsd listening on TCP port 3493. We can use telnet to manually connect to upsd, and talk to it using the NUT protocol, sending the command that upscmd would send.

First, create a user that can connect to upsd. SSH into your DSM (you need to enable ssh access on your DSM first), and add the following lines to the file /usr/syno/etc/ups/upsd.users:

[myuser]
    password = mypassword
    actions = SET
    instcmds = ALL

Change myuser and mypassword to something more secure.

Then, since DSM doesn’t have telnet, we’ll use the telnetlib module that comes with python. Create a new file, I put mine in /root/disable_ups_beeper.py:

#!/usr/bin/env python2
import telnetlib

tn = telnetlib.Telnet("127.0.0.1", 3493)

tn.write("USERNAME myuser\n")
tn.read_until("OK")
tn.write("PASSWORD mypassword\n")
tn.read_until("OK")
tn.write("INSTCMD ups beeper.disable\n")
tn.read_until("OK")
tn.write("LOGOUT\n")
print tn.read_all()

Change myuser and mypassword to the username and password you’ve set earlier. Then run this script once to disable the beeper.

python disable_ups_beeper.py

Note: In my experience, DSM re-enabled the beeper on restart. Instead of manually running disable_ups_beeper.py every time, I wrapped it in a shell script that first checks if the beeper is enabled before trying to disable it. I called it /root/beeper_control.sh:

#!/bin/bash -e

if [[ "$(upsc ups ups.beeper.status)" == "enabled" ]]; then
    echo "Beeper enabled, disabling"
    python /root/disable_ups_beeper.py
    echo "Waiting 5 seconds for UPS to update state"
    sleep 5
    if [[ "$(upsc ups ups.beeper.status)" == "disabled" ]]; then
        echo "Beeper disabled"
    else
        echo "Unable to disable beeper. Status = $(upsc ups ups.beeper.status)"
        exit 1
    fi
else
    echo "Beeper already disabled"
fi

Then I logged in to the DSM web interface, opened the Control Panel -> Task Scheduler, Create -> Triggered Task -> User-defined script. Under Event set “Boot-up”, and in the “Task Settings” tab, under User-defined script paste the following command:

bash /root/beeper_control.sh

This will keep the UPS beeper disabled for good.