GENERIC_MODBUS(8)

πŸ’… GENERIC_MODBUS β€” NUT manual, section 8 ✨

okay so bestie, this is generic_modbus(8), one of the NUT (Network UPS Tools) driver pages. Buckle up, it's giving very specific industrial-hardware energy and honestly? iconic. πŸŽ€


🌸 NAME 🌸

generic_modbus β€” a driver for contact (direct) signal UPS devices that are connected via modbus remote I/O gateways. πŸ’–


πŸ¦‹ SYNOPSIS πŸ¦‹

generic_modbus -h

generic_modbus -a DEVICE_NAME [OPTIONS]
note bestie: this man page only spills the tea on the specific features of the generic_modbus driver. For all the core driver lore, go read nutupsdrv(8). πŸ’œ

✨ SUPPORTED HARDWARE ✨

This is a generic modbus driver, and it's expected to work with contact (direct) signal UPS devices hooked up via modbus RIO (remote I/O) β€” either serial or TCP/IP. no cap. 🌈

The driver has been tested against a PULS UPS (model UB40.241) via MOXA ioLogikR1212 (RS485) and ioLogikE1212 (TCP/IP). πŸ’…

More info about this UPS lives here:

https://products.pulspower.com/ca/ubc10-241-n1.html

More info about Moxa ioLogik R1212, E1212 lives here:

https://www.moxa.com/en/products/industrial-edge-connectivity/controllers-and-ios

The PULS UPS UB40.241 supports these signals, periodt:

Ready contact      (DO) <--> HB
Buffering contact  (DO) <--> OL | OB
Battery-low        (DO) <--> LB
Replace Battery    (DO) <--> RB
Inhibit            (DI) <--> FSD

Digital port direction (DI/DO) assumes the device perspective, just so you know. πŸ‘€

So the driver's whole concept is mapping UPS states (as defined in NUT) onto the UPS contacts' states. The driver has an extended configuration interface implemented using variables defined in ups.conf. 🫢


πŸ”Œ HARDWARE INTERCONNECTION πŸ”Œ

Commissioning the modbus remote I/O server, and the UPS device, is carried out following the corresponding instruction manuals β€” not our problem, respectfully. πŸ™ˆ The figure below depicts the anticipated communication path and hardware interconnection:

+------+       +----------------+       +------------+       +------------+
| UPSD | <---> | GENERIC_MODBUS | <---> | MODBUS RIO | <---> | UPS DEVICE |
+------+  (1)  +----------------+  (2)  +------------+  (3)  +------------+
   |                   |
   +-------------------+
      HOST CONTROLLER

(1) Unix IPC
(2) RS232 | TCP/IP
(3) contacts

πŸŽ€ EXTRA ARGUMENTS πŸŽ€

This driver supports the following optional settings in the ups.conf(5) file. all optional, all yours to play with πŸ’–

Generic

  • device_mfr=value β€” a string specifying the manufacturer of the UPS device (default UNKNOWN).
  • device_model=value β€” a string specifying the model of the UPS device (default UNKNOWN).

Serial

  • ser_baud_rate=value β€” a integer specifying the serial port baud rate (default 9600).
  • ser_data_bit=value β€” a integer specifying the serial port data bit (default 8).
  • ser_parity=value β€” a character specifying the serial port parity (default N).
  • ser_stop_bit=value β€” an integer specifying the serial port stop bit (default 1).

Modbus

  • rio_slave_id=value β€” an integer specifying the RIO modbus slave ID (default 1).

States (X = OL, OB, LB, HB, RB, CHRG, DISCHRG, FSD)

  • <X>_addr=value β€” a number specifying the modbus address for the X state.
  • <X>_regtype=value β€” a number specifying the modbus register type for the X state.

Default values:

1 for X = OL, OB, LB ,HB, RB, CHRG, DISCHRG
0 for X = FSD

Valid values:

0:COIL, 1:INPUT_B, 2:INPUT_R, 3:HOLDING
  • <X>_noro=value β€” a number specifying the contact configuration for the X state (default 1).

Valid values:

0:NC, 1:NO
note: NO stands for normally open and NC for normally closed contact. πŸ’…

Shutdown

  • FSD_pulse_duration=value β€” a number specifying the duration in milliseconds for the inhibit pulse. If it's not defined, the signal has only one transition, depending on the FSD_noro configuration.

Examples for FSD signal configuration:

FSD_noro = 1

FSD_pulse_duration = 150

                     +-----+
                     |     |
inhibit pulse  >-----+     +------------------>
                      <--->
                      150ms

FSD_noro = 0

inhibit pulse  >-----+
                     |
                     +------------------------>

πŸ’œ CONFIGURATION πŸ’œ

Here's an example of generic_modbus driver configuration in the ups.conf file β€” steal it, it slays:

[generic_modbus]
  driver = generic_modbus
  port = /dev/ttyUSB0
  desc = "generic ups driver"
  # device info
  device_mfr = "PULS"
  device_model = "UB40.241"
  # serial settings
  ser_baud_rate = 9600
  ser_parity = N
  ser_data_bit = 8
  ser_stop_bit = 1
  # modbus slave id
  rio_slave_id = 5
  # UPS signal state attributes
  OB_addr = 0x0
  OB_regtype = 1
  OB_noro = 0
  LB_addr = 0x1
  LB_regtype = 1
  HB_addr = 0x2
  HB_regtype = 1
  RB_addr = 0x3
  RB_regtype = 1
  FSD_addr = 0x0
  FSD_regtype = 0
  FSD_pulse_duration = 150

⚑ INSTANT COMMANDS ⚑

This driver supports the following instant commands:

  • load.off β€” executes "instant poweroff". πŸ’€

🧚 INSTALLATION 🧚

Heads up: this driver may not be built by default. πŸ‘‘ You can build it by installing libmodbus and running configure --with-modbus=yes.

You also need to give proper permissions on the local serial device file (/dev/ttyUSB0 for example) so the run-time NUT driver user account can access it. fr fr, don't skip this one. 🫢


🌈 OTHER NOTES 🌈

The generic_modbus driver intends to support generic UPS devices with contact signals through modbus TCP/RTU gateways (also known as RIO β€” remote I/Os). The data and signal path looks like this:

[UPSD] <--- IPC ---> [GENERIC_UPS] <--- modbus TCP/RTU ---> MODBUS-RIO <--- contacts ---> [UPS DEVICE]

On the other hand, you can setup any kind of modbus server, and configure the generic_modbus driver to connect and read or write specific registers. Your application / modbus server could then drive NUT statuses (e.g. OL, OB, HB etc) by writing over those registers. main character energy, honestly. ⭐


😭 KNOWN ISSUES 😭

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. Because of that, you may want β€” or have β€” to use a dynamic naming service to access the UPS. πŸ‘€

careful bestie: 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). the timing is evil. πŸ’€

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). πŸ’…


πŸ‘‘ AUTHOR πŸ‘‘

Dimitris Economou <dimitris.s.economou@gmail.com>


🌸 SEE ALSO 🌸

The core driver:

nutupsdrv(8), ups.conf(5)

Internet resources:

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

and that's the whole page, bestie, you ate it. πŸŽ€ this was Network UPS Tools version 2.8.5, dated 10/07/2026 β€” mwah, slay, bye πŸ’–βœ¨πŸ¦‹

πŸ“¦ where this page comes from