[195] | 1 | #!/usr/bin/env python |
---|
| 2 | |
---|
| 3 | ''' |
---|
| 4 | create CGI scripts for each PV (& RRD database) |
---|
| 5 | ''' |
---|
| 6 | ########### SVN repository information ################### |
---|
| 7 | # $Date: 2010-08-18 20:28:25 +0000 (Wed, 18 Aug 2010) $ |
---|
| 8 | # $Author: jemian $ |
---|
| 9 | # $Revision: 206 $ |
---|
| 10 | # $HeadURL$ |
---|
| 11 | # $Id: cgiCreate.py 206 2010-08-18 20:28:25Z jemian $ |
---|
| 12 | ########### SVN repository information ################### |
---|
| 13 | |
---|
| 14 | ############################################################################### |
---|
| 15 | |
---|
| 16 | import xmlSupport |
---|
| 17 | import os.path |
---|
| 18 | from makeTagHTML import makeTagHTML |
---|
| 19 | import time |
---|
| 20 | |
---|
| 21 | |
---|
| 22 | ############################################################################### |
---|
| 23 | |
---|
| 24 | def makeGraphEntry(pvEntry, rrd, span, cgi, desc ,yTitle, properties): |
---|
| 25 | spanName = span['name'] |
---|
| 26 | png = os.path.join( |
---|
| 27 | properties['rrd_logs_base_dir'], |
---|
| 28 | 'plots', |
---|
| 29 | pvEntry['fileRoot'] + '-' + spanName + '.png' |
---|
| 30 | ) |
---|
| 31 | graph = 'RRD::GRAPH' + "\n" |
---|
| 32 | graph += ' ' + png + "\n" |
---|
| 33 | graph += ' --imgformat=PNG' + "\n" |
---|
| 34 | #### NEEDS WORK HERE on the directory & path name |
---|
| 35 | img = 'img src="../plots/%s" width="%lu" height="%lu"' |
---|
| 36 | graph += " --imginfo '" + makeTagHTML(img, '', 0).strip() + "'\n" |
---|
| 37 | graph += ' --lazy --start ' + span['value'] + ' --end now' + "\n" |
---|
| 38 | graph += ' --interlaced' + "\n" |
---|
| 39 | graph += ' --slope-mode' + "\n" |
---|
| 40 | graph += ' --title "' + desc + '"' + "\n" |
---|
| 41 | graph += ' --vertical-label="' + yTitle + '"' + "\n" |
---|
| 42 | graph += ' --units-exponent 0' + "\n" |
---|
| 43 | if (pvEntry['scale'] == 'log'): |
---|
| 44 | graph += ' --alt-autoscale' + "\n" |
---|
| 45 | graph += ' --logarithmic' + "\n" |
---|
| 46 | if (pvEntry['scale'] == 'lin'): |
---|
| 47 | graph += ' --alt-autoscale' + "\n" |
---|
| 48 | graph += ' --alt-y-grid' + "\n" |
---|
| 49 | graph += ' DEF:a=' + rrd + ':EPICS:AVERAGE' + "\n" |
---|
| 50 | graph += ' DEF:aH=' + rrd + ':EPICS:MAX' + "\n" |
---|
| 51 | graph += ' DEF:aL=' + rrd + ':EPICS:MIN' + "\n" |
---|
| 52 | graph += ' VDEF:mean=a,AVERAGE' + "\n" |
---|
| 53 | graph += ' COMMENT:" PV=' + yTitle + ' average\:"' + "\n" |
---|
| 54 | graph += ' GPRINT:mean:"%lg"' + "\n" |
---|
| 55 | graph += ' COMMENT:"\\n"' + "\n" |
---|
| 56 | graph += ' COMMENT:" "' + "\n" |
---|
| 57 | graph += ' LINE1:aH#ccccff:max' + "\n" |
---|
| 58 | graph += ' LINE1:aL#ffcccc:min' + "\n" |
---|
| 59 | graph += ' LINE2:a#ff0000:average' + "\n" |
---|
| 60 | rrdCmd = '<RRD::TIME::NOW %Y-%m-%d,%H\:%M\:%S>' |
---|
| 61 | graph += ' COMMENT:" plotted\: ' + rrdCmd + '\\n"'+ "\n" |
---|
| 62 | return "<" + graph + ">" |
---|
| 63 | |
---|
| 64 | ############################################################################### |
---|
| 65 | |
---|
| 66 | def write_text_file(fileName, content): |
---|
| 67 | f = open(fileName, 'w') |
---|
| 68 | f.write(content) |
---|
| 69 | f.close() |
---|
| 70 | return fileName |
---|
| 71 | |
---|
| 72 | |
---|
| 73 | ############################################################################### |
---|
| 74 | |
---|
| 75 | def write_executable_text_file(fileName, content): |
---|
| 76 | write_text_file(fileName, content) |
---|
| 77 | os.chmod(fileName, 0775) |
---|
| 78 | return fileName |
---|
| 79 | |
---|
| 80 | |
---|
| 81 | ############################################################################### |
---|
| 82 | |
---|
| 83 | def createPvCGI (pv, rrd, properties): |
---|
| 84 | yTitle = pv['pv'].replace(':', '\:') |
---|
| 85 | desc = pv['desc'] |
---|
| 86 | cgi = os.path.join( |
---|
| 87 | properties['rrd_logs_base_dir'], |
---|
| 88 | properties['subdirs']['cgi_dir'], |
---|
[203] | 89 | pvEntry['fileRoot'] + '.cgi' |
---|
[195] | 90 | ) |
---|
| 91 | script = '#!'+properties['rrd']['rrdcgi']+"\n" |
---|
| 92 | script += "<!-- \n" |
---|
| 93 | script += " auto-created " + time.ctime() + "\n" |
---|
| 94 | script += " using " + properties['rrd']['rrdcgi'] + "\n" |
---|
| 95 | script += " and " + cgi + "\n" |
---|
| 96 | script += "-->\n" |
---|
| 97 | head = makeTagHTML( |
---|
[206] | 98 | 'head', |
---|
| 99 | makeTagHTML('meta http-equiv="Pragma" content="no-cache"') |
---|
| 100 | +makeTagHTML('meta http-equiv="Refresh" content="300"') |
---|
| 101 | +makeTagHTML('title', desc, 0) |
---|
[195] | 102 | ) |
---|
| 103 | #------------ |
---|
| 104 | # cannot use makeTagHTML since rrdcgi does not accept short-form closing tags |
---|
| 105 | body = "<RRD::GOODFOR -300>" |
---|
| 106 | body += makeTagHTML('h1', desc, 0) + "\n" |
---|
| 107 | table = '' |
---|
| 108 | row = makeTagHTML('td', "database last updated:", 0)+"\n" |
---|
| 109 | row += makeTagHTML('td', "<RRD::TIME::LAST " + rrd + " %c>", 0) |
---|
| 110 | table += makeTagHTML('tr', row)+"\n" |
---|
| 111 | row = makeTagHTML('td', "CGI executed:", 0)+"\n" |
---|
| 112 | row += makeTagHTML('td', "<RRD::TIME::NOW %c>", 0) |
---|
| 113 | table += makeTagHTML('tr', row)+"\n" |
---|
| 114 | db = makeTagHTML('table', table)+"\n" |
---|
| 115 | body += makeTagHTML('small', makeTagHTML('tt', db))+"\n" |
---|
| 116 | #------------ |
---|
| 117 | table = '' |
---|
| 118 | for spanName in properties['spans']['names']: |
---|
| 119 | row = makeTagHTML( |
---|
[206] | 120 | 'em', |
---|
| 121 | makeTagHTML('small', "data for last "+spanName, 0).strip(), |
---|
| 122 | 0 |
---|
| 123 | ) + "\n" |
---|
| 124 | row += makeTagHTML('br') + "\n" |
---|
| 125 | # make graph entry |
---|
| 126 | row += makeGraphEntry( |
---|
| 127 | pv, |
---|
| 128 | rrd, |
---|
| 129 | properties['spans'][spanName], |
---|
| 130 | cgi, |
---|
| 131 | desc , |
---|
| 132 | yTitle, |
---|
| 133 | properties |
---|
| 134 | ) |
---|
| 135 | table += makeTagHTML('tr', makeTagHTML('td', row)) |
---|
[195] | 136 | body += makeTagHTML('table', table)+"\n" |
---|
| 137 | #------------ |
---|
| 138 | html = makeTagHTML( |
---|
| 139 | 'html', |
---|
[206] | 140 | head + "\n" |
---|
| 141 | + makeTagHTML('body', body.strip()) |
---|
[195] | 142 | ) |
---|
| 143 | script += html |
---|
| 144 | write_executable_text_file(cgi, script) |
---|
| 145 | print "created CGI file: ", cgi |
---|
| 146 | |
---|
| 147 | ############################################################################### |
---|
| 148 | |
---|
| 149 | cfg = xmlSupport.readConfigurationXML('/home/joule/WEB33/www/rrd') |
---|
| 150 | |
---|
| 151 | for pvEntry in cfg['pvList']: |
---|
| 152 | rrd = os.path.join( |
---|
| 153 | cfg['properties']['rrd_logs_base_dir'], |
---|
| 154 | cfg['properties']['subdirs']['rrd_file_dir'], |
---|
| 155 | pvEntry['fileRoot'] + '.rrd' |
---|
| 156 | ) |
---|
| 157 | # only create those RRD files that do not already exist |
---|
| 158 | if (os.path.exists(rrd)): |
---|
| 159 | #print "found " + rrd |
---|
[206] | 160 | createPvCGI (pvEntry, rrd, cfg['properties']) |
---|
[195] | 161 | else: |
---|
| 162 | # do not create CGI file if there is no RRD, no data to show |
---|
[206] | 163 | print "!!! need to create " + rrd |
---|
[195] | 164 | |
---|
| 165 | ############################################################################### |
---|