diff --git a/epics/html/wsgi/wsgi_isttok_archive.py b/epics/html/wsgi/wsgi_isttok_archive.py new file mode 100644 index 0000000..9380937 --- /dev/null +++ b/epics/html/wsgi/wsgi_isttok_archive.py @@ -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 = """ + +""" + +def text_with_tooltip(text, tooltip): + html = '
'+text+'\n'\ + ' '+tooltip+'
' + 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 = '\n' \ + '' \ + 'ISTTOK EPICS WSGI Page' \ + '\n' \ + '\n' \ + '
'+style_tooltip+'
\n'\ + '
\n' \ + 'mod_wsgi EPICS ISTTOK info Page\n' \ + '
\n' \ + '
\n' \ + ' '+text_with_tooltip('Rpump1 pressure: '+ '{0:.3e}'.format(valuePrimary1)+ ' mBar','ISTTOK:central:RPump1-Pressure')+'\n' \ + '
\n' \ + '
\n' \ + ' '+text_with_tooltip('Turbopump 1 admission pressure: '+ '{0:.3e}'.format(valueTMPadmission)+ ' mBar','ISTTOK:central:TMPump1-PressureAdmission')+'\n' \ + '
\n' \ + '
\n' \ + ' '+text_with_tooltip('Tokamak Vessel pressure: '+ '{0:.3e}'.format(valueChamber1)+ ' mBar','ISTTOK:central:VVessel-Pressure')+'\n' \ + '
\n' \ + '
\n' \ + 'Current Time: ' +now+ '\n' \ + '
\n'+html2 +'
\n' \ + '\n' \ + '\n' + response_header = [('Content-type','text/html')] + start_response(status,response_header) + html = bytes(html, encoding= 'utf-8') + return [html] + +#'
\n'+html2.encode('utf8')+'
\n' \ +# '

sys path: ' + os.environ['PATH'] + '

' \ diff --git a/epics/html/wsgi/wsgi_isttok_status.py b/epics/html/wsgi/wsgi_isttok_status.py index d68db9b..bb437de 100644 --- a/epics/html/wsgi/wsgi_isttok_status.py +++ b/epics/html/wsgi/wsgi_isttok_status.py @@ -15,44 +15,50 @@ Created on December 8 16:34:35 2019 @author: bernardo carvalho@IPFN """ # -from epics import caget, caput, cainfo +from epics import caget, caput, cainfo, PV 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' +#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' def application(environ,start_response): 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 = '\n' \ ' ISTTOK Status page' \ ' ' \ - '\n

ISTTOK Present Condition

\n' -# html += '

RPump1-Pressure: ' + str(RPump1press) + ' mBar

' - html += '

RPump1-Pressure: ' + RPump1press + ' mBar

' - # html += '

RPump2-Pressure: ' + str(RPump2press) + ' mBar

' - html += '

TMPump1-PressureAdmission: ' + TMPump1press + ' mBar

' - html += '

VVessel-Pressure: ' + VVesselpress + ' mBar

' - html += '

OPSTATE: ' + opState + ', UPS-OnBattery: '+ OnBattery+ '

' - html += '

Note: you can try to login to rpi-isttok machine and do: ' - html += '

caput ISTTOK:central:OPREQ START

' - html += '

PULSE-NUMBER: ' + pulseNum + '

' - html += '

Rpi CurrentTime: ' + rpiCurrentTime + '

' - html += '
 ' + RPump1Info + '
' + '\n

ISTTOK Present Vaccum Condition

\n' + RP1pv = PV('ISTTOK:central:RPump1-Pressure') + if RP1pv.connect(timeout=0.2): + 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 += '

RPump1-Pressure: ' + RPump1press + ' mBar. ALARM Status:' +RPpreAlarm+'

' + else: + html += '

RPump1-Pressure: ' + RPump1press + ' mBar. ALARM Status:' +RPpreAlarm+'

' + html += '

TMPump1-PressureAdmission: ' + TMPump1press + ' mBar

' + html += '

VVessel-Pressure: ' + VVesselpress + ' mBar

' + html += '

OPSTATE: ' + opState + ', UPS-OnBattery: '+ OnBattery+ '

' + html += '

OPREQ: ' + opReq + '

' + if opReqN == 0: + html += '

Note: you can try to login to rpi-isttok machine and do: ' + html += '

caput ISTTOK:central:OPREQ START

' + html += '

PULSE-NUMBER: ' + pulseNum + '

' + html += '

Rpi CurrentTime: ' + rpiCurrentTime + '

' + else: + html += '

Sorry, cannot connect to EPICS.

' + html += '\n' \ '\n' response_header = [('Content-type','text/html'), @@ -60,4 +66,12 @@ def application(environ,start_response): start_response(status,response_header) return [html.encode('UTF-8')] # html = bytes(html, encoding= 'utf-8') +# html += '

RPump1-Pressure: ' + str(RPump1press) + ' mBar

' # return [html] +# RPump1press = caget('ISTTOK:vacuum:RPump1-Pressure') +# RPump2press = caget('ISTTOK:vacuum:RPump2-Pressure') + # html += '

RPump2-Pressure: ' + str(RPump2press) + ' mBar

' +# TMPump1press = caget('ISTTOK:vacuum:TMPump1-PressureAdmission') +# VVesselpress = caget('ISTTOK:vacuum:VVessel-Pressure') +# RPump2press = caget('ISTTOK:central:RPump2-Pressure') +# html += '
 ' + RPump1Info + '
'