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, and port=auto is equivalent to specifying any of the USB matching options below (vendorid, productid, vendor, product, serial, bus) without an explicit port value — either is enough to select USB mode. If port is set to anything other than auto while USB matching options are also given, the port value 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.runtime from the standard HID Power Device usages this device also exposes on the same interrupt pipe, instead of letting that data go stale. The default is yes. Set to no to 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.

Note
This could be a device filesystem path like /dev/usb/hiddev0 but 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/serial string values (minus any surrounding whitespace), or the whole 4-digit hexadecimal code for vendorid and productid.

Try lsusb(8) or running this NUT driver with -DD command-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" or bus="00[2-3]") as seen on Linux in /sys/bus/usb/devices or lsusb(8); including leading zeroes.

Note
Bus 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" or device="00[1-2]") as seen on Linux in /sys/bus/usb/devices or lsusb(8); including leading zeroes.

Note
Device 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 device enumeration values, and in turn — this should be less volatile across reboots or re-plugging. The value may be seen in the USB topology output of lsusb -tv on systems with that tool, for example.

Note
This 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.

Warning

This 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 number 0 (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_index discovery, you can see larger wDescriptorLength values (roughly 600+ bytes) in reports of lsusb or 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_MIN setting in ups.conf(5) or protocol commands to change the driver.debug value), but may also benefit from LibUSB specific debugging.

For the latter, you can set the LIBUSB_DEBUG driver option; alternatively you can classically export the environment variable LIBUSB_DEBUG before 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 as 4 ("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

SEE ALSO

The core driver

Internet resources

The NUT (Network UPS Tools) home page: https://www.networkupstools.org/