APC UPS LUA script for powerchute

Moderator: leecollings

Post Reply
Ittiz
Posts: 48
Joined: Tuesday 03 January 2017 0:37
Target OS: Linux
Domoticz version: 13939
Location: USA
Contact:

APC UPS LUA script for powerchute

Post by Ittiz »

I have an old APC UPS (1400XL) I decided to use as a power backup for my automation server. If you install the serial cable with an APC software called PowerCute you can get really useful data out of the UPS. I made a LUA parser script using an HTTPS poller to poll PowerChute and output useful data to dummy devices in Domoticz. It gets current line in voltage, battery voltage, and battery charge. It allows you to send notifications if you power fails, or even if you have a power blink. It's useful for sending notifications if you have a power failure. There are many other sensors in the UPS but I didn't add them because they were more specific for the device, like server power usage. A side note I'm in the US so I configured it for a 120v electrical grid, but it's customizable. I've provided the parser script below. It'll only work on the new beta versions of Domoticz and you'll need curl.

Code: Select all

s = request['content'];

--PowerChute logon info
local pca = "127.0.0.1" -- ip or address, localhost if the computer is it's own server
local pcp = "6547" -- port, usually stays the same
local pcu = "user" -- powerchute user
local pcpw = "password" -- powerchute password

--Devices
local sdidx = 99 -- idx of the Alert type dummy device
local sdn = "UPS status" -- name of the Alert type dummy device
local acvidx = 74 -- idx of the AC (mains) voltage dummy device
local acvn = "Pole 1 Vac" -- name of the AC (mains) voltage dummy device
local dcvidx = 75 -- idx of the DC (battery) voltage dummy device
local dcvn = "Server Battery Vdc" -- name of the DC (battery) voltage dummy device
local bcidx = 76 -- idx of the battery charge % dummy device
local bcn = "Server Battery Charge" -- name of the battery charge % dummy device

--Voltage values

local BoostVAC = 114 -- Minimal voltage before stepping up voltage
local BuckVAC = 126 -- Maximal voltage before stepping down voltage
local UnderVAC = 103 -- Minimal voltage before switching to battery
local OverVAC = 132 -- Maximal voltage before switching to battery

--Don't change below this line unless you know what you're doing

commandArray = {}
local apc = assert(io.popen('curl -i -k "https://' .. pca .. ':' .. pcp .. '/j_security_check?j_username=' .. pcu .. '&j_password=' .. pcpw .. '"'))
local thedata = apc:read('*all')
apc:close()
--print(thedata) --debug
local thecookie = string.sub(thedata, string.find(thedata, "Set-")+12, string.find(thedata, ";Path=/;Secure")-1)
apc = assert(io.popen('curl -k --cookie "' .. thecookie .. '" https://' .. pca .. ':' .. pcp .. '/status'))
thedata = apc:read('*all')
apc:close()

local stop1 = string.find(thedata, 'Line Voltage</td>')+141
local stop2 = string.find(thedata, "&nbsp;VAC")-1
local linevoltage = tonumber(string.sub(thedata, stop1, stop2))
local thedata = string.sub(thedata, stop1, string.len(thedata))
if (tonumber(otherdevices[acvn]) ~= linevoltage) then
	domoticz_updateDevice(acvidx,"0",linevoltage,"12","255")
end 
--print(linevoltage) --debug
stop1 = string.find(thedata, 'Battery Charge</td>')+143
stop2 = string.find(thedata, "Battery Voltage")-498
local batterycharge = tonumber(string.sub(thedata, stop1, stop2))
local thedata = string.sub(thedata, stop1, string.len(thedata))
if (tonumber(otherdevices[bcn]) ~= batterycharge) then
	domoticz_updateDevice(bcidx,"0",batterycharge,"12","255")
end
--print(batterycharge) --debug
stop1 = string.find(thedata, 'Battery Voltage</td>')+144
stop2 = string.find(thedata, "&nbsp;VDC")-1
local batteryvoltage = tonumber(string.sub(thedata, stop1, stop2))
local thedata = string.sub(thedata, stop1, string.len(thedata))
if (tonumber(otherdevices[dcvn]) ~= batteryvoltage) then
	domoticz_updateDevice(dcvidx,"0",batteryvoltage,"12","255")
end

if (otherdevices[sdn] ~= 'Power Failed' and linevoltage == 0) then
	domoticz_updateDevice(sdidx,"4","Power Failed","12","255") --
elseif (otherdevices[sdn] ~= 'Mains Voltage too High' and linevoltage > OverVAC-0.1) then
	domoticz_updateDevice(sdidx,"3","Mains Voltage too High","12","255") --
elseif (otherdevices[sdn] ~= 'Brown Out' and linevoltage < UnderVAC+0.1 and linevoltage > 0) then
	domoticz_updateDevice(sdidx,"3","Brown Out","12","255") --
elseif  ((otherdevices[sdn] == 'Normal' or otherdevices[sdn] == 'Low Mains Voltage' or otherdevices[sdn] == 'High Mains Voltage')  and linevoltage > UnderVAC and linevoltage < OverVAC and batterycharge ~= 100) then
	domoticz_updateDevice(sdidx,"3","Power Blink","12","255") --
elseif ((otherdevices[sdn] ~= 'Battery Charging' and otherdevices[sdn] ~= 'Normal' and otherdevices[sdn] ~= 'Low Mains Voltage' and otherdevices[sdn] ~= 'High Mains Voltage') and (linevoltage > UnderVAC and linevoltage < OverVAC and batterycharge ~= 100)) then
	domoticz_updateDevice(sdidx,"2","Battery Charging","12","255") --
elseif (otherdevices[sdn] ~= 'Low Mains Voltage' and linevoltage < BoostVAC and linevoltage > UnderVAC and batterycharge == 100) then
	domoticz_updateDevice(sdidx,"0","Low Mains Voltage","12","255") --
elseif (otherdevices[sdn] ~= 'High Mains Voltage' and linevoltage < OverVAC and linevoltage > BuckVAC and batterycharge == 100) then
	domoticz_updateDevice(sdidx,"0","High Mains Voltage","12","255") --
elseif (otherdevices[sdn] ~= 'Normal' and linevoltage > BoostVAC-0.1 and linevoltage < BuckVAC+0.1 and batterycharge == 100) then
	domoticz_updateDevice(sdidx,"1","Normal","12","255") --
else
	--no change
end 

return commandArray

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest