Help with delaying script and implementing checks before completion

Login or Register to Reply

Thread Tools Search this Thread
# 1  
Code Help with delaying script and implementing checks before completion

Hello everyone,

I was wondering if any of you could help me with this. I am an absolute beginner and don't know how to program, but I can follow a tutorial and tweak code sometimes. My understanding of programing is limitted to what for and while loops do, and how if then else logic works. That being said:

My setup is that I have a raspberry pi hooked up to an APC UPS via USB. When mains power goes out, the UPS triggers a "powerout" script which, in turn, sends me an email notification and calls me to my home number and my mobile phone using a SIP account, and a pre-recorded message plays when the call is answered.

I've got this working following various tutorials readily available on the internet.

However, there is a huge problem with this setup as when there is a little fluctuation in the mains power, the UPS turns to battery power in matter of miliseconds and the script is triggered regardless of the fact that power may return in a couple more miliseconds. Therefore I tend to receive calls alerting me of a power failure in the middle of the night and it is really inconvenient.

Therefore, I was hoping that you guys could help me tweak the script so that it waits for, let's say, 10 seconds, then checks again the UPS status, and, only if the UPS is still running on batteries after those 10 secs. places the phone call.

Here is the script which gets triggered when the power goes out:

# -*- coding: utf-8 -*-
# This shell script if placed in /etc/apcupsd
# will be called by /etc/apcupsd/apccontrol when the UPS
# goes on batteries.
# We send an email message to root to notify him.

#MSG="$HOSTNAME UPS $1 Power Failure !!!"
#   echo "Subject: $MSG"
#   echo " "
#   echo "$MSG"
#   echo " "
#   /sbin/apcaccess status

# Added this new script from
#  ANG 8-23-2014

#!/usr/bin/env python

import smtplib
import email.mime.text
import syslog
import os

def log(msg):


from_email = GMAIL_ADDRESS
to_emails = ["RECIPIENT EMAIL ADDRESS GOES HERE"]  # email address

msg_subject = "MSG SUBJECT GOES HERE"
msg_text = "MSG TEXT GOES HERE"


msg = email.mime.text.MIMEText(msg_text)
msg['Subject'] = msg_subject
msg['From'] = from_email
msg['To'] = ", ".join(to_emails)
s = smtplib.SMTP_SSL('', '465')
s.sendmail(from_email, to_emails, msg.as_string())

retvalue=os.system("python /etc/apcupsd/")
print retvalue

#exit 0

As you can see, the calling home part is dealt with at the very end of the script by calling a python script ( and Ideally, I would like to pause execution of the script for 10 seconds before that line of code, then somehow check the ups status and, if the power is still out, place the call, but if the power has already returned, exit the script before calling

I imagine it will be easy to pause execution for 10 secs. but the part I really need help with is checking the UPS status.

Also, I guess it could be done by either parsing the results of "cat /var/log/" where the output is something like:

2017-06-08 12:34:16 +0200  Power failure.
2017-06-08 12:34:22 +0200  Running on UPS batteries.
2017-06-08 12:37:04 +0200  Mains returned. No longer on UPS batteries.
2017-06-08 12:37:04 +0200  Power is back. UPS running on mains.
2017-06-08 12:37:14 +0200  Power failure.
2017-06-08 12:37:20 +0200  Running on UPS batteries.
2017-06-08 13:17:57 +0200  Mains returned. No longer on UPS batteries.
2017-06-08 13:17:57 +0200  Power is back. UPS running on mains.

As you can see those lasts ones were legit power outages but it is not always the case. What I would need to do is check whether the last line says either "Power failure." or "Running on UPS batteries." and, in that case place the call, or whether it reads "Mains returned. No longer on UPS batteries." or "Power is back. UPS running on mains." and in that case abort the phone call, but I don't know how to do it.

Another option would be to get the script to call "apcaccess" which produces an output like the following one:
APC      : 001,028,0733
DATE     : 2017-06-18 11:22:35 +0200  
HOSTNAME : raspberrypi
VERSION  : 3.14.12 (29 March 2014) debian
CABLE    : USB Cable
UPSMODE  : Stand Alone
STARTTIME: 2017-01-16 20:40:23 +0100  
MODEL    : Smart-UPS 2200 
BCHARGE  : 100.0 Percent
TIMELEFT : 372.0 Minutes
MBATTCHG : 5 Percent
MINTIMEL : 3 Minutes
MAXTIME  : 0 Seconds
ALARMDEL : 30 Seconds
BATTV    : 54.5 Volts
XONBATT  : 2017-06-08 12:37:14 +0200  
TONBATT  : 0 Seconds
CUMONBATT: 11121 Seconds
XOFFBATT : 2017-06-08 13:17:57 +0200  
STATFLAG : 0x05000008
MANDATE  : 2016-02-23
SERIALNO : AS1608151711  
NOMBATTV : 48.0 Volts
FIRMWARE : UPS 09.3 / ID=18
END APC  : 2017-06-18 11:22:37 +0200

As you can see, the idea would be similar, I would need to parse this output (which I don't know how to do) to get the value of the "STATUS" line. which will either read ONLINE if the ups is running on mains power, and something else (I don't remember it right now) if it is running on batteries.

Thank you very much in advance. Any help will be much appreciated. Have a nice weekend Smilie

Last edited by Scott; 06-18-2017 at 06:55 AM.. Reason: Please use code tags
# 2  
Either method is possible; I'd prefer the second with apcaccess as it describes the actual status of the UPS while the log could be delayed / overwritten / have other, meaningless lines. You also seem to have it in your script but commented out. Unfortunately, I don't know apcaccess and so can't tell which info indicates a "power out" status and maybe more (mayhap on top of "STATUS: ONLINE", one of the bits in STATFLAG might give deeper insight?).
Assuming it were the STATUS line, and stealing from your script, try (untested, and not sure the sh shell will correctly run this, you may need e.g. bash)
sleep 10
/sbin/apcaccess status > /tmp/TMP$$
! grep -q "STATUS   : ONLINE" /tmp/TMP$$ && echo mail -s $MSG  $SYSADMIN </tmp/TMP$$
rm /tmp/TMP$$

Remove the echo when happy with the result.

Final comment: the "shebang" in your script #!/bin/sh needs to be in the very first line to become effective, i.e. determines the shell to be run to execute your code.

Last edited by RudiC; 06-18-2017 at 08:48 AM..
This User Gave Thanks to RudiC For This Post:
# 3  
Thank you sooo much for your prompt response.

I'll surely give it a try and let you know how it went although I might not be able to fully test it for a couple of weeks since I have this set up in a remote location and I need to be able to unplug the ups to test it.

Thanks again Smilie

---------- Post updated 19-06-17 at 02:19 PM ---------- Previous update was 18-06-17 at 02:29 PM ----------

Thank you very much @RudiC it works perfectrly well!

I forgot to mention that the main script was a python script and I could not integrate your code directly. Instead, I have placed it on a separate .sh which handles the logic for either calling or not calling based on the status of the UPS after 10 seconds and I call that one from the main script.

Thanks againSmilie
Login or Register to Reply

Thread Tools Search this Thread
Search this Thread:
Advanced Search

More UNIX and Linux Forum Topics You Might Find Helpful
Sendmail delaying mails for 45 mins
Hi, I'm trying to send out mails from my server using mailx, however everytime I send one, it appears to be held in the /var/spool/mqueue for 44 mins before being sent. I'm quite new to sendmail, so don't really know where to start with this /var/log/syslog displays the following: Dec 16...... Solaris
Script function which checks if itself is already running
Hi All, I have a cron job set up which is set to run every 10 seconds. What I need to do is have the script do a check to see if it is already running such that if it is running it wont fire up additional instances and processes according to its normal process. For example if I have a script...... Shell Programming and Scripting
Shell Programming and Scripting
Script to do the following checks
Hi , I need a script for processing below scenario. I have to check daily by doing ftp IP to check it is logging or not. So i want this activity to be automated such that if login succesful i will get "FTP LOGIN SUCCESS" in a log file and if fails i want the error message in the same log...... Shell Programming and Scripting
Shell Programming and Scripting
Script to performs checks
Hi , I need a script which performs below activity I have one file named "testfile" in 9 different directories with same name. I want to perform below action with each testfile of each directory. if ; then mv listfiles listfiles_`date +%b%y` else echo No Such files fi ...... Shell Programming and Scripting
Shell Programming and Scripting
Sendmail error delaying relay
When I try to send mail, sendmail delays a lot. After monitoring syslog, I noticed that sendmail starts with this first message... waits a minute and gives the second message... waits another minute and then sends off the email. How do I correct this in sendmail or completly disable it. I'm sending...... Solaris

Featured Tech Videos