Make APCUPSd tweet for help!

by on Aug.18, 2009, under How-To's, Linux, Software


Please note:  Twitter stopped using “Basic” authentication methods on their API calls and unfortunately this method no longer works.  User “Laramy” (comment below)  has provided a workaround and I am currently working to test this.    This document is still posted for archival reasons.

Well, the world is abuzz with all things twitter so I figured that I’d join the fray.  But rather than tweeting about farts being blasted into an office chair or a toilet that twitters or even a tweeting toaster, I decided to do something useful with this thing called Twitter.  I have APCUPSd running on a Linux box that tweets when the server detects a change in power.  Read more to find out how you can incorporate this into your linux server.

After thinking about my network monitor application that “tweets” when a server goes down or comes up unexpectedly, I thought I’d take a look at seeing what it would take to get notified when my server lost power.  I already installed and configured APCUPSd and it was confirmed as working so now I wanted to be notified on power changes.

The whole “twitter” thing had caught on right when I was looking for a solution to a problem I had.  The issue was that I had a server that was randomly dropping offline and freezing and I needed a way to be notified realtime of when the machine went down.  Well I spent a few days developing a network monitor application that has since then grew into quite a nice suite.

I did some research and found out that the Twitter application had an API that could be called to post updates.  I did some further searching and found how to post to Twitter using PHP-CURL, and later on found that CURL was a standalone application that could be called from the commandline. With that, I found out what I needed to do and set it up.


In order to make this work, you will need the following:

  • Root access on a linux box running APCUPSd with a known working good configuration.
  • Two twitter accounts, one for your phone and one for your monitor application.
  • the CURL application installed on your linux box. (Ubuntu users can apt-get install curl to install it automatically)

I’m not going to cover how to set up a new Twitter account. I’m sure everyone has been beaten over the head with it already.

1:  You must follow your newly created friend

Twitter for SMS will work if these conditions are met:

  1. You have a twitter account that you receive twitter messages on.
  2. Your twitter account must “follow” your monitor application’s twitter account.

In this case, I have set up “trs_netstat” as my monitor application’s twitter account and I follow it with my own twitter account.

Notes: A cellphone plan with unlimited SMS is a REQUIREMENT, I used almost 2200 SMS messages last month.  I also recommend enabling privacy mode on your accounts so that way you’re not broadcasting to the world that your UPS is running on battery.

In order to make sure that your computer can successfully communicate with Twitter, use the syntax below:

root@linux ~ # curl -u {twitter username}:{twitter password} -d status="This is a test message."

If everything works the way it should, you should in turn get a lot of XML data back.  This is a good thing.  If you got a lot of XML data but no post on the Twitter site, look for the following line in your XML

<error>Not found</error>

This means that the URL you specified is incorrect, and other errors will show up in the XML, typically with the <error></error> tags.

2: Create the scripts… or not?

I read up on the APCUPSD website on how to customize how apcupsd behaves when certain events are triggered.

To write your own routine for the powerout action, you create shell script named powerout and put it in the lib directory (normally /etc/apcupsd). When the powerout action is invoked by apcupsd, apccontrol will first give control to your script. If you want apccontrol to continue with the default action, simply exit your script with an exit status of zero. If you do not want apccontrol to continue with the default action, your script should exit with the special exit code of 99. However, in this case, please be aware that you must ensure proper shutdown of your machine if necessary.

So waitasec… APCUPSd supports 21 different configuration options.  So if I want to get notification of all 21 events, I gotta write 21 scripts or create 21 symlinks?  How about, “Heck no!”

By adding a call to my script within apccontrol, I can ensure that I get all the notifications that apcupsd would send and there would be no need to set up 21 symlinks.

In my /etc/apcupsd/apccontrol on line 58, I added the call to my twitapc script shown below:

 if [ $? = 99 ] ; then exit 0 fi fi ${SCRIPTDIR}/twitapc ${1} ${2} ${3} {$4} case "$1" in killpower) echo "Apccontrol doing: ${APCUPSD} --killpower on UPS ${2}" 

The line that starts off with ${SCRIPTDIR} is the one you want to add.  The ${1} ${2} ${3} {$4} is important as this hands off variables that apccontrol was invoked with to twitapc for action.  Some of the variables passed are actions like “killpower” shown above, and one of them includes the UPS name.  You want to keep this information with twitapc so that you get these notifications.

3: Add my script to your configuration (or ….)

This is the twitapc script.  If it looks identical to the apccontrol script, that’s because it is.  I copied apccontrol and changed some of the variables to perform the calls I needed. Theapccontrol script already covered the events with good coverage so there wasn’t a need to rewrite an entire script.

 #!/bin/sh # # Copyright (C) 1999-2002 Riccardo Facchetti # # for apcupsd release 3.14.2 (15 September 2007) - debian # # platforms/apccontrol. Generated from by configure. # # Note, this is a generic file that can be used by most # systems. If a particular system needs to have something # special, start with this file, and put a copy in the # platform subdirectory. # # # These variables are needed for set up the autoconf other variables. # #---------------------------------------------------------------------- # # Script modified for twitapc by FIRESTORM_v1. # # # # # # prefix=/usr exec_prefix=${prefix} APCPID=/var/run/ APCUPSD=/sbin/apcupsd SHUTDOWN=/sbin/shutdown SCRIPTSHELL=/bin/sh SCRIPTDIR=/etc/apcupsd WALL=wall # #Leave the lines above alone, these are the lines you want to edit: # # # tw_user='Twitter Username' tw_pass='Twitter Password' tw_url='' timestamp=$(date +%m%d%Y-%H%M) case "$1" in killpower) msg="Apccontrol doing: ${APCUPSD} --killpower on UPS ${2}" sleep 10 msg="Apccontrol has done: ${APCUPSD} --killpower on UPS ${2}" ;; commfailure) msg="Warning communications lost with UPS ${2}" ;; commok) msg="Communications restored with UPS ${2}" ;; # # powerout, onbattery, offbattery, mainsback events occur # in that order. # powerout) ;; onbattery) msg="Power failure on UPS ${2}. Running on batteries." ;; offbattery) msg="Power has returned on UPS ${2}..." ;; mainsback) msg="Mains power restored on UPS ${2}..." ;; failing) msg="Battery power exhaused on UPS ${2}. Doing shutdown." ;; timeout) msg="Battery time limit exceeded on UPS ${2}. Doing shutdown." ;; loadlimit) msg="Remaining battery charge below limit on UPS ${2}. Doing shutdown." ;; runlimit) msg="Remaining battery runtime below limit on UPS ${2}. Doing shutdown." ;; doreboot) msg="UPS ${2} initiating Reboot Sequence" ;; doshutdown) msg="UPS ${2} initiated Shutdown Sequence" ;; annoyme) msg="Power problems with UPS ${2}. Please logoff." ;; emergency) msg="Emergency Shutdown. Possible battery failure on UPS ${2}." ;; changeme) msg="Emergency! Batteries have failed on UPS ${2}. Change them NOW" ;; remotedown) msg="Remote Shutdown. Beginning Shutdown Sequence." ;; startselftest) ;; endselftest) ;; battdetach) ;; twittest) msg="TwitAPC Test Message" echo "Test message sent. Please check your phone." ;; battattach) ;; *) echo "Usage: ${0##*/} command" echo " warning: this script is intended to be launched by" echo " apcupsd and should never be launched by users." echo " To test your twitter connection, run the below command:" echo " # twitapc twittest" exit 1 ;; esac if [ -n "$msg" ] then curl -o /dev/null -s -u $tw_user:$tw_pass -d status="$msg ::$timestamp" $tw_url fi 

( I apologize that this code is not properly indented. The HTML editor application stripped out the whitespace. )

All that is needed is to adjust the $tw_username and the tw_password to match your account settings. If you want to test it, just run it from command line with the parameter twittest

 root@littleblackbox:/etc/apcupsd# ./twitapc twittest Test message sent. Please check your phone. 

This will send the test message.  If it isn’t working for you, remove the “-o /dev/null -s ” from the curl statement at the bottom of the script.

4:  Profit!!!

If the twitter test message worked, then you’re in it for real.  Test it out by, you guessed it, pulling out the UPS power cord from the wall socket.  Of course the UPS will switch to battery and will start beeping, but within a few seconds, you should get a text message from Twitter with the user ID of the account specified in twitapc.

After a few seconds, plug it back in and you should get two more after power is restored and the system is back to normal.

Here is a screenshot of my network monitor twitter page with some sample notifications on it.

trs_netstat twitter

I added a timestamp to the script as my phone doesn’t always display timestamps on it’s text messages. It’s formatted MMDDYYYY-HHMM and can be easily changed in the script

I am always interested to hear your comments and your suggestions.  If you have a success story, by all means tell me.
Have fun and happy twitter-ups-ing..


:, , , , ,

6 Comments for this entry

  • Oliver

    This is possibly the worst way to do it. Your monitoring should not rely on some 3rd party network service.

    Try using something which does monitoring properly, like Nagios.

  • firestorm_v1

    Although I do appreciate your concern about the reliability of relying on a third party network service, I wanted an SMS text message to go directly to my phone, not email. Even by using an external SMS gateway, I’d still be relying on “some 3rd party network service” so I’m still screwed.

    I know that Twitter gets a load of crap for being the new “flashy buzzword” thing, however it does have its uses. And since I use the twitter API for a few other projects, I already had most of the pieces of the puzzle so why go reinventing the same puzzle over again just to add to it?

    I have reviewed Nagios before and know it is definitely a viable application, however it is considerably overkill for what I wanted to do here.

  • laramy

    curl is no longer supported. can this be ported to oauth?

  • laramy
    I got this to work. i am going to edit your script to call my python command.

  • firestorm_v1

    Hello Laramy:

    I have tried without success using my rather limited knowledge of bash scripting however maybe using another language may have the tools needed. Keep us posted if you are able to get it working!

    Thank you.


  • firestorm_v1

    Hello Laramy:

    This sounds awesome! I will have to test this and make sure it works and if so, of course I’ll post a follow up article. I’ll be sure to give you props for this lead.

    Thank you!


4 Trackbacks / Pingbacks for this entry