Page 1 of 2

Help with apcupsd

PostPosted: Sun Feb 10, 2013 9:28 pm
by DU Lou
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

Re: Help with apcupsd

PostPosted: Sun Feb 10, 2013 11:40 pm
by berkinet
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.

Re: Help with apcupsd

PostPosted: Mon Feb 11, 2013 6:55 pm
by berkinet
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

Re: Help with apcupsd

PostPosted: Mon Feb 18, 2013 3:45 pm
by DU Lou
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

Re: Help with apcupsd

PostPosted: Mon Feb 18, 2013 3:59 pm
by berkinet
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.

Re: Help with apcupsd

PostPosted: Wed Mar 06, 2013 7:41 am
by durosity
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 :(

Re: Help with apcupsd

PostPosted: Wed Mar 06, 2013 8:47 am
by philc
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.

Re: Help with apcupsd

PostPosted: Wed Mar 06, 2013 9:08 am
by berkinet
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.

Re: Help with apcupsd

PostPosted: Wed Mar 06, 2013 1:20 pm
by durosity
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..

Re: Help with apcupsd

PostPosted: Wed Mar 06, 2013 3:47 pm
by philc
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

Re: Help with apcupsd

PostPosted: Wed Mar 06, 2013 3:49 pm
by berkinet
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:

Re: Help with apcupsd

PostPosted: Wed Mar 06, 2013 3:53 pm
by berkinet
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?

Re: Help with apcupsd

PostPosted: Sat Jun 15, 2013 8:49 pm
by hamw
What's the status of this script? I implemented Ben's plugin, but it looks like this script gives more info?

Re: Help with apcupsd

PostPosted: Sun Sep 08, 2013 6:38 pm
by durosity
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? ;)

Re: Help with apcupsd

PostPosted: Tue Sep 10, 2013 8:51 am
by berkinet
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.