{"id":1,"date":"2021-02-23T02:51:45","date_gmt":"2021-02-23T02:51:45","guid":{"rendered":"http:\/\/varmintworks.com\/varmint-blog\/?p=1"},"modified":"2021-03-20T01:22:49","modified_gmt":"2021-03-20T08:22:49","slug":"ups-monitor","status":"publish","type":"post","link":"https:\/\/varmintworks.com\/varmint-blog\/2021\/02\/23\/ups-monitor\/","title":{"rendered":"Monitoring a UPS with a Raspberry Pi Zero W"},"content":{"rendered":"\n<p>Here on Whidbey Island in Washington state, we live in an area where the power goes out regularly. Heavy winds and\/or snow\/ice break breaches or fell trees onto power lines and\u2026 darkness. Sadness. Often, the power \u201cblinks\u201d, or at least we think it did, but have no way to verify. And we could start a graceful shutdown if we knew it had happened and could automate. After having recently installed a Raspberry Pi based <a href=\"https:\/\/www.home-assistant.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Home Assistant<\/a> solution in the house, It became even more important for me to have some indication of power outages, as well as monitor voltage. Over the years, I have accumulated 3 Costco Uninterruptible Power Supplies (UPSes):<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/bLM6ty2pqiemhVw-Le3dEHDMi6aydRCLKc2rn7RVsN-tbMCaAdWNwo3aDS_MODzDQ_nf39C-r-OIvQldLN_5dZp4cSxWm4P4QKMaHvgBYxol7wFKpnMzjmsWh2jeXT5q-K2S70cR\" alt=\"\"\/><\/figure>\n\n\n\n<p>I looked at the <a href=\"https:\/\/www.cyberpowersystems.com\/product\/software\/power-panel-personal\/powerpanel-for-linux\/\" target=\"_blank\" rel=\"noreferrer noopener\">\u201cPowerPanel\u201d software the vendor (CyberPower) provides<\/a>. They do have a version of this for Linux, but only x86\/x64 architecture support: No ARM flavors. I was also aware of <a href=\"https:\/\/networkupstools.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">Network UPS Tools<\/a>. At first I thought it was similar to a PC: I\u2019d have to get the PowerPanel \u201cdriver\u201d from the vendor, and then NUT could talk to it. WRONG! NUT has built-in drivers! And I found a <a href=\"https:\/\/perfecto25.medium.com\/monitor-cyberpower-ups-devices-with-raspberry-pi-99559725dbb8\" target=\"_blank\" rel=\"noreferrer noopener\">great article<\/a>, on one of my favorite sites: <a href=\"https:\/\/medium.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Medium<\/a>. This should be easy, right?! While that article was well written, it just didn\u2019t work for me. And I got frustrated following a blind script, when I wanted to understand how each of these settings fit together as a whole to accomplish my goal. I gave up that night. I knew the only way through this was to start from scratch and build up layer by layer\u2026 verifying it worked at each step, learning and understanding as I go. Then I would actually understand what I was doing.<\/p>\n\n\n\n<p>With renewed caffeine in my veins the following evening, I tried again, starting from the ground up, reading both the relevant RPIZero W documentation and the NUT <a href=\"https:\/\/networkupstools.org\/documentation.html\" target=\"_blank\" rel=\"noreferrer noopener\">documentation<\/a>. I built out my understanding of all of this, documented it, and got it running. This document and associated info is the result of those efforts. Best wishes and I hope you find this easier than I did originally!<\/p>\n\n\n\n<p>&#8211; Mike Porter<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">NUT Overview<\/h1>\n\n\n\n<p>The Network UPS Tools (NUT) are built with a \u201clayered\u201d approach to interfacing with your UPS\/s. From the \u201cbottom\u201d of the stack to the top, we find:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>First is the hardware layer. This includes the proper cabling and power supply\/s required.<\/li><li>Second Is the OS layer. Here this is mainly about getting the USB software at the OS\/OS Driver level set up correctly.<\/li><li>Third is the \u201cstart\u201d of NUT: the NUT \u201cDriver\u201d layer, aka \u201cups\u201d (defined in ups.conf) In this layer, you define your UPS\/s, and the parameters NUT needs to communicate<\/li><li>Fourth, is the \u201cserver\u201d layer for NUT, aka \u201cupsd \u201c (UPS daemon) (defined in upsd.conf, upsd.users, and hosts.cpnf)&nbsp;<\/li><li>Finally, there are the various clients that call into the NUT server, there is a \u201cserver\u201d layer. For example, with the command line interface (CLI) upsc. Or the built-in UPS Monitor process, aka \u201cupsmon\u201d. Or Nginx. Anything that calls into that NUT server.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/dih9TPRQXmncFdeRKtD4pfw8lNrn9IgmdgOtBmMlGvOKGte_qOHAP9j1YqPg4oqlMffaOhnPHhFYSFOhkDaX2cnX-GXulnmRZUDjyHcnih35dvIMZR_QrgYPsLy78YRAZ6Iis1CP\" alt=\"\"\/><\/figure>\n\n\n\n<p>In this documentation, I will walk you through:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Step 1: Prepare the Raspberry Pi Zero W Hardware<\/li><li>Step 2: Prepare and Configure Boot SD Card<\/li><li>Step 3: Prepare and Install NUT Packages<\/li><li>Step 4: Configure and Test NUT Driver<\/li><li>Step 5: Configure and Test NUT Server<\/li><li>Step 6: Configure and Test NUT Client &#8211; upsmon<\/li><li>Step 7: Configure and Test NUT Client &#8211; NGinx (OPTIONAL)<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Step by Step Installation Overview<\/h2>\n\n\n\n<p>In order to try and lay out a \u201cmap\u201d of the pieces and parts that are involved, I used the overview graphic, and added along the stack visuals the individual configuration files and the parameters I needed to set for this installation. The install process starts at the bottom of the graphic, and works its way to the top. We will verify each level before proceeding to the next step.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/de6Ohm5--iZuuAS5A4kI1GK2efGSxWtixfLTM-PNwnYdgVkezMtnMahvpyjwyhO5wfLoGlmdq3w7F8k6AQAfHYZxk8T7OIQSeu39K64vW6LIIQ4NMIqCBG7PnFxypkxquyGfMYw_\" width=\"624\" height=\"424\"><\/h2>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Prepare the Raspberry Pi Zero W Hardware<\/h2>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/vSigDP2lQfce1ONd7DtRt1Ti1Pt6D2Rc8c30EyhSWV4WBVeOd0RCEKWuyLR--IgiG-oCmlMIJt5Bj35FkdZpCr3-89lgAKrPwdmU40AwEZJG-W_81jV6Bi4XW4T6gzhJk8tenaf6\" alt=\"\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/X8XR5wWZ0CRypo2HrgF4WDc3CpyHCaTBZ7uJVGctN1_ruWyHS4c8fCcxhkgD_q3KX6zGMUD6l7T_1Uo21ZhFBVuhV6jql3sUIS4E2HegtvysMETr4wKmnOCg705zfyRGfOxHmAlF\" alt=\"\"\/><\/figure>\n\n\n\n<p>NOTE: This was the correct cable for my UPS. Yours might have a different interface, and\/or require a different driver.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Power Supply for Raspberry Pi Zero W: In this case, I can either use one of the two front USB 2.1 amp outlets that are backed by the UPS (which avoids consuming a UPS outlet on the back), Or use a separate supply. In this case, I\u2019m using a separate cord solely because of the cable length.<\/li><li>You can use any case that works for you. I happened to have <a href=\"https:\/\/www.canakit.com\/pi-zero-case-canakit.html\">this one from CanaKit<\/a> lying around and it was perfect for my needs!<\/li><li>You will need a \u201cUSB To Go\u201d adapter. It will allow you to plug in the UPS cable to the Raspberry Pi. Specifically, it is a combination (for my UPS) of the following cables:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Picture<\/strong><\/td><td><strong>Description \/ Link<\/strong><\/td><\/tr><tr><td><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/RJtILj_K7jv8VCRerLpEV3TMhCiWp9W9J2natnqqM0bLqVSc2qCjV72tPQ_54A7spxY4kuQurDyo8gs4NhSKhfMHYSPWuNHteST7BLF2L4UK9jguDZ2Wp13KknBj_7fKgGqwUp2T\" width=\"149\" height=\"121\"><\/td><td><strong>USB 2.0 Micro USB Male to USB Female OTG Adapter<\/strong><a href=\"https:\/\/www.amazon.com\/gp\/product\/B01C6032G0\">This was the one I purchased<\/a>.<\/td><\/tr><tr><td><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/HE6i0j79SuT3PLqugCwSmLfP9_33B5-GbmI_r6KLlwlYwWKHYWn-bCAqjolS7ETLwQbnnjci6uNRNjvnge353OuvzZVyvymRt_iUf8iIrIEkxffIvKyoCDp3rZzANzuZ2u0pMF4L\" width=\"170\" height=\"104\"><\/td><td><strong>USB 2.0 USB 2.0 A-Male to B-Male Cord<\/strong>I have tons of these lying around<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Prepare and Configure Boot SD Card<\/h2>\n\n\n\n<ol class=\"wp-block-list\"><li>Image with the latest Raspberry Pi OS \u201cLite\u201d version, 32-bit<\/li><li>Eject SDCard &amp; Re-Insert<\/li><li>Then, add to the BOOT partition:<ol><li>Empty ssh file<\/li><li>Copy prepared wpa_supplicant.conf file, containing:<\/li><\/ol><\/li><\/ol>\n\n\n\n<p>country=US<\/p>\n\n\n\n<p>ctrl_interface=DIR=\/var\/run\/wpa_supplicant GROUP=netdev<\/p>\n\n\n\n<p>update_config=1<\/p>\n\n\n\n<p>network={<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; ssid=&#8221;&lt;&lt;NameOfYourWIFI&gt;&gt;&#8221; &nbsp; &nbsp; &lt;- Change this to yours<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; psk=&#8221;&lt;&lt;SuperSecretPassword&gt;&gt;&#8221; &lt;- Change this to yours<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; key_mgmt=WPA-PSK&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\"><li>Safely eject CD card and insert into Raspberry Pi<\/li><\/ol>\n\n\n\n<ol class=\"wp-block-list\" start=\"4\"><li><strong>BOOT<\/strong><\/li><li>Find YOUR Raspberry Pi\u2019s IP address [mine=192.168.0.201]&nbsp; &lt;- Not sure how? <a href=\"https:\/\/www.raspberrypi.org\/documentation\/remote-access\/ip-address.md\">Go here<\/a><\/li><li>ssh pi@192.168.0.201&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;- This is mine. Use <strong><em>YOUR <\/em><\/strong>IP address<\/li><li>Passwd&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;- <strong><em>Please?! At LEAST change the&nbsp;<\/em><\/strong><\/li><\/ol>\n\n\n\n<p><strong><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;root password!<\/em><\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"8\"><li>sudo raspi-config<ol><li>1 System Options \/ S4 Hostname<\/li><\/ol><\/li><\/ol>\n\n\n\n<p>[rpzw-ups01]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\"><li>5 Localisation Options \/ L1 Locale (2 screens)<ol><li>1st screen, UNSELECT en_GB.UTF-8 UTF-8, then<\/li><li>select en_US.UTF-8 UTF8<\/li><li>2nd screen, move from none to en_US.UTF-8<\/li><\/ol><\/li><li>5 Localisation Options \/ L2 Timezone<ol><li>1st screen, US<\/li><li>2nd screen, Pacific Ocean<\/li><\/ol><\/li><li>5 Localisation Options \/ L4 WLAN country<ol><li>[US]<\/li><\/ol><\/li><\/ol>\n\n\n\n<ol class=\"wp-block-list\" start=\"9\"><li><strong>REBOOT<\/strong><\/li><li>sudo apt-get update&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;- ~ 1 minute<\/li><li>sudo apt-get full-upgrade&nbsp; &nbsp; &lt;- ~ 17-18 minutes, YMMV<\/li><li>Plug in UPS cable between the Raspberry Pi and the UPS<\/li><li><strong>REBOOT<\/strong><\/li><\/ol>\n\n\n\n<p>You now have a Raspberry Pi Zero W with a full updated image! Congratulations! You should verify the OS &amp; Hardware, and their ability to communicate with the UPS:<\/p>\n\n\n\n<p>To verify: lsusb -t<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/mQ9zgKPhf8TMhYdIDnDQ2tLAtqMD66zEZ22sUT-Mh9HXufQ0dNHtQcohnHxpRIqRrxH42F88qUoEfU_UccI5o0j41JC4fYXFx5cSdGzCg45a4583Ue_vGgtSp4IsXZq7dUKYIqkw\" alt=\"\"\/><\/figure>\n\n\n\n<p>NOTE: Class=Human Interface Device\u2026 so NUT driver should be usbhid-ups<\/p>\n\n\n\n<p>Also note, Driver=dwc_otg\u2026 USB OTG is working!!! Several articles I found that assumed this was the problem. Not for me.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><\/h2>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Prepare and Install NUT Packages<\/h2>\n\n\n\n<ol class=\"wp-block-list\"><li>Create User &amp; Group<ol><li>sudo adduser ups&nbsp; [password: mikehome]<\/li><li>sudo addgroup nut<\/li><li>sudo adduser ups nut<\/li><\/ol><\/li><li>sudo apt-get install nut nut-client nut-server &nbsp; &lt;- ~ 2 minutes<\/li><li>Create a place to store UPS state and data<ol><li>sudo mkdir -p \/var\/nut\/run<\/li><li>sudo chmod 0770 \/var\/nut\/run<\/li><li>sudo chown root:nut \/var\/nut\/run<\/li><\/ol><\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Configure NUT Driver<\/h2>\n\n\n\n<ol class=\"wp-block-list\"><li>Edit \/etc\/nut\/ups.conf to configure you UPS<ol><li>sudo nano \/etc\/nut\/ups.conf<\/li><li>Add:<\/li><\/ol><\/li><\/ol>\n\n\n\n<p>[ups01]<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;driver = usbhid-ups<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;port = auto<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pollinterval = 15 &nbsp; &nbsp; &nbsp; &lt;- Required See <a href=\"https:\/\/raspberrypi.stackexchange.com\/questions\/66611\/nut-cyberpower-data-stale\">this<\/a>.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;desc = &#8220;CP1500 AVR UPS&#8221;<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\"><li>Start UPS Driver<ol><li>sudo systemctl start nut-driver<\/li><\/ol><\/li><\/ol>\n\n\n\n<p>To verify: sudo systemctl status nut-driver<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/-Nmfg6m7fvfE3PnCkWav7UfE5W29WX15RRSefIgBjXdQ6czNxuCP_r5aaA3g7-5T9sCmdmo9fxZ27Bnk3wOzmsWerIRQsm2l_QLdXW-0wsHs-I6OZgzFq9aZtJtZZJrL8nEwCkjP\" alt=\"\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><\/h2>\n\n\n\n<h2 class=\"wp-block-heading\">Step 5: Configure and Test NUT Server<\/h2>\n\n\n\n<ol class=\"wp-block-list\"><li>Edit \/etc\/nut\/upsd.conf to configure you UPS Server<ol><li>sudo nano \/etc\/nut\/upsd.conf<\/li><li>Add:<\/li><\/ol><\/li><\/ol>\n\n\n\n<p>LISTEN 127.0.0.1 3493<\/p>\n\n\n\n<p>LISTEN ::1 3493<\/p>\n\n\n\n<p>LISTEN 192.168.0.201 3493<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\"><li>Uncomment :&nbsp; STATEPATH \/var\/run\/nut<\/li><li>Edit \/etc\/nut\/upsd.users<ol><li>sudo nano \/etc\/nut\/upsd.users<\/li><li>Uncomment:<\/li><\/ol><\/li><\/ol>\n\n\n\n<p>[admin]<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;password = mypass<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;actions = SET<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;instcmds = ALL<\/p>\n\n\n\n<p>[upsmon]<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;password&nbsp; = pass<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;upsmon master<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\"><li>Edit \/etc\/nut\/hosts.conf<ol><li>sudo nano \/etc\/nut\/hosts.conf<\/li><li>Add:<\/li><\/ol><\/li><\/ol>\n\n\n\n<p>MONITOR ups01@192.168.0.201 &#8220;CP1500 AVR UPS&#8221;<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"4\"><li>Edit \/etc\/nut\/nut.conf<ol><li>sudo nano \/etc\/nut\/nut.conf<\/li><li>Set mode to:<\/li><\/ol><\/li><\/ol>\n\n\n\n<p>MODE=standalone<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"5\"><li>For security, you should consider locking down these files. For testing, it will work without this, but for any attempt to \u201csecure\u201d this server, this is a best practice:<ol><li>cd \/etc\/nut<\/li><li>sudo chown root:nut upsd.conf upsd.users<\/li><li>sudo chmod 0640 upsd.conf upsd.users<\/li><li>cd ~<\/li><\/ol><\/li><li><strong>REBOOT<\/strong><\/li><\/ol>\n\n\n\n<p>To verify: sudo systemctl restart nut-server, then sudo systemctl status nut-server<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/tkJmUO7HTE5unUdx4SK1slA4IhIRtc0tnmP4aHRxdtsdXbmZPtd8kqBqb1AeCYly2_Hs_zL83KLLVFZE5LaKzyJ4e8E9-QsOFh9_-jwKKV99D8CgwE3zx4KDZyyPg1U2Sic_v87O\" alt=\"\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><\/h2>\n\n\n\n<h2 class=\"wp-block-heading\">Step 6: Configure and Test NUT Client &#8211; upsmon<\/h2>\n\n\n\n<ol class=\"wp-block-list\"><li>Edit \/etc\/nut\/upsmon.conf to configure you UPS monitor client<ol><li>sudo nano\/etc\/nut\/upsmon.conf<\/li><li>Add: (must match \/etc\/nut\/upsd.users upsmon user\/pass)<\/li><\/ol><\/li><\/ol>\n\n\n\n<p>MONITOR ups01@localhost 1 upsmon pass master<\/p>\n\n\n\n<p>To verify: sudo systemctl restart nut-monitor, then sudo systemctl status nut-monitor<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/66z1KXXU9EuGKSwqeFxY5k0GetIOT9xS5oDOTsvVT_WaUfgjETDKB7JCjiPiHfLIyyT11uRgGlEXipBZakLMJmkCtCeNZVnDeQzFCBaVSlXPg9ilv1_b07jXvHdDzlakD5jpccQl\" alt=\"\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Step 7: Configure and Test NUT Client &#8211; Nginx (OPTIONAL)<\/h2>\n\n\n\n<p>While I wasn\u2019t really looking for a web integration, this was so simple and lightweight, it was worth it. The idea came from:&nbsp;<\/p>\n\n\n\n<p><a href=\"https:\/\/loganmarchione.com\/2017\/02\/raspberry-pi-ups-monitor-with-nginx-web-monitoring\/\">https:\/\/loganmarchione.com\/2017\/02\/raspberry-pi-ups-monitor-with-nginx-web-monitoring\/<\/a>, although it assumed a working nginx install and assumed that folks know how the nginx.conf &amp; sites-enabled\/default works. I decided to flesh this out and it worked the first time.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Install Nginx &amp; NUT Integration<ol><li>sudo apt-get install nginx&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;- ~ 2 minutes<\/li><li>sudo apt-get install nut-cgi fcgiwrap &nbsp; &lt;- ~ 2 minutes<\/li><\/ol><\/li><\/ol>\n\n\n\n<p>NOTE: You should see this prompt pop up:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/Dy1jLnwXk6ifsJl2kLpm8xNoA62JAB0HyONCPyPqLR1qBCb6hwyWajUXnPqOimvXBbWuUG3Jnfn2_wJcqkNRub1Np9CGsSixgx4tTSLKfznSbaEntR3v5EJ4LznX5Cx40k_qMpWT\" alt=\"\"\/><\/figure>\n\n\n\n<p>Go ahead and select Y, to install the package maintainer\u2019s version. When the install is complete, you will then need to re-edit the \/etc\/nut\/hosts.conf to add the line we inserted and got overwritten above in Step 5, Item 3, as shown here:<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\"><li>Edit \/etc\/nut\/hosts.conf<\/li><\/ol>\n\n\n\n<ol class=\"wp-block-list\"><li>sudo nano \/etc\/nut\/hosts.conf<\/li><li>Add:<\/li><\/ol>\n\n\n\n<p>MONITOR ups01@192.168.0.201 &#8220;CP1500 AVR UPS&#8221;<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\"><li>Edit the \/etc\/nginx\/sites-enabled\/default file:<ol><li>sudo nano \/etc\/nginx\/sites-enabled\/default<\/li><li>Modify these lines:<\/li><\/ol><\/li><\/ol>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;listen 80 default_server;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;listen [::]:80 default_server;<\/p>\n\n\n\n<p>To<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;listen 80<strong>80<\/strong> default_server;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;listen [::]:80<strong>80<\/strong> default_server;<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\"><li>Insert the blue portion only inside of the existing server {} section. DO NOT copy the red parts, and make sure you are pasting this INSIDE of the server {} section in this file! So where do I paste the blue stuff? Immediately after the last comments after the 8080 ports above: right under the line that read: <strong># include snippets\/snakeoil.conf;<\/strong><\/li><\/ol>\n\n\n\n<p>server {<\/p>\n\n\n\n<p>&#8230;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;location \/nut {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alias \/usr\/share\/nut\/www\/;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try_files $uri $uri\/ \/index.html;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;location \/cgi-bin\/ {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gzip off;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;root \/usr\/lib;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include fastcgi_params;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fastcgi_pass unix:\/var\/run\/fcgiwrap.socket;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fastcgi_param SCRIPT_FILENAME&nbsp; $document_root$fastcgi_script_name;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<\/p>\n\n\n\n<p>&#8230;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"4\"><li>Set the permissions and ownership properly, and start the services:<ol><li>sudo chmod 644 \/etc\/nut\/hosts.conf<\/li><li>sudo chmod 644 \/etc\/nut\/*.html<\/li><li>sudo chown www-data:www-data \/usr\/lib\/cgi-bin\/nut\/*.cgi<\/li><li>sudo systemctl restart fcgiwrap.service<\/li><li>sudo systemctl restart fcgiwrap.socket<\/li><li>sudo systemctl restart nginx<\/li><\/ol><\/li><\/ol>\n\n\n\n<p>To verify: Go to a browser and enter: <a href=\"http:\/\/192.168.0.201:8080\/nut\">http:\/\/192.168.0.201:8080\/nut<\/a> (use your Raspberry Pi\u2019s IP address) and you should see the following pages:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/q_INyX-azjmFEsyuhxBIBTXuobmr30ntzUDh0VcwVbM6ANYzWobpXc68kbHk2BzjtgiSwhwN-ANOVaZ7O8LFV2d5tsF9BA_vBTkYYt8jx1ABldDvHiQMDajmlE1VLIBgSQReC5pE\" alt=\"\"\/><\/figure>\n\n\n\n<p>Click on the Statistics link and see:&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/GXrgaOFWvKsRNFPl8ji_rLqI46-hOg5S6jc9LX4lUMlTDy7N8bqaoUlfkE_DaOF9S6hBIigfOWwgtCYafEQLOjBT3sos01myxVNKzDw3CSSuG5e2LSqY6MG36xaFX0XyzEhysuTL\" alt=\"\"\/><\/figure>\n\n\n\n<p>Click on the UPS link in the System column from above, and see:&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/Buk9TL6ydtwoNyq25pFk6CqOTLl85JC4e02lX7BgCY16OUJ4qzGktcxvACxb8qzFq7knEcCLFK-Y3LUWYCufpXHTIxG3OstfIh_Ike4JgQIThKFeCi3gnLiRo5BqOAMViwnnqJeQ\" width=\"624\" height=\"431\"><\/h2>\n\n\n\n<h1 class=\"wp-block-heading\">Going Further<\/h1>\n\n\n\n<p><a href=\"https:\/\/www.home-assistant.io\/integrations\/nut\/\">Home Assistant Integration<\/a><\/p>\n\n\n\n<p>I used the first \u201colder, smaller\u201d SD Card I found: a&nbsp; SanDisk 32GB. After all of this software was installed and running, this was my df profile:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/FxpenJGHALZE3wdPIvF1Rr8q_v65uHmHpofOvKJUPc5ByjM7bVAdNH6_y4rLe3PLgECswWM0JFaJEIxpV4WBXvodS5jM0zSbMboGLTtQtg4jz_KrI9dIar5j7K97r5GeuxYlomQY\" alt=\"\"\/><\/figure>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p><strong>Document Information<\/strong><\/p>\n\n\n\n<p>Project UPS Monitor<\/p>\n\n\n\n<p>Description Monitoring a CyberPower UPS with a Raspberry Pi Zero W, with Web Server &amp;&nbsp; Home Assistant Integration<\/p>\n\n\n\n<p>Created 2021-02-17 by MIke Porter<\/p>\n\n\n\n<p>Update History<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td>Date\/s<\/td><td>Change\/s<\/td><\/tr><tr><td>2021-02-17 &#8211;&nbsp;2021-02-19<\/td><td>Created graphics outlines and re-organized content. Generally cleaned it up considerably from the original notes.<\/td><\/tr><\/tbody><\/table><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Here on Whidbey Island in Washington state, we live in an area where the power goes out regularly. Heavy winds and\/or snow\/ice break breaches or fell trees onto power lines and\u2026 darkness. Sadness. Often, the power \u201cblinks\u201d, or at least we think it did, but have no way to verify. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":30,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4],"tags":[18,7,17,13],"class_list":["post-1","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-raspberry-pi","tag-home-assistant-io","tag-raspberry-pi","tag-ups","tag-work-from-home"],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/varmintworks.com\/varmint-blog\/wp-content\/uploads\/2021\/02\/20210218_125726-01.jpeg?fit=1682%2C1216&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/varmintworks.com\/varmint-blog\/wp-json\/wp\/v2\/posts\/1","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/varmintworks.com\/varmint-blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/varmintworks.com\/varmint-blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/varmintworks.com\/varmint-blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/varmintworks.com\/varmint-blog\/wp-json\/wp\/v2\/comments?post=1"}],"version-history":[{"count":2,"href":"https:\/\/varmintworks.com\/varmint-blog\/wp-json\/wp\/v2\/posts\/1\/revisions"}],"predecessor-version":[{"id":173,"href":"https:\/\/varmintworks.com\/varmint-blog\/wp-json\/wp\/v2\/posts\/1\/revisions\/173"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/varmintworks.com\/varmint-blog\/wp-json\/wp\/v2\/media\/30"}],"wp:attachment":[{"href":"https:\/\/varmintworks.com\/varmint-blog\/wp-json\/wp\/v2\/media?parent=1"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/varmintworks.com\/varmint-blog\/wp-json\/wp\/v2\/categories?post=1"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/varmintworks.com\/varmint-blog\/wp-json\/wp\/v2\/tags?post=1"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}