Uninterruptable Power Supply

From SME Server
Jump to navigationJump to search


To see page for SME 10 and before go to Uninterruptable_Power_Supply/legacy

Is this article helpful to you?
Please consider donating or volunteering
Thank you!

Uninterruptable Power Supply

PythonIcon.png Skill level: Advanced
The instructions on this page may require deviations from standard procedures. A good understanding of linux and Koozali SME Server is recommended.


Introduction

The primary goal of the Network UPS Tools (NUT) project is to provide reliable monitoring of UPS hardware and ensure safe shutdowns of the systems which are connected.

The default configuration of NUT, will keep your connected systems operational until a critical battery state is reached (ie battery is nearing exhaustion) and then power down your server/equipment in a controlled fashion. See http://www.networkupstools.org/

If you have an APC UPS, see also Uninterruptable_Power_Supply:APC for an alternative to the standard SME Nut implementation

If you have Dell UPS, this might Help Uninterruptable_Power_Supply:LatestGeekery

Configuration Options using server-manager

Not all UPS's are supported by USB or the usbhid-ups driver. However NUT supports many UPS's and can be configured under SME Server easily.

SME Server 11 and newer supports 3 modes with Nut:

  • Standalone
  • NetServer
  • NetClient

Configuring as a standalone

Standalone mode means the UPS monitoring cable is connected directly to your SME Server, and only provides current to your server. You can configure one UPS in this mode using the manager.


If you need to set more UPS using this mode for your server, in the situation where you have multiple powersupply and need a dedicated UPS per power supply you can use command line to add more of them :

config set nut-driver@ups2 service status enabled Model usbhid-ups 
signal-event smeserver-nutUPS-update

where "ups2" would be the name of your ssecond UPS. First UPS will be named "ups".

Configuring as a NetServer

NetServer mode is similar to standalone in the fact that UPS monitoring cable are connected to the SME Server. However, in this mode the server act as a server for other devices to check what is the status of the UPS. You might have 1 or more secondary severs protected by the same UPS, and they will need to connect to SME Server to know if the UPS is out of power.

To use this mode you need to give to the other machines the UPS name and server address (eg ups@192.168.1.1); a username (which will be *upssecondary* since SME 11, but if you migrated from SME10 you might see *upsslave*); and a dedicated password. Those 3 things will be displayed on both the configuration page and status page.


Similarly to standalone mode, you might add more UPS using the command line.

Configuring as Netclient

In this mode, your SME Server will have to communicate with another server that is connected to the UPS monitoring cable. Similarly to NetServer mode, you will need 3 things to configure your SME Server, but this time you will need to fill them in on the manager panels to enable communication.




Particular configuration with extra steps

Sometime you need to add some more specific configurations, here is some guidance.

Selecting your type of UPS

For both Standalone and NetServer, you might set a different driver than the default. Mostly selecting a new driver will need nothing more.

If you select genericups, you will need to fill more information.

Nut ups drivers.png

Also to note as long as you use USB as connection you can leave USB device as auto.

Default Configuration (USB)

The default configuration in SME Server for 'NUT' is set by the configuration database properties

nut-driver@ups = service
  Model  = usbhid-ups
  status = enabled

Most USB connected UPS's will work with these default settings. If using a USB connection just enable NUT as follows:

If your USB UPS does not work properly OR you have a serial device then follow the Configuration Options below as required.

Serial Connection

  1. Find the configuration details for your model of UPS. Refer to: http://www.networkupstools.org/stable-hcl.html and make note of the driver name and upstype number (if any) in the third column.
    Warning.png Warning:
    Always use the serial cable supplied with the UPS. Standard serial cables won't work with a serial UPS and have been known to cause damage to the UPS. Pay particular attention to any references to cable in in the UPS Model column.

  2. From the console issue the following commands:
    config setprop nut-driver@ups Model <model> 
    config setprop nut-driver@ups Type <type> 
    config setprop nut-driver@ups Device <device> 
    config setprop nut-driver@ups status enabled
    
    Where:

    <model> and <type> are the driver name and type number found above.

    <device> is the serial port that the UPS is connected to

    eg. /dev/ttyS0. It also possible to use a more readable symlink.

    See HowTo on udev - symlinks for details.

    Note: The case of Model, Device and Type.

  3. Check:
    config show nut-driver@ups
    
  4. Apply changes and restart server:
    signal-event nut-conf
    # or 
    signal-event smeserver-nutUPS-update
    
  5. Confirm server is communicating with UPS:
    upsc ups@localhost
    

CLI configuration and usage

UPS Variables and Commands

In some cases you may wish to modify variables on the actual UPS such as the Low Charge/LOWBATTERY setting. This requires the use of the upsrw command and UPS administrative privileges.

You may also want to control the UPS directly from the command line by issuing UPS commands. This requires use of the upscmd command and UPS administrative privileges.

Warning.png Warning:
In general, the UPS data should be left protected and changes to it or issuing of commands well thought out. If you wish to make data changes or issue commands then the administrative privileges can be enabled as below and should then be disabled.


UPS Administrative Privileges

You should check your new password ( AdminPass ) to run upsrw & upscmd. Of course, you could change your password for a easier one to use.

config show nut

To set new admin password in database. The new password would be admin ( change it to suit your need )

config setprop nut AdminPass admin 

To enabled administrative privileges and run command to ups.

config setprop nut AdminUser enabled

Now, to get upsd to recognize admin modification for administrative privileges we expand the template and reload the upsd configuration

/sbin/e-smith/expand-template /etc/ups/upsd.users
/usr/sbin/upsd -c reload 
Important.png Note:
To disabled the administrative privileges once you have changed the UPS parameters or issued commands as required, issue the commands
config setprop nut AdminUser disabled
/sbin/e-smith/expand-template /etc/ups/upsd.users
/usr/sbin/upsd -c reload


UPS access

The access of the ups is controlled by database properties. The default propertie is set to localhost and give permission to run upsrw & upscmd from localhost only if administrative privileges is set to enabled as above. Three choices is available to set access.

  • localhost: the ups access is only from the local machine.
  • private: the ups access is from your local machine and local network as per define in server-manager panel.
  • public: the ups access is similar to localhost.

The appropriate mode is set via the events actions. Public is not allowed for Nut, if you force it yourself, next event will reset to the default, as presented below:

In standalone and NetServer, access is done with ( UPS name is ups )

ups@localhost

NetServer also allows access via LAN (private), access to your ups is ( UPS name is ups )

ups@192.168.1.1

Netclient mode needs the ip of the remote server, access to your ups is ( UPS name is ups )

ups@192.168.1.2

Setting UPS Variables

In order to set UPS variables it is necessary to have enabled the administrative privileges as above first and you get the possibility to run command from the ups if access is set to private as above.

In the examples below, it is assumed your UPS name is ups, that it is local, that the administrative user is admin and password admin. You can verify your UPS name via:

upsc -l

To view a complete list of the UPS variables, both informational and modifiable

upsc ups

To determine the modifiable variables for your UPS, their current settings and their available setting values execute the command:

upsrw ups

You can now modify the variables you wish using a command similar to the following (Note the order of the arguments is important, and you may need quotes around the value being set, "20"):

upsrw -s battery.charge.low=20 -u admin -p admin ups

For remote host (NetClient), we need to add the IP from remote server with the UPS to run command.

upsrw -s battery.charge.low=20 -u admin -p admin ups@192.168.2.1

Where the value after -s should be one of the parameters identified by the upsrw ups command. You can of course verify your changes using

upsrw ups

or

upsc ups

After you are done, clean up by disabling the upsc administrative privileges:

Warning.png Warning:
Make sure you understand the meaning or the UPS variables and their available setting options. Verify that your changes meet your intended behaviour!


More information on upsrw can be found at:

- Manual page: man upsrw

Changing battery date

An example to update you battery date upon changing it. (use your own password)

upsrw -s  battery.mfr.date=2020/08/31 -u admin -p admin ups

Issuing UPS Commands

In order to issue UPS commands it is necessary to have enabled the administrative privileges as above first and you get the possibility to run command from the ups if access is set to private as above.

In the examples below, it is assumed your UPS name is UPS, that it is local, that the administrative user is admin and password admin. You can verify your UPS name via:

upsc -l

To view a complete list of available commands for your UPS:

upscmd -l ups

You can now issue a command to the localhost UPS with similar to the following:

upscmd -u admin -p admin ups test.battery.start

For remote host (Netclient with remote server connected to UPS ), we need to add the IP from remote server with the UPS to run command.

upscmd -u admin -p admin ups@192.168.2.1 test.battery.start

Where the command test.battery.start is a valid command for your UPS as previously determined by upscmd -l ups. Depending upon the command issued you may get broadcast messages and emails relating to and confirming what the UPS is doing.

After you are done, clean up by disabling the upsc administrative privileges.

Warning.png Warning:
Before issuing any commands verify what they do for your particular UPS via the relevant documentation and ensure that the command meets your intended behavioural requirement!

Issuing commands could shutdown your server unexpectedly!


Timeout Issues

If you have comms problems like this you can add a custom timeout:

"USBDEVFS_CONTROL failed cmd blazer_usb rqt 33 rq 9 len 8 ret -110"

Add a new config item. The default is 2

config setprop nut pollInterval 4

Restart nut

service nut-server restart

Now check to see the correct timeout:

upsc UPS | grep driver.parameter.pollinterval
driver.parameter.pollinterval: 4

To reset either delete the key, or set it to the default of 2, or delete the property (delprop)

Scheduling Events

Shutdown Time Delay Example

By default NUT will issue a shutdown command as soon as it receives a low battery event from the UPS. There may be instances and installation configurations that require a shutdown sooner, or other events with timed or schedules outcomes. See the man pages etc for further info and example situations.

In essence the upsmon program monitors the relevant UPS and for each NOTIFYFLAG event in upsmon.conf takes immediate action as defined. In order to delay or schedule any actions, the events need to be passed to upssched which can set timers and schedule events.

The following changes to standard SME Server NUT configuration will shut down the server a specified time after receiving the "on battery" signal (the example given is for 2 minutes). It assumes you already have an enabled and working NUT configuration and UPS

To create a timed shutdown before the BATTLOW signal is received, it is necessary to configure upssched and have a script handle the UPS events (upsmon cannot do this).

First we need to create a new custom template directory:

mkdir -p /etc/e-smith/templates-custom/etc/ups/upsmon.conf
cd /etc/e-smith/templates-custom/etc/ups/upsmon.conf

Create and edit a new file called 'NOTIFYCMD' with the following content:

NOTIFYCMD /usr/sbin/upssched

Expand the template:

/sbin/e-smith/expand-template /etc/ups/upsmon.conf

Now create another a custom template directory

mkdir -p /etc/e-smith/templates-custom/etc/ups/upssched.conf
cd /etc/e-smith/templates-custom/etc/ups/upssched.conf

Create and edit a new file called '01CONFIG' with the following content:

CMDSCRIPT /sbin/e-smith/nutUPS.cmd
PIPEFN /tmp/upspipe
LOCKFN /tmp/upslock
AT COMMBAD * EXECUTE commbad
AT COMMOK * EXECUTE commok
AT NOCOMM * EXECUTE nocomm
AT ONBATT * EXECUTE powerout
AT ONBATT * START-TIMER shutdownnow 120     
AT LOWBATT * EXECUTE shutdowncritical
AT ONLINE * CANCEL-TIMER shutdownnow
AT ONLINE * EXECUTE powerup

In the above set the line AT ONBATT * START-TIMER shutdownnow 120 to how many seconds after ONBATT signal you want to shut down

Expand the template:

/sbin/e-smith/expand-template /etc/ups/upssched.conf

Create and edit a new script file at:

/sbin/e-smith/nutUPS.cmd

Add the following content:

#! /bin/sh
       case $1 in
               commbad)
                       /bin/echo "UPS communications failure on `date`." | /bin/mail -s"UPS communications LOST" admin
                       /usr/bin/wall "UPS communications failure."
                       ;;
               commok)
                       /bin/echo "UPS communications restored on `date`." | /bin/mail -s"UPS communications restored" admin
                       /usr/bin/wall "UPS communications restored."
                       ;;
               nocomm)
                       /bin/echo "UPS communications cannot be established on `date`." | /bin/mail -s"UPS uncontactable" admin
                       /usr/bin/wall "UPS communications cannot be established."
                       ;;
               powerout)
                       /bin/echo "Power failure on `date`." | /bin/mail -s"UPS on battery" admin
                       /usr/bin/wall "UPS on battery. Shutdown in 60 seconds...."
                       ;;
               shutdownnow)
                       /bin/echo "UPS has been on battery for 60 seconds. Starting orderly shutdown on `date`." | /bin/mail -s"UPS on battery for 60 seconds" admin
                       /usr/bin/wall "UPS has been on battery for 60 seconds. Shutting down NOW!!!!"
                       /usr/bin/sudo /sbin/e-smith/signal-event halt
                       ;;
               shutdowncritical)
                       /bin/echo "UPS battery level CRITICAL. Starting EMERGENCY shutdown on `date`." | /bin/mail -s"UPS battery CRITICAL" admin
                       /usr/bin/wall "UPS battery level CRITICAL. Shutting down NOW!!!!"
                       /usr/bin/sudo /sbin/e-smith/signal-event halt
                       ;;
               powerup)
                       /bin/echo "Power restored on `date`." | /bin/mail -s"UPS on line" admin
                       /usr/bin/wall "UPS on line. Shutdown aborted."
                       ;;
               *)
                       /bin/echo "Unrecognized command: $1"
                       ;;
       esac

Now make it executable by nut user

chmod 754 /sbin/e-smith/nutUPS.cmd
chown root:nut /sbin/e-smith/nutUPS.cmd

Nut requires to use sudo for this process to work, so sudo needs configuring to enable the user nut. By default the /etc/sudoers file is not part of the SME Server template system. To workaround this create a custom template directory:

mkdir -p /etc/e-smith/templates-custom/etc/sudoers
cd /etc/e-smith/templates-custom/etc/sudoers

To preserve the content of the original /etc/sudoers file copy that into the custom template directory:

cp /etc/sudoers 10sudoers 

Create and edit a new file called '30nut' with the following content:

nut   ALL=NOPASSWD: ALL

Then run:

/sbin/e-smith/expand-template /etc/sudoers

Finally to complete the process:

signal-event post-upgrade
signal-event reboot

While testing with the SMEServer v9.1 (circa March 2016), the above nutUPS.cmd script with entries in 01CONFIG template fails due to lack of permissions at the shutdownnow case at:

/usr/bin/sudo /sbin/e-smith/signal-event halt

Tweaking the /etc/sudoers did not mitigate it.

The error in the /var/log/messages is:

Mar 14 13:22:16 svr01 upssched[3507]: Timer daemon started
Mar 14 13:22:16 svr01 upssched[3507]: New timer: shutdownnow (120 seconds)
Mar 14 13:25:16 svr01 upssched[3507]: Event: shutdownnow
Mar 14 13:25:16 svr01 wall[3539]: wall: user nut broadcasted 1 lines (70 chars)
Mar 14 13:25:16 svr01 upssched[3507]: exec_cmd(/sbin/e-smith/nutUPS.cmd shutdownnow) returned 1

However, the nut user has the necessary shutdown permissions:

/usr/bin/sudo -u nut /usr/bin/sudo /sbin/e-smith/signal-event halt

Configure Nut-cgi Monitor Scripts

The nut-cgi rpm contains scripts that can be run via the webserver to monitor the UPS(s).

Download and install

You have to enable the epel repository:

yum install smeserver-extrarepositories-epel -y

then install nut-cgi:

yum install --enablerepo=epel nut-cgi 

then configure it the SME way: Edit file /etc/ups/hosts.conf and add.

mkdir -p /etc/e-smith/templates-custom/etc/ups/hosts.conf
echo 'MONITOR UPS@localhost "local UPS"' >/etc/e-smith/templates-custom/etc/ups/hosts.conf/10localhost
expand-template /etc/ups/hosts.conf

Httpd template

mkdir -p /etc/e-smith/templates-custom/etc/httpd/conf/httpd.conf
cd /etc/e-smith/templates-custom/etc/httpd/conf/httpd.conf

Now edit and create a new file 92nutupscmon with the following content

{
    $OUT = "";
    my $allow = 'all';
    my $pass = '0';
    my $satisfy = 'all';
    my $name = $nut{'Name'} || 'NUT UPS Daemon Monitoring';
    my $PublicAccess = $nut{'PublicAccess'} || "local";

    for ('exit-if-none')
    {
      if ($PublicAccess eq 'none')
          {
           next;
          }
      elsif ($PublicAccess eq 'local')
          {
            $allow   = "ip $localAccess";
            $pass    = 0;
            $satisfy = 'All';
          }
      elsif ($PublicAccess eq 'local-pw')
          {
            $allow   = "ip $localAccess";
            $pass    = 1;
            $satisfy = 'All';
          }
      elsif ($PublicAccess eq 'global')
          {
            $allow   = 'all granted';
            $pass    = 0;
            $satisfy = 'All';
          }
      elsif ($PublicAccess eq 'global-pw')
          {
            $allow   = 'all granted';
            $pass    = 1;
            $satisfy = 'All';
          }
      elsif ($PublicAccess eq 'global-pw-remote')
          {
            $allow   = "ip $localAccess";
            $pass    = 1;
            $satisfy = 'Any';
          }
 
      $OUT .= "#------------------------------------------------------------\n";
      $OUT .= "# nut multimon - $name\n";
      $OUT .= "#------------------------------------------------------------\n";

      {
        if ((exists $nut{'URL'}) && ($nut{'URL'} ne '')) {
          $OUT .= "Alias  /$nut{'URL'}  /var/www/nut-cgi-bin\n"; 
        }  
      }

      $OUT .= "Alias  /nut  /var/www/nut-cgi-bin\n";

      $OUT .= "\n";
      $OUT .= "<Directory /var/www/nut-cgi-bin>\n";
      $OUT .= "    DirectoryIndex upsstats.cgi\n";
      $OUT .= "    Options +ExecCGI\n";
      $OUT .= "    <Require$satisfy>\n" if ($pass);
      $OUT .= "    Require $allow\n";
      if ($pass)
      {
          $OUT .= "    AuthName $name\n";
          $OUT .= "    AuthType Basic\n";
          $OUT .= "    AuthExternal pwauth\n";
          $OUT .= "    require valid-user\n";
          $OUT .= "    </Require$satisfy>\n";
      }
      $OUT .= "</Directory>\n";
    }
}

Configure databases and expand the template

config setprop nut PublicAccess local
/sbin/e-smith/expand-template /etc/httpd/conf/httpd.conf


Important.png Note:
The above sets access to the scripts to local ip addresses only. See the Web_Application_RPM#New_DB_settings for further info and settings


Restart the web server

systemctl restart httpd-e-smith

Usage of Nut-cgi Scripts

Now go to http://yourdomain.tld/nut to see the statistics and information for the UPS at localhost.

By editing /etc/ups/hosts.conf and adding additional network UPS details, nut-cgi can be used to monitor more than one UPS. By the modification above, only the localhost is monitored.

Additional Information

General

By default, NUT is configured for a USB connected UPS in Standalone mode, but is disabled. When enabled, NUT will monitor the UPS and take various actions when certain notifications are received. This is controlled by the /etc/ups/upsmon.conf file which among other things lists the notifications and the actions to be taken for each. For example an On Battery event is captured by the NOTIFYFLAG ONBATT entry and the following SYSLOG+WALL+EXEC command string. This string tells upsmon to write the event to the System Log, broadcast a message to all users via Wall, and execute the command denoted by the NOTIFYCMD entry.

SME Server sets the NOTIFYCMD to /sbin/e-smith/nutUPS.notify, and this executable file simply sends an email to the SME admin user with a notification of the event.

Apart from the various events that the UPS and upsmon may notify via the NOTIFYFLAGS a Low Battery event will automatically and immediately cause upsmon to issue the SHUTDOWNCMD as defined in upsmon.conf (signal-event halt) and set a flag POWERDOWNFLAG so it knows on future restart that it is a UPS recovery.

For information on configuration parameters:

man ups.conf
man upsd.conf
man upsd.users
man upsmon.conf
man upssched.conf

For general information:

man upsd
man nutupsdrv

Master/slave vs Primary/secondary

Pre nut-2.8 version used the wording Master/slave for the type of UPS access. This has been moved to Primary/secondary since then.

In SME Server 11 and after we use 3 levels of users : admin, primary and secondary. Admin is for write access to ups. Primary is for local use. Secondary is to give for a remote NetClient, with the current server set as NetServer.

Encryption

Current configuration of Nut in SME Server 11 (2025/05) does not handle SSL encryption. WE suggest you not to use admin user over the lan, but only locally.

Further reading

The NUT website is here: NUT

From the above references you can glean which configuration setting does what function, etc.

If you want to modify the operation of NUT from the standard configuration, then you should generally modify the NUT config files by creating custom templates, expanding the templates and restarting service. This will ensure modifications survive a future reboot or reconfiguration.

An example of doing this can be found in the forum [1] and in the section above for UPS Administrative Privileges

See also Known Problem - Restarting Nut


Documentation

Nut is a Software well documented, you can find the TOC here and with an overview