QNAP NAS model TS-453 Pro has limited documentation on how to control its various peripherals, namely:
- the front LCD display, a 2 row, 16 column blue & white LCD display, and its two menu buttons ("ENTER", "SELECT")
- the front LEDs "STATUS" (red & green) & "USB" (blue)
- the 4 "disk error" LEDs (red)
- the front "USB COPY" button
- the main rear fan
I've spent some time toying with the stock firmware to figure that out.
Just FYI, to act of these peripherals (and a lot of other stuff such as flashing the firmware), the stock firmware uses a combination of a 1.3 MB shared library libuLinux_hal.so
, a 364 KB hal_daemon
service and a 176 KB hal_app
command-line tool, plus some other libraries for parsing the specific INI-stored "HAL config" for each device model. For example, to produce a beep:
$ hal_app --se_buzzer enc_id=0,mode=1
sends a message to hal_daemon
which eventually writes to the relevant low-level I/O port through libuLinux_hal
.
This can be controlled using standard hwmon tooling on Linux. Install lm-sensors
/fancontrol
. A sensible /etc/fancontrol
is presented below:
INTERVAL=10
DEVPATH=hwmon1=devices/platform/coretemp.0 hwmon2=devices/platform/f71882fg.656
DEVNAME=hwmon1=coretemp hwmon2=f71869a
FCTEMPS=hwmon2/device/pwm1=hwmon1/temp2_input
FCFANS= hwmon2/device/pwm1=hwmon2/device/fan1_input
MINTEMP=hwmon2/device/pwm1=30
MAXTEMP=hwmon2/device/pwm1=65
MINSTART=hwmon2/device/pwm1=150
MINSTOP=hwmon2/device/pwm1=0
This is a well-documented A125 board. There are multiple scripts and programs on the web to read the buttons and control the LCD display. See eg. the implementation for qcontrol
: a125.c
.
The tl;dr is:
- serial port
/dev/ttyS1
, baudrate 1200 (yes; that's 2 updates per second at best) - write
0x4D, 0x5E, 0x00
to switch the backlight off, write0x4D, 0x5E, 0x01
to switch the backlight on - write
0x4D, 0x0C, 0x00, 0x20, {16 chars}
to write to the first line, write0x4D, 0x0C, 0x01, 0x20, {16 chars}
to write to the second line (pad with spaces to clear the previous characters) - for each button press and release, the read buffer will receive 4 characters of the form
0x53, 0x05, 0x00, {BM}
where{BM}
is a bitmask of0x01
→ ENTER (UP) and0x02
→ SELECT (DOWN). Possible values are thus0x00
,0x01
,0x02
,0x03
. Pressing ENTER then pressing SELECT then releasing ENTER then releasing SELECT will send four 4-byte messages ending with0x01 → 0x03 → 0x02 → 0x00
.
This is the funny, otherwise undocumented part.
The stock firmware contains model-specific config files, eg. model_QW370_QW550_16_10.conf
, that describes on what low-level I/O ports should one read and write. Reproduced below are the interesting parts:
[System Enclosure]
VENDOR = QNAP
MODEL = TS-453 Pro
SIO_DEVICE = F71869A # The motherboard model.
# …
[System IO]
RESET_BUTTON = SIO:I92:B1
STATUS_GREEN_LED = SIO:I91:B2
STATUS_RED_LED = SIO:I91:B3
USB_COPY_BUTTON = SIO:IE2:B2
FRONT_USB_LED = SIO:IE1:B7
# …
[System Disk 1]
DEV_BUS = B00:D28:F0
DEV_PORT = 1
ERR_LED = SIO:I81:B0
# …
What I couldn't find in this file is the base port number. strace-ing the stock binary, I discovered it's 0xA05
(2565).
Port | Purpose |
---|---|
0xA05 |
Control "register" XX (:I{XX} ) |
0xA06 |
Register value, using negative bitmask offset X (:B{X} ) |
To change a LED state, write its control register to 0xA05
and the relevant bitmask to 0xA06
.
For instance, to change STATUS_GREEN_LED = SIO:I91:B2
:
- write to
0xA05
:0x91
(:I91
) - write to
0xA06
:0xFF ^ 0b100
, as GREEN is 2nd bit (:B2
)
To read a button status, write the control register to 0xA05
, read 0xA06
and mask it to get the relevant bit. For instance, to poll for COPY button status USB_COPY_BUTTON = SIO:IE2:B2
:
- write to
0xA05
:0xE2
(:IE2
) - read
0xA06
and get its 2nd bit (:B2
)
There is a sample C program below to demo this feature.
@artvel I did not look but to change the behavior of power buttons you'll usually have to toy with ACPI, which is a standard interface. No reason it wouldn't work with QNAP NASes.