Skip to content

Commit

Permalink
Defined UTF-8 encoding in all files; now the report type in wc_getRep…
Browse files Browse the repository at this point in the history
…ort can be given as argument; added the new tool wc_checkAlarms
  • Loading branch information
weiher committed Jul 19, 2017
1 parent 37fdbf4 commit 06131c9
Show file tree
Hide file tree
Showing 8 changed files with 248 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ import wc_query
myDictonary = {'username':'wsdl', 'password':'seife', 'node':'/trees/geographic', 'url':'https://webctrl.rz-berlin.mpg.de'}
wc_query.main(myDictonary)

To be able to import the wc_* tools append to the PYTHONPATH the webctrl directory. There are two possible ways:
To be able to import the wc_* tools append to the PYTHONPATH the webctrl directory. To do that there are two possible ways:
1) Set the PYTHONPATH environment variable in the shell in which you run your python script that uses the tool(s):
export PYTHONPATH="$PYTHONPATH:/path/to/webctrl"
2) Set the python path inside the python script before the import statement:
Expand Down
15 changes: 15 additions & 0 deletions alarm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# -*- coding: UTF-8 -*-


class alarm:

def __init__(self, date, age, standort, message, quelle, bestaetigtVon, kategorie, status):
self.date = date
#self.time = time
self.age = age
self.standort = standort
self.message = message
self.quelle = quelle
self.bestaetigtVon = bestaetigtVon
self.kategorie = kategorie
self.status = status
207 changes: 207 additions & 0 deletions wc_checkAlarms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
# -*- coding: utf-8 -*-

import suds
import sys
import xml
import argparse
import getpass
from alarm import alarm
from time import sleep
import datetime


def main(args):
# Check all arguments
try:
if args['username'] is None:
print 'No username specified. Login to WebCTRL needs a username and a password. Check all options for this command via -h'
sys.exit(1)
else:
username = args['username']
except KeyError:
print 'No "username" key specified. Please provide the key-value pair: \'username\':\'myUsername\''
sys.exit(1)

try:
if args['password'] is None:
print 'No password specified. Login to WebCTRL needs a username and a password. Check all options for this command via -h'
sys.exit(1)
else:
password = args['password']
except KeyError:
print 'No "password" key specified. Please provide the key-value pair: \'password\':\'myPassword\''
sys.exit(1)

try:
if args['node'] is None:
print 'No path to a node specified. Check all options for this command via -h'
sys.exit(1)
except KeyError:
print 'No "node" key specified. Please provide the key-value pair: \'node\':\'/my/node\''
sys.exit(1)

try:
if args['url'] is None:
print 'No URL given. Specify the URL to the WebCTRL server analogous to http://google.de'
sys.exit(1)
else:
wsdlFile = args['url'] + '/_common/webservices/Report?wsdl'
except KeyError:
print 'No "url" key specified. Please provide the key-value pair: \'url\':\'http://myURL.de\''
sys.exit(1)


# Connect to the webCTRL server
try:
client = suds.client.Client(wsdlFile, username=username, password=password)
except AttributeError:
print 'Error: Incorrect username and/or password'
except xml.sax._exceptions.SAXParseException:
print 'Error: Incorrect/Misspelled WSDL file. It should be: http(s)://URL?wsdl'
sys.exit(1)
except:
print("Unexpected error:", sys.exc_info()[0])
print('Perhaps your URL to the WSDL file is not correct.')
sys.exit(1)

checkForNewAlarmsInterval = args['interval']
alarmsRunning = [] # running alarms waiting to be checked/acknowledged and, eventually, switched off
alarmsChecked = [] # alarms that are already acknowloedged or switched off

# As long as this script runs get a report about all current alarms and their status every X seconds. The alarms are
# managed in objects that will be deleted once the status of an alarm has switched to "Normal". It will be checked
# if an alarm is handled - at least acknowledged - in a certain amount of time and, if not, consequences follow as
# e.g. e-mail or SMS to a given address or telephone number.
while True:
# Get a report about all current alarms in the network or in parts of the network (depending on the node setting)
try:
report = client.service.runReport(args['node'], '~alarms', 'csv')
except suds.WebFault as fault:
print fault
sys.exit(1)

print report

lines = report.split("\n")
lines = lines[1:]
#file = open("testAlarms.txt", "r")
#lines = file.read().split("\n")

# Go through the report and create alarm objects distinguishing by their current alarm status.
# Start looping from the last line in order to process the oldest alarms first.
for line in reversed(lines):

if 'Aktueller Status' in line:
status = line[18:]
indexOfQuote = status.index('"')
status = status[:indexOfQuote]
elif 'Kategorie' in line:
kategorie = line[11:]
elif 'Besttigt' in line:
bestaetigtVon = line[10:]
elif 'Quelle' in line:
quelle = line[8:]
elif '","' in line:
parts = line.split(",")
dateAndTime = parts[0].replace('"', '').split(" ")
standort = parts[1].replace('"', '')
message = parts[2].replace('"', '')

date = dateAndTime[0]
parts = date.split(".")
day = int(parts[0])
month = int(parts[1])
year = int(parts[2])
#print(year,month,day)

time = dateAndTime[1]
parts = time.split(":")
hours = int(parts[0])
minutes = int(parts[1])
seconds = int(parts[2])
#print(hours,minutes,seconds)

date = datetime.datetime(year, month, day, hours, minutes, seconds)

# Create the alarm object and add the unchecked/unsolved alarms to a list for observation
if status == 'Normal':
# Before appending the current alarm to the list of alarms check if this alarm is already contained
# in the list:
alarmAlreadyKnown = False
for a in alarmsChecked:
if a.quelle == quelle and a.date == date:
# This alarm is already known; move on to the next alarm
alarmAlreadyKnown = True
break
if not alarmAlreadyKnown:
# Before appending the checked/solved alarm to the list, first check if this alarm is already
# the check/solution to a prior alarm with status e.g. 'unnormal':
removedAlarm = False
for a in alarmsRunning:
if a.quelle == quelle:
# Remove alarm from running and do not append to checked
removedAlarm = True
alarmsRunning.remove(a)
print('Removing alarm ' + str(date) + quelle + ' from alarmsRunning')
if not removedAlarm:
# This should actually not happen: to have an alarm with status 'Normal' but to not find an
# appropriate alarm with status 'Unnormal'
age = 0
alarmsChecked.append(alarm(date, age, standort, message, quelle, bestaetigtVon, kategorie, status))
else:
# Before appending the current alarm to the list of alarms check if this alarm is already contained
# in the list:
alarmAlreadyKnown = False
for a in alarmsRunning:
if a.quelle == quelle and a.date == date:
# This alarm is already known; move on to the next alarm
alarmAlreadyKnown = True
# Observe the age of the alarm, i.e, increase the age by the time interval in which new alarms are caught
a.age += checkForNewAlarmsInterval
break
if not alarmAlreadyKnown:
print('Appending alarm '+str(date)+quelle+' to alarmsRunning')
age = 0
alarmsRunning.append(alarm(date, age, standort, message, quelle, bestaetigtVon, kategorie, status))

if alarmsChecked:
for a in alarmsChecked:
print(a.date, a.standort, a.message, a.quelle, a.bestaetigtVon, a.kategorie, a.status)
else:
print('No alarms in list alarmsChecked')

if alarmsRunning:
for a in alarmsRunning:
print(a.date, a.standort, a.message, a.quelle, a.bestaetigtVon, a.kategorie, a.status)
# Check the age of the still running alarms and take action in case of, for example, the age is greater than e.g. 20 min
if a.age / 60 > 20:
pass
# send e-mail / SMS notification to ...
else:
print('No alarms in list alarmsRunning')

sleep(checkForNewAlarmsInterval)


if __name__=='__main__':
if len(sys.argv) < 2:
print "You haven't specified any arguments. Use -h to get more details on how to use this command."
sys.exit(1)

parser = argparse.ArgumentParser()
parser.add_argument('--username', '-u', type=str, default=None, help='Username for the login to the WebCTRL server')
parser.add_argument('--password', '-p', type=str, default=None, help='Password for the login to the WebCTRL server')
parser.add_argument('--node', '-n', type=str, default='trees/geographic',
help='Path to the point or node whose children you want to retrieve. Start querying at the lowest level with "-n /trees/geographic"')
parser.add_argument('-url', type=str, default='https://webctrl.rz-berlin.mpg.de',
help="URL of the WebCTRL server as e.g. http://google.de")
parser.add_argument('-interval', '-i', type=int, default=60, help="Interval in SECONDS in which the script checks for new alarms")
args = parser.parse_args()

# Get the password if it hasn't been passed as argument
if args.password is None:
args.password = getpass.getpass('No password specified via -p. Please enter your WebCTRL login password: ')

# Convert the argparse.Namespace to a dictionary via vars(args)
main(vars(args))
sys.exit(0)
18 changes: 17 additions & 1 deletion wc_getReport.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-

import suds
import sys
import numpy
Expand Down Expand Up @@ -46,6 +48,15 @@ def main(args):
print 'No "url" key specified. Please provide the key-value pair: \'url\':\'http://myURL.de\''
sys.exit(1)

try:
if args['reportType'] is None:
print 'No report type specified. Using a default: ~point-list-report'
else:
reportType = args['reportType']
except KeyError:
print 'No "reportType" key specified. Please provide the key-value pair, e.g.: \'reportType\':\'~point-list-report\''
sys.exit(1)


# Connect to the webCTRL server
try:
Expand All @@ -63,11 +74,12 @@ def main(args):

# Get the report
try:
report = client.service.runReport(args['node'], '~point-list-report', 'csv')
report = client.service.runReport(args['node'], reportType, 'csv')
except suds.WebFault as fault:
print fault
sys.exit(1)

print report

# Split the report into separate lines and calculate the number of columns
lines = report.split("\n")
Expand Down Expand Up @@ -123,6 +135,10 @@ def main(args):
help='Path to the point or node whose children you want to retrieve. Start querying at the lowest level with "-n /trees/geographic"')
parser.add_argument('-url', type=str, default='https://webctrl.rz-berlin.mpg.de',
help="URL of the WebCTRL server as e.g. http://google.de")
parser.add_argument('-reportType', '-t', type=str, default='~point-list-report',
help="The type of the report: ~schedule-instance, ~effective-schedule, ~point-list-report, ~locked-value, \
~network-io, ~test-and-balance, ~equipment-checkout, ~audit-log, ~alarms, ~alarm-source, ~network-status, \
~module-version, ~security-assignment, ~alarm-messages, ~alarm-actions, ~trend-usage, ~parameter-mismatch")
args = parser.parse_args()

# Get the password if it hasn't been passed as argument
Expand Down
2 changes: 2 additions & 0 deletions wc_getTrend.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-

import suds
import sys
import xml
Expand Down
2 changes: 2 additions & 0 deletions wc_getValue.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-

import suds
import sys
import xml
Expand Down
2 changes: 2 additions & 0 deletions wc_monitor.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-

import suds
import sys
import xml
Expand Down
2 changes: 2 additions & 0 deletions wc_query.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-

import suds
import sys
import xml
Expand Down

0 comments on commit 06131c9

Please sign in to comment.