NAME
apcmicrolink - Driver for APC Smart-UPS units using the Microlink protocol (serial or USB)
SYNOPSIS
apcmicrolink -h
apcmicrolink -a UPS_NAME [OPTIONS]
|
Note
|
This man page documents the hardware-specific features of the apcmicrolink driver. For general information about NUT drivers, see nutupsdrv(8). |
DESCRIPTION
The apcmicrolink driver talks the APC Microlink protocol used by newer serial-connected Smart-UPS families such as SMT and SMX units with the Microlink RJ45 serial port. It can also reach the same protocol tunneled over USB HID on models that have no serial port at all — see USB MODE below.
This driver is currently experimental. It discovers most values from the device descriptor blob at runtime and maps supported Microlink objects onto standard NUT variables where possible. Unknown descriptor fields can also be published for debugging and reverse-engineering.
SUPPORTED HARDWARE
This driver is intended for APC Smart-UPS models that expose the Microlink protocol, whether over the RJ45 serial cable or tunneled through USB HID.
Tested support currently targets:
-
APC Smart-UPS SMT/SMX Microlink models (serial)
-
APC Smart-UPS 500 / SCL500RMI1UC (USB) — see USB MODE below; this is the only USB Microlink model tested so far, by a single user/tester. SCL500RMI1UC is the European regional SKU of the SCL500RM1UC family; the non-European SCL500RM1UC is expected, but not confirmed, to match.
Other APC Microlink devices may work if they expose a compatible descriptor layout.
CONFIGURATION
The driver is configured via ups.conf(5).
A minimal serial configuration:
[apc-microlink]
driver = apcmicrolink
port = /dev/ttyUSB0
A minimal USB configuration (see USB MODE below):
[apc-microlink]
driver = apcmicrolink
port = auto
Optional settings
- port=device|auto
-
For serial devices, the path to the serial port (e.g.
/dev/ttyUSB0). For USB devices,auto(the default handling in NUT for USB drivers). See USB MODE below; USB mode requires builds with USB support enabled, andport=autois equivalent to specifying any of the USB matching options below (vendorid,productid,vendor,product,serial,bus) without an explicitportvalue — either is enough to select USB mode. Ifportis set to anything other thanautowhile USB matching options are also given, theportvalue is ignored (with a warning) in favor of USB mode. - baudrate=num
-
Set the serial line speed. The default is
9600. Serial mode only. - showinternals=yes|no
-
Publish additional internal Microlink runtime values. By default this follows the driver debug level and is enabled automatically when debug logging is on.
- showunmapped=yes|no
-
Publish descriptor values that do not currently map to a standard NUT variable. By default this follows the driver debug level and is enabled automatically when debug logging is on.
- cmdsrc=rj45|usb|localuser|smartslot1|internalnetwork1
-
Select the Microlink command source used for outgoing command writes. The default is
rj45. - hid_fallback=yes|no
-
USB mode only. While the Microlink tunnel itself has nothing fresh to report (including while it is still trying to connect after startup, see USB MODE below), publish
ups.status/battery.charge/battery.runtimefrom the standard HID Power Device usages this device also exposes on the same interrupt pipe, instead of letting that data go stale. The default isyes. Set tonoto get an honest data gap instead of a value sourced from a different (less precise) channel than the rest of the Microlink data.
- port = string
-
Required option for all NUT drivers. Some value must be set, typically auto for drivers that handle USB connections.
NoteThis could be a device filesystem path like /dev/usb/hiddev0but current use of libusb API precludes knowing and matching by such identifiers. They may also be inherently unreliable (dependent on re-plugging and enumeration order). At this time the actual value is ignored, but syntactically some port configuration must still be there.
It is possible to control multiple UPS units simultaneously by running several instances of this driver, provided they can be uniquely distinguished by setting some combination of the vendor, product, vendorid, productid, serial, bus and/or device options detailed below. For devices or operating systems that do not provide sufficient information, the allow_duplicates option can be of use (limited and risky!)
- vendorid = regex
- productid = regex
- vendor = regex
- product = regex
- serial = regex
-
Select a specific UPS, in case there is more than one connected via USB. Each option specifies an extended regular expression (see regex(7) for more information on regular expressions), which must match the UPS’s entire respective
vendor/product/serialstring values (minus any surrounding whitespace), or the whole 4-digit hexadecimal code forvendoridandproductid.Try lsusb(8) or running this NUT driver with
-DDcommand-line argument for finding out the strings to match.Examples:
-
-x vendor="Foo.Corporation.*" -
-x vendorid="051d*"(APC) -
-x product=".*(Smart|Back)-?UPS.*"
-
- bus = regex
-
OPTIONAL, NOT RECOMMENDED.
Select a UPS on a specific USB bus or group of buses. The argument is a regular expression that must match the bus name where the UPS is connected (e.g.
bus="002"orbus="00[2-3]") as seen on Linux in/sys/bus/usb/devicesor lsusb(8); including leading zeroes.NoteBus numbers are not guaranteed by the OS to be stable across re-boots, kernel driver reloads or device re-plugging (e.g. changing visible population of USB hubs). - device = regex
-
OPTIONAL, NOT RECOMMENDED.
Select a UPS on a specific USB device or group of devices. The argument is a regular expression that must match the device name where the UPS is connected (e.g.
device="001"ordevice="00[1-2]") as seen on Linux in/sys/bus/usb/devicesor lsusb(8); including leading zeroes.NoteDevice numbers are not guaranteed by the OS to be stable across re-boots or device re-plugging. - busport = regex
-
OPTIONAL, NOT RECOMMENDED.
If supported by the hardware, OS and libusb on the particular deployment, this option should allow to specify physical port numbers on an USB hub, rather than logical
deviceenumeration values, and in turn — this should be less volatile across reboots or re-plugging. The value may be seen in the USB topology output oflsusb -tvon systems with that tool, for example.NoteThis option is not practically supported by some NUT builds (it should be ignored with a warning then), and not by all systems that NUT can run on. - allow_duplicates
-
OPTIONAL, NOT RECOMMENDED.
If you have several UPS devices which may not be uniquely identified by the options above (e.g. only VID:PID can be discovered there), this flag allows each driver instance where it is set to take the first match if available, or proceed to try another.
Normally the driver initialization would abort at this point claiming "Resource busy" or similar error, assuming that the otherwise properly matched device is unique — and some other process already handles it.
WarningThis feature is inherently non-deterministic! The association of driver instance name to actual device may vary between runs!
If you only care to know that at least one of your no-name UPSes is online, this option can help.
If you must really know which one, it will not!
- usb_set_altinterface = bAlternateSetting
-
Force redundant call to
usb_set_altinterface(), especially if needed for devices serving multiple USB roles where the UPS is not represented by the interface number0(default). - usb_config_index
- usb_hid_rep_index
- usb_hid_desc_index
- usb_hid_ep_in
- usb_hid_ep_out
-
Force use of specific interface, endpoint, descriptor index etc. numbers, rather than defaulting to 0 (rarely other values in certain drivers for some devices known to use non-zero numbers). Specified as a hexadecimal number.
As a rule of thumb for
usb_hid_desc_indexdiscovery, you can see largerwDescriptorLengthvalues (roughly 600+ bytes) in reports oflsusbor similar tools. - LIBUSB_DEBUG = INTEGER
-
Run-time troubleshooting of USB-capable NUT drivers can involve not only raising the common NUT debug verbosity (e.g. using the
DEBUG_MINsetting in ups.conf(5) or protocol commands to change thedriver.debugvalue), but may also benefit from LibUSB specific debugging.For the latter, you can set the
LIBUSB_DEBUGdriver option; alternatively you can classically export the environment variableLIBUSB_DEBUGbefore starting a NUT driver program (may be set and "exported" in driver init script or service method, perhaps via nut.conf(5)), to a numeric value such as4("All messages are emitted").For more details, including the currently supported values for your version of the library, see e.g.:
IMPLEMENTED FEATURES
The driver publishes standard identity, status, runtime and outlet-group data when these objects are present in the Microlink descriptor. Descriptor-backed values are interpreted as strings, hex identifiers, dates, times, fixed-point numbers, and enum or bitfield maps depending on the Microlink type reported by the device.
Writable descriptor-backed variables are exposed as read-write NUT variables when the device reports them as modifiable. Depending on the connected model, this can include values such as:
-
ups.id -
ups.display.language -
ups.test.interval -
battery.date -
input.transfer.delay -
input.transfer.high -
input.transfer.low -
outlet.group.N.timer.shutdown -
outlet.group.N.timer.reboot -
outlet.group.N.timer.start -
outlet.group.N.delay.shutdown -
outlet.group.N.delay.reboot -
outlet.group.N.delay.start -
outlet.group.N.minimumreturnruntime -
outlet.group.N.lowruntimewarning -
outlet.group.N.name
On the tested Smart-UPS 500 (SCL500RMI1UC), the vendor’s own documentation lists these factory-default values for the delay/timer fields above:
-
outlet.group.N.delay.start("Turn On Delay"): 0 sec -
outlet.group.N.delay.shutdown("Turn Off Delay"): 0 sec on the unswitched/main group, 90 sec on switched groups -
outlet.group.N.delay.reboot("Reboot Duration"): 8 sec -
outlet.group.N.minimumreturnruntime("Minimum Return Time"): 0 sec
outlet.group.N.switchable (yes/no) is published read-only for every
outlet group, and instant commands for switching a group’s load are only
registered for groups where it is yes — some Microlink UPS models expose
one unswitched group (typically group 0) alongside one or more independently
switchable groups, and the unswitched group has no on/off/cycle/shutdown
commands to offer.
Supported instant commands currently include:
-
test.battery.start -
test.battery.stop -
test.panel.start -
test.panel.stop
Driver-assisted shutdown is not yet implemented.
USB MODE
Support for reaching the Microlink protocol over USB HID (port = auto)
is newer and less exercised than the serial path, and should be considered
experimental even relative to the rest of this already-experimental driver.
As of this writing it has been built and tested against a single APC
Smart-UPS 500 (SCL500RMI1UC) by a single tester, over an extended session
that included intentional fault injection (USB replug, driver restarts
mid-handshake, forced fallback). It has not been tested against any other
USB Microlink model, nor by anyone besides that tester.
How it works
The UPS tunnels the same Microlink byte protocol that apcmicrolink speaks
over RS232, but through two HID vendor-page reports on a generic HID vendor
tunnel, using genuine interrupt IN/OUT transfers rather than HID
Get/Set_Report control transfers (the tested device does not react to the
latter at all). Device matching uses the usual NUT USB
vendorid/productid/vendor/product/serial/bus/device options described
above; see lsusb(8) or -DD for finding the values to match.
Session startup over USB is intermittently unreliable on the tested
hardware — the device can take upwards of 90 seconds to become responsive
to the tunnel handshake after power-up or a USB replug. If the handshake
does not complete during driver startup, and the device also exposes
standard HID Power Device usages (as the tested model does), the driver
starts up anyway using those for ups.status/battery.charge/
battery.runtime (see the hid_fallback option above) instead of
refusing to start. Outlet-group data and instant commands, which depend
on the full Microlink descriptor, become available automatically once the
tunnel connects — no driver restart is needed. If the tunnel stays
unresponsive, the driver periodically attempts a USB device reset to try
to recover it.
Kernel usbhid conflict
The Linux kernel’s generic usbhid input driver will also claim this kind
of device by default, since from the USB descriptor’s point of view it is
just another HID device. If usbhid holds the interface, this driver
cannot claim it and will fail to start; and if usbhid reclaims the
interface after a USB reset or re-enumeration event while this driver is
already running (observed on the tested hardware), every following
interrupt transfer this driver attempts will be rejected by the kernel
until the driver process is restarted.
Neither this driver nor NUT’s shared USB layer (nut_libusb.c) attempts
to detach usbhid on its own. A udev rule that unbinds usbhid from the
UPS’s vendor/product ID avoids this. For example, for VID:PID 051d:0003
(APC Smart-UPS 500 / SCL500RMI1UC):
SUBSYSTEM=="usb", DRIVER=="usbhid", ATTRS{idVendor}=="051d", ATTRS{idProduct}=="0003", RUN+="/bin/sh -c 'echo -n $kernel > /sys/bus/usb/drivers/usbhid/unbind'"
Save this as e.g.
/etc/udev/rules.d/70-nut-apcmicrolink-usbhid-blacklist.rules, adjusting
the idVendor/idProduct match for your own device (see
lsusb(8)), then reload with:
:; udevadm control --reload-rules
:; udevadm trigger --subsystem-match=usb
Any other Microlink-over-USB model that the kernel’s usbhid driver also
claims by default would need the same treatment, with its own IDs
substituted.
CABLING
Use the APC Microlink serial cable appropriate for the UPS. USB-to-serial adapters can work if they present a standard TTY device to the operating system. For USB Microlink models with no serial port at all, see USB MODE above instead.
For USB mode on the tested Smart-UPS 500 (SCL500RMI1UC), connectivity uses the APC/Schneider Electric cable model 940-0504 (USB A to USB A), not a standard USB A-to-B cable.
AUTHORS
-
Lukas Schmid <lukas.schmid@netcube.li>
-
Nicolai nmbro Brogaard <nicolai.brogaard+nut@gmail.com>
SEE ALSO
The core driver
Internet resources
The NUT (Network UPS Tools) home page: https://www.networkupstools.org/