Help with apcupsd

Posted on
Sun Feb 10, 2013 9:28 pm
DU Lou offline
Posts: 279
Joined: Mar 08, 2012
Location: Florida

Help with apcupsd

I wanted to be fair to Ben's UPS Plugin and didnt want to monopolize his UPS Plugin Thread http://www.perceptiveautomation.com/userforum/viewtopic.php?f=33&t=9559&start=0 with more questions about this hack so I started a new thread here.

Is there anyone who implemented APCUPSD in Mountain Lion or recently enough that can speak to getting it installed when hooked with a single UPS?

Many Thanks!
~Lou

Posted on
Sun Feb 10, 2013 11:40 pm
berkinet offline
User avatar
Posts: 3290
Joined: Nov 18, 2008
Location: Berkeley, CA, USA & Mougins, France

Re: Help with apcupsd

Yes. I have it installed on OS-X server 10.8.2 and it works locally and remotely. The basic install is simple, it is a package installation. But, the initial configuration can be a bit daunting. FYI, the files you need to edit are in /etc/apcupsd

If you need any help installing, configuring or operating it, let me know. Also, I posted a simple AppleScript to import UPS data into Indigo variables and posted it on the previous thread.

Posted on
Mon Feb 11, 2013 6:55 pm
berkinet offline
User avatar
Posts: 3290
Joined: Nov 18, 2008
Location: Berkeley, CA, USA & Mougins, France

Re: Help with apcupsd

I have converted the AppleScript noted in this topic to Python. This script does not require the apcaccess program and can run on Indigo 5 or 6.

A few notes:
  1. The script must be called from inside Indigo, preferably from file rather than embedded - just in case it should hang while reading the UPS data.
  2. You must create 2 Indigo variables: apcUpsHost and apcUpsPort.
      apcUpsHost is the IP Address, FQDN or bonjour name of the host running the apcupsd daemon (I.e. the host the UPS is connected to). Eg: 192.168.1.1, indigo.local, localhost, my.indigo.com, etc.
      apcUpsPort is the port assigned to the APC apcupsd daemon Netserver. Usually 3551.
  3. Data read from the UPS will be saved to variables of the same names used in the apcaccess report.
      I.e. any of the following: ALARMDEL, BATTDATE, BATTV, BCHARGE, CABLE, CUMONBATT, DATE, DRIVER, FIRMWARE, HITRANS, HOSTNAME, LASTXFER, LINEV, LOADPCT, LOTRANS, MAXTIME, MBATTCHG, MINTIMEL, MODEL, NOMBATTV, NOMINV, NOMPOWER, NUMXFERS, SELFTEST, SENSE, SERIALNO, STARTTIME, STATFLAG, STATUS, TIMELEFT, TONBATT, UPSMODE, UPSNAME, VERSION, XOFFBATT, XONBATT
  4. You just need to create variables for the data items you wish. If you do not create a variable for a given item, it will be silently ignored. You may place the variables in a folder if you wish.

Save the script (see below) as apcupsdata.py (or any name you like, with a .py extension), create a schedule to run it as often as you wish and go. That's it.

For now, I think this is probably sufficient. As noted in the other topic re: the UPS plugin, I do not presently see any increased value in having this instantiated as a plugin (creating a UPS device with states representing the data items) instead of a script with variables representing the data items. But, if there is a convincing argument, I could change my mind. Or, someone else is free to take this work and adapt it as they wish.

The script:
Code: Select all
"""Revised by berkinet from
https://github.com/BrightcoveOS/Diamond/blob/master/src/collectors/apcupsd/apcupsd.py
"""
import socket
from struct import pack
import re
import indigo


def getData(apcHostname, apcPort):
    # Get the data via TCP stream
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((apcHostname, apcPort))

    # Packet is pad byte, size byte, and command
    s.send(pack('xb6s', 6, 'status'))

    # Ditch the header
    s.recv(1024)
    data = s.recv(1024)

    # We're done. Close the socket
    s.close()
    return data


apcHostname = indigo.variables["apcUpsHost"].value
apcPort = int(indigo.variables["apcUpsPort"].value)

metrics = {}
raw = {}

data = getData(apcHostname, apcPort)

data = data.split('\n\x00')
for d in data:
    matches = re.search("([A-Z]+)\s+:\s+(.*)$", d)

    if matches:
        value = matches.group(2).strip()
        raw[matches.group(1)] = matches.group(2).strip()

        metrics[matches.group(1)] = value

for metric in metrics:  # config['metrics']:
    value = metrics[metric]

    try:
        indigo.variable.updateValue(metric, value)
    except:
        pass
Last edited by berkinet on Tue Sep 10, 2013 2:50 am, edited 1 time in total.

Posted on
Mon Feb 18, 2013 3:45 pm
DU Lou offline
Posts: 279
Joined: Mar 08, 2012
Location: Florida

Re: Help with apcupsd

berkinet wrote:
FYI, the files you need to edit are in /etc/apcupsd.


This is exactly where I got stuck! After I installed the file the script opened automatically for editing however it was locked so I couldn't edit it. I couldn't find the /etc/apcupsd location either. (Still fairly new to OS X file structure) :)

~Lou

Posted on
Mon Feb 18, 2013 3:59 pm
berkinet offline
User avatar
Posts: 3290
Joined: Nov 18, 2008
Location: Berkeley, CA, USA & Mougins, France

Re: Help with apcupsd

By default, the Finder hides most system files and directories. To see those files you can either use the Terminal app (actually a UNIX shell session) or, from the Finder select Go -> Go to Folder... and enter /etc/apcupsd

Once you have the folder open, you can use Command-I to get info and change the file permissions so you can edit it.

Posted on
Wed Mar 06, 2013 7:41 am
durosity offline
User avatar
Posts: 4320
Joined: May 10, 2012
Location: Newcastle Upon Tyne, Ye Ol' England.

Re: Help with apcupsd

I’m having a bit of an issue with this script. Whenever i run apcaccess from the command prompt i get the output i’d expect:
Code: Select all
APC      : 001,043,1083
DATE     : 2013-03-06 13:29:21 +0000 
HOSTNAME : hawk.durosity.net
VERSION  : 3.14.10 (13 September 2011) darwin
UPSNAME  : hawk.durosity.net
CABLE    : USB Cable
DRIVER   : USB UPS Driver
UPSMODE  : Stand Alone
STARTTIME: 2013-03-06 12:37:06 +0000 
MODEL    : Smart-UPS 1500 RM
STATUS   : ONLINE
LINEV    : 252.0 Volts
LOADPCT  :   0.0 Percent Load Capacity
BCHARGE  : 100.0 Percent
TIMELEFT : 339.0 Minutes
MBATTCHG : 5 Percent
MINTIMEL : 3 Minutes
MAXTIME  : 0 Seconds
OUTPUTV  : 223.2 Volts
SENSE    : High
DWAKE    : -01 Seconds
DSHUTD   : 090 Seconds
LOTRANS  : 208.0 Volts
HITRANS  : 253.0 Volts
RETPCT   : 000.0 Percent
ITEMP    : 14.4 C Internal
ALARMDEL : 30 seconds
BATTV    : 27.7 Volts
LINEFREQ : 50.0 Hz
LASTXFER : Automatic or explicit self test
NUMXFERS : 0
TONBATT  : 0 seconds
CUMONBATT: 0 seconds
XOFFBATT : N/A
SELFTEST : NO
STESTI   : 14 days
STATFLAG : 0x07000008 Status Flag
MANDATE  : 2008-04-26
SERIALNO : AS0817332616
BATTDATE : 2008-04-26
NOMOUTV  : 230 Volts
NOMBATTV :  24.0 Volts
FIRMWARE : 617.3.I USB FW:8.1
END APC  : 2013-03-06 13:29:45 +0000 


However when i run the script (either embedded or as a separate .py file) in indigo (with the host name set as either hawk.durosity.net or localhost and the appropriate port) the only variable set is the DATE entry with 2013-03-06 13:35:30 +0000. HOSTNAME with hawk.durosity.net and VERSION with 3.14.10 (13 September 2011) darwin. If i then go back to the command prompt and run apcaccess i just get “Error contacting apcupsd @ hawk.durosity.net:3551: Connection refused” which then won’t unlock until i reinstall APCUPSD.. even restarting the server didn’t seem to fix it. Also if i try to run the script again i get:

Code: Select all
  Script Error                    apcupsdata.py: (61, 'Connection refused')
  Script Error                    Exception Traceback (most recent call shown last):

     apcupsdata.py, line 33, at top level
     apcupsdata.py, line 13, in getData
     apcupsdata.py, line 0, in connect
error: (61, 'Connection refused')


Any ideas?

(Also on a side note.. I know that APCUPSD can be setup to handle multiple devices, but ’m presuming that this script can’t be configured to work with multiple UPSes can it? If not possibly a convincing argument for a plugin rather than a script?.. then we could have a device for each UPS we want to monitor which in my case will be 4 soon)

UPDATE: I’ve found that entering sudo /sbin/apcupsd stop then sudo /sbin/apcupsd start into the command prompt unlocks it without need to reinstall the system.. but still doesn’t help get variables populated in indigo :(

Computer says no.

Posted on
Wed Mar 06, 2013 8:47 am
philc offline
Posts: 156
Joined: May 17, 2011

Re: Help with apcupsd

Same problem here - exactly the same symptoms.

I have apcagent running and the second the script executes, apcagent also loses connection. Looking in the system report, the UPS still shows a connection via USB - so the underlying connection is there, but the communication breaks.

Posted on
Wed Mar 06, 2013 9:08 am
berkinet offline
User avatar
Posts: 3290
Joined: Nov 18, 2008
Location: Berkeley, CA, USA & Mougins, France

Re: Help with apcupsd

FWIW, I am also having problems. Something has changed. In fact, I was seeing the script spawn over and over creating several zombie processes. I will be traveling for a few days and cannot get to this immediately -- maybe someone else here can see if they can suss out the problem.

Posted on
Wed Mar 06, 2013 1:20 pm
durosity offline
User avatar
Posts: 4320
Joined: May 10, 2012
Location: Newcastle Upon Tyne, Ye Ol' England.

Re: Help with apcupsd

berkinet wrote:
I will be traveling for a few days and cannot get to this immediately


Pft.. cancel your travel plans and fix it dammit! :wink: We don’t pay you to go gallivanting around the world.. in fact.. we don’t even pay you at all!


Seriously though it is strange.. i’ve got it installed on my MBP.. when i hook the UPS to it and tell the script to use it instead it works fine. Just for reference my server is running on the server version of OSX 10.8.. but i wouldn’t have thought that’d make a difference in this case. Alas it’s beyond my abilities to work out what’s wrong with it..

Computer says no.

Posted on
Wed Mar 06, 2013 3:47 pm
philc offline
Posts: 156
Joined: May 17, 2011

Re: Help with apcupsd

Berkinet,
Could this be like the AD2USB plugin? Only one program can talk to the USB port at a time, but if you use SER2SOCK it might allow communication via IP?
I know APCUPSD does network service...that's why I run it...but locally it just looks at the localhost (127.0.0.1). I also know that if APCUPSD is running, energy saver on the Mac doesn't realize there's a UPS connected. Shutdown settings have to be created in the apcupsd.conf file. Maybe that's got something to do with it. I dunno...I'm a numpty when it comes to this stuff.
What I can definitely say is that this is a GREAT script if you can get it running. I have a big honkin' UPS in my server cage, which powers all of my electronics closet. When the power fails, I have my two unRAID servers shut down within five minutes. That extends the runtime of the UPS from about 60 minutes to about 180, which bridges me over the most common outages and keeps the phones and alarm system going. Problem is that when power return within that three hours, I have to go manually intervene to restart the unRAID servers and mount them. If I'm at work or out of town, it usually means a pretty stern phone call from CINCHOUSE asking why the hell she can't get Cinderella going for the four year old.
With your script, I'll be able to tell when power has returned and Indigo can send the magic packet to wake the servers, then remount the drives. It would allow for a lot of other post-return-of-electricity housecleaning as well.
I can't use Ben's plugin because it pulls from the Energy Saver pref pane (which I don't see for the reasons above).
Let me know what else you need.
Best,
Phil

Posted on
Wed Mar 06, 2013 3:49 pm
berkinet offline
User avatar
Posts: 3290
Joined: Nov 18, 2008
Location: Berkeley, CA, USA & Mougins, France

Re: Help with apcupsd

durosity wrote:
Pft.. cancel your travel plans and fix it dammit! :wink: We don’t pay you to go gallivanting around the world.. in fact.. we don’t even pay you at all!

:lol:

Posted on
Wed Mar 06, 2013 3:53 pm
berkinet offline
User avatar
Posts: 3290
Joined: Nov 18, 2008
Location: Berkeley, CA, USA & Mougins, France

Re: Help with apcupsd

philc wrote:
Could this be like the AD2USB plugin? Only one program can talk to the USB port at a time, but if you use SER2SOCK it might allow communication via IP?

I doubt this is the issue as the is no serial/USB involved. Clearly, something has changed, but the question is what: Indigo, MacOS, the calendar?

Posted on
Sat Jun 15, 2013 8:49 pm
hamw offline
Posts: 1212
Joined: Mar 31, 2008

Re: Help with apcupsd

What's the status of this script? I implemented Ben's plugin, but it looks like this script gives more info?

Posted on
Sun Sep 08, 2013 6:38 pm
durosity offline
User avatar
Posts: 4320
Joined: May 10, 2012
Location: Newcastle Upon Tyne, Ye Ol' England.

Re: Help with apcupsd

I don’t suppose we had any luck getting this up and running did we?.. alas it’s way above my very rudimentary understanding of python! Also i don’t suppose any form of bribery would make someone *cough cough berkinet* making this into a plugin that’d support multiple UPSes? ;)

Computer says no.

Posted on
Tue Sep 10, 2013 8:51 am
berkinet offline
User avatar
Posts: 3290
Joined: Nov 18, 2008
Location: Berkeley, CA, USA & Mougins, France

Re: Help with apcupsd

Well, so far no bribe has arrived... But, I am looking into this anyway.

It sure looks like 10.8 broke apcupsd. The script I posted looks fine, it is the apcupsd daemon that has issues. apcupsd loads, but then quits when it receives a query).

I have the source now and will see what I can do to resolve the problem.

Who is online

Users browsing this forum: No registered users and 6 guests