Changed WSGI files

This commit is contained in:
Bernardo Carvalho
2022-10-27 23:18:01 +01:00
parent 701502bddd
commit 61dc77e757
2 changed files with 252 additions and 28 deletions

View File

@@ -0,0 +1,210 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Feb 8 16:34:35 2018
@author: joao_loureiro/bernardo carvalho
add EPICS path to /etc/apache2/envvars
"""
import epics
import time
import os
os.environ['MPLCONFIGDIR'] = '/var/www/html/matplotlib'
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick
from matplotlib.ticker import FuncFormatter
import mpld3
from mpld3 import plugins, utils
import numpy as np
import MySQLdb
os.environ['EPICS_CA_ADDR_LIST']= '192.168.1.110 192.168.1.152'
os.environ['EPICS_CA_AUTO_ADDR_LIST']= 'NO'
def format_tick_labels(x, pos):
return f"{x:5.2g}"
class HelloWorld(mpld3.plugins.PluginBase): # inherit from PluginBase
"""Hello World plugin"""
JAVASCRIPT = """
mpld3.register_plugin("helloworld", HelloWorld);
HelloWorld.prototype = Object.create(mpld3.Plugin.prototype);
HelloWorld.prototype.constructor = HelloWorld;
function HelloWorld(fig, props){
mpld3.Plugin.call(this, fig, props);
};
HelloWorld.prototype.draw = function(){
// FIXME: this is a very brittle way to select the y-axis element
var ax = this.fig.axes[0].elements[1];
// see https://github.com/mbostock/d3/wiki/Formatting#d3_format
// for d3js formating documentation
ax.axis.tickFormat(d3.format(",.3e"));
// TODO: use a function for tick values that
// updates when values pan and zoom
//ax.axis.tickValues([1,100,1000]);
// HACK: use reset to redraw figure
this.fig.reset();
}
"""
def __init__(self):
self.dict_ = {"type": "helloworld"}
style_tooltip = """
<style>
.tooltip {
position: relative;
display: inline-block;
border-bottom: 1px dotted black;
}
.tooltip .tooltiptext {
visibility: hidden;
width: 800px;
background-color: #555;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 0;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -60px;
opacity: 0;
transition: opacity 1s;
}
.tooltip .tooltiptext::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #555 transparent transparent transparent;
}
.tooltip:hover .tooltiptext {
visibility: visible;
opacity: 1;
}
</style>
"""
def text_with_tooltip(text, tooltip):
html = '<div class="tooltip">'+text+'\n'\
' <span class="tooltiptext">'+tooltip+'</span></div>'
return html
def application(environ,start_response):
status = '200 OK'
valuePrimary1 = epics.caget('ISTTOK:central:RPump1-Pressure')
# valuePrimary2 = epics.caget('ISTTOK:central:RPump2-Pressure')
valueChamber1 = epics.caget('ISTTOK:central:VVessel-Pressure')
valueTMPadmission = epics.caget('ISTTOK:central:TMPump1-PressureAdmission')
now = time.ctime()
# Open database connection
# db = MySQLdb.connect(host = "192.168.1.152",user = "report", passwd="$report", db = "archive")
db = MySQLdb.connect(host = "192.168.1.100",user = "report", passwd="$report", db = "archive")
# prepare a cursor object using cursor() method
cursor = db.cursor()
# channel_id =5 | ISTTOK:central:VVessel-Pressure
sql_chamber ="SELECT `smpl_time`, `float_val` FROM `sample` WHERE `channel_id` = 5 " \
"AND `smpl_time` > addtime(now(),'-01:00:00') ORDER BY `smpl_time` DESC LIMIT 100;"
# sql_chamber ="SELECT `smpl_time`, `float_val` FROM `sample` WHERE `channel_id` = 5 ORDER BY `smpl_time` DESC LIMIT 250;"
# 21 | ISTTOK:central:RPump1-Pressure
sql_primary ="SELECT `smpl_time`, `float_val` FROM `sample` WHERE `channel_id` = 6 " \
"AND `smpl_time` > addtime(now(),'-01:00:00') ORDER BY `smpl_time` DESC LIMIT 100;"
# sql_primary ="SELECT `smpl_time`, `float_val` FROM `sample` WHERE `channel_id` = 6 ORDER BY `smpl_time` DESC LIMIT 250;"
# Execute the SQL command
cursor.execute(sql_chamber)
# Fetch all the rows in a list of lists.
results = cursor.fetchall()
data_chamber = []
for row in results:
data_chamber.append([row[0],row[1]])
# Execute the SQL command
cursor.execute(sql_primary)
# Fetch all the rows in a list of lists.
results = cursor.fetchall()
data_primary = []
for row in results:
data_primary.append([row[0],row[1]])
# disconnect from server
db.close()
#
data_chamber = np.array(data_chamber)
data_primary = np.array(data_primary)
fig,axr = plt.subplots(1, sharex=True)
axr.set_yscale('log')
axr.yaxis.set_major_formatter(FuncFormatter(format_tick_labels))
axr.semilogy(data_chamber[:,0],data_chamber[:,1], color='red')
axr.set_ylim(1e-8, 1e-4)
# axr.legend(['Tokamak Chamber', 'Primary pump'], loc =2)
axr.legend(['Tokamak Chamber'], loc='upper left')
axr.set_xlabel('Time', fontsize = 15)
axr.set_ylabel('TMP1Pressure/mbar', fontsize = 15, color = 'red')
ax2 = axr.twinx()
ax2.plot(data_primary[:,0],data_primary[:,1], color='blue')
ax2.set_ylabel('Rpump Pressure/mbar', fontsize = 15, color = 'blue')
ax2.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.3e'))
ax2.set_ylim(1e-4, 1e-2)
fig.set_size_inches(12,5, forward=True)
fig.tight_layout()
ax_fmt = HelloWorld()
mpld3.plugins.connect(fig, ax_fmt)
html2 = mpld3.fig_to_html(fig)
html = '<html>\n' \
'<head>' \
'<title>ISTTOK EPICS WSGI Page</title>' \
'</head>\n' \
'<body>\n' \
'<div>'+style_tooltip+'</div>\n'\
'<div style="width: 100%; font-size: 40px; font-weight: bold; text-align: center;">\n' \
'mod_wsgi EPICS ISTTOK info Page\n' \
'</div>\n' \
'<div style="width: 100%; font-size: 20px; font-weight: bold; text-align: center;">\n' \
' '+text_with_tooltip('Rpump1 pressure: '+ '{0:.3e}'.format(valuePrimary1)+ ' mBar','ISTTOK:central:RPump1-Pressure')+'\n' \
'</div>\n' \
'<div style="width: 100%; font-size: 20px; font-weight: bold; text-align: center;">\n' \
' '+text_with_tooltip('Turbopump 1 admission pressure: '+ '{0:.3e}'.format(valueTMPadmission)+ ' mBar','ISTTOK:central:TMPump1-PressureAdmission')+'\n' \
'</div>\n' \
'<div style="width: 100%; font-size: 20px; font-weight: bold; text-align: center;">\n' \
' '+text_with_tooltip('Tokamak Vessel pressure: '+ '{0:.3e}'.format(valueChamber1)+ ' mBar','ISTTOK:central:VVessel-Pressure')+'\n' \
'</div>\n' \
'<div style="width: 100%; font-size: 20px; font-weight: bold; text-align: center;">\n' \
'Current Time: ' +now+ '\n' \
'</div><center>\n'+html2 +'</center>\n' \
'</body>\n' \
'</html>\n'
response_header = [('Content-type','text/html')]
start_response(status,response_header)
html = bytes(html, encoding= 'utf-8')
return [html]
#'</div><center>\n'+html2.encode('utf8')+'</center>\n' \
# '<p> sys path: ' + os.environ['PATH'] + '</p>' \

View File

@@ -15,44 +15,50 @@ Created on December 8 16:34:35 2019
@author: bernardo carvalho@IPFN @author: bernardo carvalho@IPFN
""" """
# #
from epics import caget, caput, cainfo from epics import caget, caput, cainfo, PV
import os import os
#os.environ['EPICS_CA_ADDR_LIST'] = 'localhost 192.168.1.110 192.168.1.120' #os.environ['EPICS_CA_ADDR_LIST'] = 'localhost 192.168.1.110 192.168.1.120'
os.environ['EPICS_CA_ADDR_LIST'] = 'localhost 192.168.1.110' #os.environ['EPICS_CA_ADDR_LIST'] = 'localhost 192.168.1.110'
os.environ['EPICS_CA_ADDR_LIST'] = '192.168.1.110'
os.environ['EPICS_CA_AUTO_ADDR_LIST'] = 'NO' os.environ['EPICS_CA_AUTO_ADDR_LIST'] = 'NO'
def application(environ,start_response): def application(environ,start_response):
status = '200 OK' status = '200 OK'
RPump1press = caget('ISTTOK:central:RPump1-Pressure', as_string=True)
# RPump2press = caget('ISTTOK:central:RPump2-Pressure')
TMPump1press = caget('ISTTOK:central:TMPump1-PressureAdmission', as_string=True)
VVesselpress = caget('ISTTOK:central:VVessel-Pressure', as_string=True)
# RPump1press = caget('ISTTOK:vacuum:RPump1-Pressure')
# RPump2press = caget('ISTTOK:vacuum:RPump2-Pressure')
# TMPump1press = caget('ISTTOK:vacuum:TMPump1-PressureAdmission')
# VVesselpress = caget('ISTTOK:vacuum:VVessel-Pressure')
rpiCurrentTime = caget('ISTTOK:central:CurrentTime', as_string=True)
opState = caget('ISTTOK:central:OPSTATE.VAL', as_string=True)
pulseNum = caget('ISTTOK:central:PULSE-NUMBER', as_string=True)
OnBattery = caget('ISTTOK:central:UPS-OnBattery', as_string=True)
# cainfo not working
RPump1Info = cainfo("ISTTOK:central:RPump1-Pressure", print_out=False)
html = '<html>\n' \ html = '<html>\n' \
'<head> <meta charset="UTF-8"/> <title>ISTTOK Status page</title>' \ '<head> <meta charset="UTF-8"/> <title>ISTTOK Status page</title>' \
'<meta http-equiv="refresh" content="5"> </head>' \ '<meta http-equiv="refresh" content="5"> </head>' \
'<body>\n <h1> ISTTOK Present Condition </h1> \n' '<body>\n <h1> ISTTOK Present Vaccum Condition </h1> \n'
# html += '<p>RPump1-Pressure: ' + str(RPump1press) + ' mBar </p>' RP1pv = PV('ISTTOK:central:RPump1-Pressure')
html += '<p>RPump1-Pressure: ' + RPump1press + ' mBar </p>' if RP1pv.connect(timeout=0.2):
# html += '<p>RPump2-Pressure: ' + str(RPump2press) + ' mBar </p>' RPpreAlarm = caget('ISTTOK:central:RPump1-Pressure.SEVR', as_string=True)
RP1A = caget('ISTTOK:central:RPump1-Pressure.SEVR')
RPump1press = RP1pv.get(as_string=True)
TMPump1press = caget('ISTTOK:central:TMPump1-PressureAdmission', as_string=True)
VVesselpress = caget('ISTTOK:central:VVessel-Pressure', as_string=True)
rpiCurrentTime = caget('ISTTOK:central:CurrentTime', as_string=True)
opState = caget('ISTTOK:central:OPSTATE.VAL', as_string=True)
opReq = caget('ISTTOK:central:OPREQ.VAL', as_string=True)
opReqN = caget('ISTTOK:central:OPREQ.VAL')
pulseNum = caget('ISTTOK:central:PULSE-NUMBER', as_string=True)
OnBattery = caget('ISTTOK:central:UPS-OnBattery', as_string=True)
RPump1Info = cainfo("ISTTOK:central:RPump1-Pressure", print_out=False)
if RP1A == 0:
html += '<p>RPump1-Pressure: ' + RPump1press + ' mBar. ALARM Status:' +RPpreAlarm+' </p>'
else:
html += '<h3 style="color: #FF0000">RPump1-Pressure: ' + RPump1press + ' mBar. ALARM Status:' +RPpreAlarm+' </h3>'
html += '<p>TMPump1-PressureAdmission: ' + TMPump1press + ' mBar </p>' html += '<p>TMPump1-PressureAdmission: ' + TMPump1press + ' mBar </p>'
html += '<p>VVessel-Pressure: ' + VVesselpress + ' mBar </p>' html += '<p>VVessel-Pressure: ' + VVesselpress + ' mBar </p>'
html += '<p>OPSTATE: ' + opState + ', UPS-OnBattery: '+ OnBattery+ '</p>' html += '<p>OPSTATE: ' + opState + ', UPS-OnBattery: '+ OnBattery+ '</p>'
html += '<p>OPREQ: ' + opReq + '</p>'
if opReqN == 0:
html += '<p>Note: you can try to login to rpi-isttok machine and do: ' html += '<p>Note: you can try to login to rpi-isttok machine and do: '
html += '<pre>caput ISTTOK:central:OPREQ START</pre> </p>' html += '<pre>caput ISTTOK:central:OPREQ START</pre> </p>'
html += '<p>PULSE-NUMBER: ' + pulseNum + ' </p>' html += '<p>PULSE-NUMBER: ' + pulseNum + ' </p>'
html += '<p>Rpi CurrentTime: ' + rpiCurrentTime + ' </p>' html += '<p>Rpi CurrentTime: ' + rpiCurrentTime + ' </p>'
html += '<pre> ' + RPump1Info + '</pre>' else:
html += '<h2 style="color: #FF0000">Sorry, cannot connect to EPICS.</h2>'
html += '</body>\n' \ html += '</body>\n' \
'</html>\n' '</html>\n'
response_header = [('Content-type','text/html'), response_header = [('Content-type','text/html'),
@@ -60,4 +66,12 @@ def application(environ,start_response):
start_response(status,response_header) start_response(status,response_header)
return [html.encode('UTF-8')] return [html.encode('UTF-8')]
# html = bytes(html, encoding= 'utf-8') # html = bytes(html, encoding= 'utf-8')
# html += '<p>RPump1-Pressure: ' + str(RPump1press) + ' mBar </p>'
# return [html] # return [html]
# RPump1press = caget('ISTTOK:vacuum:RPump1-Pressure')
# RPump2press = caget('ISTTOK:vacuum:RPump2-Pressure')
# html += '<p>RPump2-Pressure: ' + str(RPump2press) + ' mBar </p>'
# TMPump1press = caget('ISTTOK:vacuum:TMPump1-PressureAdmission')
# VVesselpress = caget('ISTTOK:vacuum:VVessel-Pressure')
# RPump2press = caget('ISTTOK:central:RPump2-Pressure')
# html += '<pre> ' + RPump1Info + '</pre>'