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)

     *	 SMX2200 (Smart-UPS X 2200, 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  Mod-
     bus.

	 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 manage-
	 ment  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 in-
	 tegrating  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
	 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 sev-
     eral  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, ser-
     ial = 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 ven-
	 dorid 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  con-
	 nected   (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. chang-
	     ing 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 deploy-
	 ment, 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.  num-
	 bers,	rather than defaulting to 0 (rarely other values in certain dri-
	 vers 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; alterna-
	 tively you can classically export the environment variable LIBUSB_DEBUG
	 before starting a NUT driver program (may be set and "exported" in dri-
	 ver init script or service method, perhaps via nut.conf(5)), to  a  nu-
	 meric 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 an IP address or 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 libmod-
	 bus. It can be good to set a higher timeout  on  TCP  connections  with
	 high latency.

     modbus_retries=num
	 Set  the number of retries for Modbus register reads on timeout errors.
	 The default is 3 retries. After exhausting retries (or  on  non-timeout
	 errors),  the	connection  is	closed and will be re-established on the
	 next update cycle.

BUGS
   RTU USB support
     This driver relies on advanced features of libmodbus to talk Modbus  proto-
     col  over USB specifically (Serial and TCP are part of common library code-
     base). At the time of this writing, the common library project is just  ex-
     pecting a merge of the pull request with this ability.

     For the time being, if your OS distribution does not ship the required fea-
     ture  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  --pre-
	     fix=/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-sta-
	     tic  --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-confdir, --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/Build-
     ing-NUT-for-in%E2%80%90place-upgrades-or-non%E2%80%90disruptive-tests

   Using host names for UPS NMC
     An UPS network management card may be assigned a fixed/static IP address or
     a	dynamic one (e.g. by DHCP) in your network. Due to this, you may want or
     have to use a dynamic naming service to access the UPS. Note that this  may
     become a problem specifically during large outages and shutdowns, when your
     DHCP/DNS server might already go down while the driver needs to resolve the
     name  involved  (especially during late-shutdown hooks, when a new instance
     of the driver program might start just to tell the UPS to power off  or  to
     power-cycle).

     It may be wise to ensure your OS name service client can cache the UPS name
     sufficiently  long,  or  to  use  fixed  IP  addressing  (and  an	entry in
     /etc/hosts for good measure, so  you  only  have  one  spot  to  eventually
     re-configure this).

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.5.	   08/04/2026			   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+15.1.quarterly>

home | help