Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
APC_MODBUS(8)			  NUT Manual			 APC_MODBUS(8)

NAME
       apc_modbus - Driver for APC Smart-UPS Modbus protocol

SYNOPSIS
       apc_modbus -h

       apc_modbus -a UPS_NAME [OPTIONS]

SUPPORTED HARDWARE
       Generally this driver should work for all the APC Modbus	UPS devices.
       Some devices might expose more than is currently	supported, like
       multiple	phases.	A general rule of thumb	is that	APC devices (or
       firmware	versions) released after 2010 are more likely to support
       Modbus than the USB HID standard.

       Tested with the following hardware:

          SMT1500 (Smart-UPS 1500, Firmware 9.6)

          SMX750 (Smart-UPS X 750, Firmware 10.1)

          SMX1500 (Smart-UPS X	1500, Firmware 15.0)

       Note that you will have to enable Modbus	communication. In the front
       panel of	the UPS, go to Advanced	Menu mode, under Configuration and
       enable Modbus.

	   Note

	   This	driver was tested with Serial, TCP and USB interfaces for
	   Modbus. Notably, the	Serial ports are not available on all devices
	   nowadays; the TCP support may require a purchase of an additional
	   network management card; and	the USB	support	currently requires a
	   non-standard	build of libmodbus (pull request against the upstream
	   library is pending, as of at	the time of this publication) as a
	   pre-requisite to building NUT with this part	of the support.	For
	   more	details	(including how to build	the custom library and NUT
	   with	it) please see NUT PR #2063

	   Note

	   As currently	published, this	driver supports	reading	information
	   from	the UPS. Implementation	of support to write (set modifiable
	   variables or	send commands) is expected with	a later	release. This
	   can impact the host shutdown	routines in particular (no ability to
	   actively tell the UPS to power off or cycle in the end). As a
	   workaround, you can try integrating apctest (from the "apcupsd"
	   project) with a "Test to kill power"	into your late-shutdown
	   procedure, if needed.

EXTRA ARGUMENTS
       This driver also	supports the following optional	settings:

       port = string
	   Some	value must be set, typically auto.

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

       device =	regex
	   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
	   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
	   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.:

	      https://libusb.sourceforge.io/api-1.0/

	      https://libusb.sourceforge.io/api-1.0/group__libusb__lib.html

       porttype=value
	   Set the type	of the port used. Available values are serial for
	   RS232/485 based connections,	tcp for	TCP/IP connections and usb for
	   USB connections.

       port=value
	   Depending on	the port type you can select a port here. For usb only
	   auto	is supported, for serial you can pass a	device path like
	   /dev/ttyS0 and for tcp you can pass a hostname with optional	port
	   like	example.com:502.

       baudrate=num
	   Set the speed of the	serial connection. The default baudrate	is
	   9600.

       parity=value
	   Set the parity of the serial	connection. Available values are N for
	   none, E for even and	O for odd. The default parity is N (none).

       databits=num
	   Set the data	bits of	the serial connection. The default databits is
	   8.

       stopbits=num
	   Set the stop	bits of	the serial connection. The default stopbits is
	   1.

       slaveid=num
	   Set the Modbus slave	id. The	default	slave id is 1.

       response_timeout_ms=num
	   Set the Modbus response timeout. The	default	timeout	is set by
	   libmodbus. It can be	good to	set a higher timeout on	TCP
	   connections with high latency.

BUGS
       This driver relies on advanced features of libmodbus to talk Modbus
       protocol	over USB specifically (Serial and TCP are part of common
       library codebase). At the time of this writing, the common library
       project is just expecting a merge of the	pull request with this
       ability.

       For the time being, if your OS distribution does	not ship the required
       feature set, you	may have to build your own libmodbus and subsequently
       (re-)build NUT against this library, as detailed	in the NUT GitHub Wiki
       at
       https://github.com/networkupstools/nut/wiki/APC-UPS-with-Modbus-protocol

       The short sequence may be like follows:

	   cd ~/
	   git clone -b	rtu_usb	https://github.com/networkupstools/libmodbus
	   cd libmodbus
	   ./autogen.sh
	   ./configure --with-libusb --prefix=/path/to/prefix
	   make	install

	   Note

	      you may need to `make &&	sudo make install` if you want to
	       place this library files' variant into a	system path (like
	       --prefix=/usr/local to match NUT	defaults -- this activity
	       would need privilege elevation via sudo), and not into your
	       home directory or some /tmp location.

	      conversely, you may want	to ./configure --with-libusb
	       --enable-static --disable-shared	--prefix=/path/to/prefix and
	       only build and install a	static libmodbus.a (can	well be
	       installed into /tmp or similarly	short-lived location), so that
	       the customized Modbus+USB logic gets built directly into
	       apc_modbus binary program and there would be no potential
	       run-time	conflict with a	dynamic	library	file available
	       elsewhere in the	system.

	   cd ~/
	   git clone https://github.com/networkupstools/nut
	   cd nut
	   ./autogen.sh
	   ./configure --with-drivers=apc_modbus --with-usb --with-modbus \
	      --with-modbus-includes=-I/path/to/prefix/include/modbus \
	      --with-modbus-libs="-L/path/to/prefix/lib	-lmodbus"
	   make

	   Note

	      Other NUT configure options may be needed for proper behavior,
	       such as --prefix, --with-sysconfdir, --with-user	and
	       --with-group to match your packaged or otherwise	preceding NUT
	       installation.

       The ./configure --enable-inplace-runtime	may be a good start to inherit
       build configuration from	an existing NUT	deployment, as further
       detailed	at
       https://github.com/networkupstools/nut/wiki/Building-NUT-for-in%E2%80%90place-upgrades-or-non%E2%80%90disruptive-tests

AUTHORS
          Axel	Gembe <axel@gembe.net>

SEE ALSO
   The core driver
       nutupsdrv(8), ups.conf(5)

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

Network	UPS Tools 2.8.2.	  04/17/2025			 APC_MODBUS(8)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=apc_modbus&sektion=8&manpath=FreeBSD+Ports+14.3.quarterly>

home | help