[Release] SmartUPS VBS Version

SmartUPS VBS Version

Purpose

Perform a graceful Hub shutdown when power is lost.

Developed for, and tested on a Windows 10 system functioning as the interface between the APC UPS and the HE Hub, but may work on any system supporting apcupsd and Visual Basic Script.

This package was derived from Steve Wright's APC UPS Monitor Driver release, but does not use or require a PHP server.

Requirements

  • Hubitat Hub plugged into an APC UPS battery backup plug
  • The APC communication cable plugged into a Windows machine's USB port
  • apcupsd.org's package installed on same Windows machine

Should your APC UPS support WiFi consider LG Kahn's release
For Non-windows systems consider Steve Wright's APC UPS Monitor Driver

Features

  • Reports UPS Device Events in Hubitat virtual device attribute, lastEvent
    • onbattery - mains power failed
    • offbattery - mains power restored
    • doshutdown - UPS about to shutdown
    • COMMLOST - apcupsd lost UPS communication
    • commok - apcupsd UPS communication restored
  • Sends UPS Device Statistics: every "user defined" minutes, using a repeating Windows Scheduled Task or the optional EventGhost webserver.
  • Support modules are Visual Basic Script
  • Executes without being logged in to Windows when using Windows Task Scheduler for triggering
  • Remotely reboot Windows machine from HE

Documentation and Source Code

6 Likes

[UPDATE] Oct 11, 2020 12:40 EDT

  • 2020-10-11 V0.1.1

    • When hub reboots, autostart optional EventGhost data refresh cycle.
    • When using EventGhost for device information and Windows reboots, restart EventGhost without logging in by creating a Windows Scheduler Task
    • See Github documentation for setup instructions
  • 2020-10-10 V0.1.0 Add command to reboot the Windows machine from HE with EventGhost command rebootWindows. See Github documentation for setup instructions

  • 2020-10-09 V0.0.9 Add support for any event including newly added commfailure.vbs and commok.vbs
    These scripts must be copied from Github to C:/apcupsd/etc/apcupsd/

  • 2020-10-08 V0.0.8 Fixed: Errors logged in hubitat log when apcupsd status was COMMLOST. Windows app apcupsd somehow lost contact UPS device. Needed a Windows reboot to recover.

[UPDATE] Nov 19, 2020 17:00 EST

  • Added field windowsbatterypercent, the actual battery percentage from windows system. Updated modules smartUPS.VBS and smartUPS.groovy.

Using RM with this field allows the windows laptop with its own battery backup that is plugged into a zigbee, zwave or wifi plug, to be removed from the UPS battery when there is a power failure.

Nice job @arnb. I have set this up today with my new APC UPS. Mostly it went really smoothly, following your instructions from the GitHub repository. A couple of things I noted were:

It may pay to be more specific about the name of the event in EventGhost. I messed around with the WebServer settings, so can't remember what the default prefix is, but I set the prefix in the WebServer plugin to WS and setup the event for the macro as WS.HE.smartUPS.

With that said, it would also be nice to have the name of the event configurable from the HE driver, allowing people to configure whatever they want in EventGhost.

EDIT: @FriedCheese2006 rightly points out that I got this wrong, the instructions do refer to cscript, not wscript as I talk about below.
The other thing I noticed when setting up the action for running the vbs script was that, using the instructions you provided for EventGhost, a window popped up for a split second before disappearing. I was able to use a mixture of the Task Scheduler notes, suggesting the use of cscript instead of wscript to stop this (there were one or two other things I tweaked, but I expect this was what fixed it).

Thanks again for setting this up.

1 Like

@sburke781 I just worked through setting this up.

The instructions don't mention to use wscript in EventGhost...it does callout using cscript:

The default prefix for the web server is HTTP.

You can edit line 168 of the device driver to change the event name:

1 Like

I will get back to your comments @FriedCheese2006, while I thought I had checked the notes carefully before posting, there is every possibility I had not.....

I'd add that the odour from a new unit may play havoc with peoples breathing if located closed to their work area, i.e. on their desktop. This may be something specific for me... but I expect it is a reality (not something else causing this issue for me) . Placing the UPS on the floor and turning on a fan "helped"....

EDIT: I do appear to have put this on the wrong thread (sorry @arnb ), still, hopefully useful for people to know, but it was the continuation of some comments I made here:

Luckily, I picked mine up to provide backup power for my comms closet (network rack,server) that I installed some cabinet ventilations fans in the ceiling for. Everything is exhausted into the attic.

1 Like

Have you had a chance to test a power outage yet? I finally got around to it tonight. For some reason, once I go on battery, I stop getting device updates, even with a manual refresh button push.

@arnb Any ideas? I can see the smartUPS.vbs running in EventGhost, but nothing is making it back to the hub.

I continue to have power to the devices in my study, let me check the updates back to HE....

Ah...I have my UPS passing through a SmartThings WiFi plug so I can toggle power if need be. Also means I can simulate an outage on demand.

I'm getting updates no problem when on main power, just not when I flip to battery.

That is weird, me too. The status seems to update, but other attributes like battery percentage, etc, don't seem to update when on battery....

Yeah...I was just getting there. Seems like the status change is breaking parsing for the rest of the message or something along those lines.

If you have time, turn on the logging (I'll do the same). There is a pretty clear split in the code that handles these two scenarios, so hopefully we can work out what's happening.

Yep, the driver only updates the broader list of attributes when the status of ONLINE is sent, which is when operating on mains power. Mine sends a status of ONBATT when operating on battery power.

@arnb - any chance you could change this in the driver? I'll change it in my copy on my hub, but would be nice for others to also have these updated with each message that is received.

I'm still seeing the update making it back and the message being parsed, but the attribute updates aren't making it for some reason. Doing a comparison of an update message when on power and one when on battery looks the exact same except the attribute changes.

On main power:

Summary
dev:3592022-06-18 10:44:03.695 pm errorSmartUps Unknown message received Referer:null  VBReferer:null body: 
dev:3592022-06-18 10:44:03.692 pm debugPARSED LAN EVENT Received: [mac:null, ip:0a1553f8, port:20fb, headers:[HTTP/1.0 200 OK:null, Server:EventGhost/0.5.0-rc6, Date:Sun, 19 Jun 2022 02:44:04 GMT, Content-type:text/html, Content-Length:26], body:, header:HTTP/1.0 200 OK
Server: EventGhost/0.5.0-rc6
Date: Sun, 19 Jun 2022 02:44:04 GMT
Content-type: text/html
Content-Length: 26
, status:200]
app:3052022-06-18 10:44:03.668 pm infoEvent: UPS battery 62
dev:3592022-06-18 10:44:03.587 pm infoDevice update received.
dev:3592022-06-18 10:44:03.585 pm traceProcessing LAN event notification...
dev:3592022-06-18 10:44:03.582 pm debugPARSED LAN EVENT Received: [mac:null, ip:0a1553f8, port:ca42, headers:[POST /notify HTTP/1.1:null, VBReferer:apcupsd, Accept:*/*, Connection:close, User-Agent:Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5), Host:10.22.83.200:39501, Accept-Language:en-us, Content-Length:1014, Content-Type:text/html], body:{"data":{"device":{"apc":"001,037,0946","date":"2022-06-18 22:43:43 -0500","hostname":"Not-A-Server","version":"3.14.14 (31 May 2016) mingw","upsname":"Not-A-Server","cable":"USB Cable","driver":"USB UPS Driver","upsmode":"Stand Alone","starttime":"2022-06-17 21:56:02 -0500","model":"Back-UPS NS 1500M2","status":"ONLINE","linev":"123.0 Volts","loadpct":"18.0 Percent","bcharge":"62.0 Percent","timeleft":"23.1 Minutes","mbattchg":"5 Percent","mintimel":"3 Minutes","maxtime":"0 Seconds","sense":"Medium","lotrans":"88.0 Volts","hitrans":"142.0 Volts","alarmdel":"No alarm","battv":"25.5 Volts","lastxfer":"Unacceptable line voltage changes","numxfers":"3","xonbatt":"2022-06-18 22:41:22 -0500","tonbatt":"0 Seconds","cumonbatt":"851 Seconds","xoffbatt":"2022-06-18 22:42:50 -0500","selftest":"NO","statflag":"0x05000008","serialno":"0B2211N10902","battdate":"2022-03-11","nominv":"120 Volts","nombattv":"24.0 Volts","nompower":"900 Watts","firmware":"957.e4 .D USB FW:e4","end apc":"2022-06-18 22:44:04 -0500"}}}, header:POST /notify HTTP/1.1
VBReferer: apcupsd
Accept: */*
Connection: close
User-Agent: Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5)
Host: 10.22.83.200:39501
Accept-Language: en-us
Content-Length: 1014
Content-Type: text/html
]
dev:3592022-06-18 10:44:03.173 pm debugRefresh scheduled 5 300
dev:3592022-06-18 10:44:03.171 pm debugSending Refresh to Windows EventGhost at 10.21.83.248:8443
dev:3592022-06-18 10:44:03.169 pm debugEntered Refresh

On battery:

Summary
dev:3592022-06-18 10:46:01.613 pm debugPARSED LAN EVENT Received: [mac:null, ip:0a1553f8, port:20fb, headers:[HTTP/1.0 200 OK:null, Server:EventGhost/0.5.0-rc6, Date:Sun, 19 Jun 2022 02:46:02 GMT, Content-type:text/html, Content-Length:26], body:, header:HTTP/1.0 200 OK
Server: EventGhost/0.5.0-rc6
Date: Sun, 19 Jun 2022 02:46:02 GMT
Content-type: text/html
Content-Length: 26
, status:200]
dev:3592022-06-18 10:46:01.549 pm warnSmartUPS Not-A-Server driver is ONBATT
dev:3592022-06-18 10:46:01.544 pm infoDevice update received.
dev:3592022-06-18 10:46:01.542 pm traceProcessing LAN event notification...
dev:3592022-06-18 10:46:01.539 pm debugPARSED LAN EVENT Received: [mac:null, ip:0a1553f8, port:cee7, headers:[POST /notify HTTP/1.1:null, VBReferer:apcupsd, Accept:*/*, Connection:close, User-Agent:Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5), Host:10.22.83.200:39501, Accept-Language:en-us, Content-Length:1013, Content-Type:text/html], body:{"data":{"device":{"apc":"001,037,0945","date":"2022-06-18 22:46:00 -0500","hostname":"Not-A-Server","version":"3.14.14 (31 May 2016) mingw","upsname":"Not-A-Server","cable":"USB Cable","driver":"USB UPS Driver","upsmode":"Stand Alone","starttime":"2022-06-17 21:56:02 -0500","model":"Back-UPS NS 1500M2","status":"ONBATT","linev":"0.0 Volts","loadpct":"19.0 Percent","bcharge":"61.0 Percent","timeleft":"21.1 Minutes","mbattchg":"5 Percent","mintimel":"3 Minutes","maxtime":"0 Seconds","sense":"Medium","lotrans":"88.0 Volts","hitrans":"142.0 Volts","alarmdel":"No alarm","battv":"24.0 Volts","lastxfer":"Unacceptable line voltage changes","numxfers":"4","xonbatt":"2022-06-18 22:44:55 -0500","tonbatt":"67 Seconds","cumonbatt":"918 Seconds","xoffbatt":"2022-06-18 22:42:50 -0500","selftest":"NO","statflag":"0x05060010","serialno":"0B2211N10902","battdate":"2022-03-11","nominv":"120 Volts","nombattv":"24.0 Volts","nompower":"900 Watts","firmware":"957.e4 .D USB FW:e4","end apc":"2022-06-18 22:46:02 -0500"}}}, header:POST /notify HTTP/1.1
VBReferer: apcupsd
Accept: */*
Connection: close
User-Agent: Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5)
Host: 10.22.83.200:39501
Accept-Language: en-us
Content-Length: 1013
Content-Type: text/html
]
dev:3592022-06-18 10:46:01.163 pm debugRefresh scheduled 5 300
dev:3592022-06-18 10:46:01.161 pm debugSending Refresh to Windows EventGhost at 10.21.83.248:8443
dev:3592022-06-18 10:46:01.158 pm debugEntered Refresh```

Figured it out. The "parse" routine (is that the proper term) was set to only update the device info if the status is "ONLINE" and to only give an event update for any other status. Adding this line should ensure that the device details are always updated when a message is received.

Add this at line 204:

updateDeviceStatus(json.data.device)

Like this:

2 Likes

There's a spot in the code where the status is checked. When you are on mains power it is ONLINE. If this is the case the driver calls a section in the code called updateDeviceStatus, which is what updates the attributes. If the status is ONBATT, the only change that is made is to the lastEvent attribute, along with the log entry you saw for "SmartUPS Not-A-Server driver is ONBATT".

Great minds... :slight_smile: I just moved the IF down and reversed the condition, i.e. not ONLINE. Same effect.

1 Like

Yeah...that seems cleaner. I think when arnb set his up, he was only concerned with the status information for an outage (looking at his RM setup) and probably why he was skipping update the device details. I have a much simpler RM setup that's using the battery percentage to trigger sending notifications and sending an event to EventGhost to run a shutdown script for a few devices in my rack.

2 Likes