Skip to content
Snippets Groups Projects
Commit d5cf007a authored by Mikhail Remnev's avatar Mikhail Remnev
Browse files

Rewritten epics ca server to get information from all sectors and to...

Rewritten epics ca server to get information from all sectors and to internally parse file contents, without calls to envext
parent 15f200db
No related branches found
No related tags found
No related merge requests found
......@@ -7,54 +7,148 @@ from pcaspy import SimpleServer, Driver
from datetime import datetime
import subprocess as sp
from threading import Thread
import thread
import time
prefix = 'ECL:'
pvdb = {
'BARREL:PHI1:TEMP' : {
'prec' : 2,
# 'scan' : 15,
},
}
for phi in range(1, 72+1):
if phi in [28, 70]: continue
name = 'S%dBARREL:TEMPAVG' % phi
pvdb[name] = { 'prec' : 2, 'scan' : 15 }
################################################
monitor_data = []
driver = None
# Set if monitor data readout crashed for some reason
thread_crashed = False
def main():
global driver
#== Initialize EPICS server
server = SimpleServer()
server.createPV(prefix, pvdb)
driver = myDriver()
#== Put new data into monitor_data array every 15 seconds
thread = Thread(target=readout_thread)
thread.daemon = True
thread.start()
while True:
# process CA transactions
# process EPICS CA transactions
server.process(0.1)
if thread_crashed: break
################################################
# EPICS CHANNEL ACCESS SERVER
class myDriver(Driver):
def __init__(self):
super(myDriver, self).__init__()
def read(self, reason):
phi = 1
# Date string for the request
yymmdd = datetime.today().strftime('%Y%m%d')
if reason == 'BARREL:PHI%d:TEMP' % phi:
proc = sp.Popen(['./envext', yymmdd, '%d' % phi],
cwd='/home/kenkichi/kanomika/envmon', stdout=sp.PIPE)
out, err = proc.communicate()
# hour min sec temperatures humidity
last_line = out.split('\n')[-2].split(' ')
hour = int(last_line[0])
minute = int(last_line[1])
sec = int(last_line[2])
temp = float(last_line[3])
hum = float(last_line[4])
print(last_line)
value = temp
else:
pv_found = False
print(reason)
if len(monitor_data) == 72:
for phi in range(1, 72+1):
if phi in [28, 70]: continue
name = 'S%dBARREL:TEMPAVG' % phi
print(reason, name, reason==name)
if reason == name:
temp1, temp2, temp3, hum = monitor_data[phi-1]
value = (temp1 + temp2 + temp3) / 3
pv_found = True
if not pv_found:
value = self.getParam(reason)
return value
################################################
# DATA PARSING
def readout_thread():
global monitor_data, driver, thread_crashed
try:
while True:
yymmdd = datetime.today().strftime('%Y%m%d')
monitor_data = parse_data(yymmdd)
driver.updatePVs()
time.sleep(15)
except Exception as e:
thread_crashed = True
print(e)
except:
thread_crashed = True
temp_ch = [
7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1,
14,13,13,13,12,12,12,11,11,11,10,10,10, 9, 9, 9, 8, 8, 8, 7,
20,20,20,19,19,19,18,18,18,17,17,17,16,16,16,15,15,15,14,14,
27,27,26,26,26,25,25,25,24,24,24,23,23,23,22,22,22,21,21,21,
34,33,33,33,32,32,32,31,31,31,30,30,30,29,29,29,27,
40,40,40,39,39,39,38,38,38,37,37,37,36,36,36,35,35,35,34,34,
47,47,46,46,46,45,45,45,44,44,44,43,43,43,42,42,42,41,41,41,
54,53,53,53,52,52,52,51,51,51,50,50,50,49,49,49,48,48,48,47,
60,60,60,59,59,59,58,58,58,57,57,57,56,56,56,55,55,55,54,54,
67,67,66,66,66,65,65,65,64,64,64,63,63,63,62,62,62,61,61,61,
72,72,72,71,71,71,69,69,69,68,68,68,67]
hum_ch = [
20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,
60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,
72,71,70,69,68,67,66,65,64,63,62,61]
# NOTE: This function is only usable for data after 2020.10.16,
# since earlier envmon version used different output format
def parse_data(yymmdd):
"""
@param yymmdd Date in 'YYYYmmdd' format
Can use datetime.today().strftime('%Y%m%d')
Return table of temperatures and humidity for each sector:
[
[phi1_temp1, phi1_temp2, phi1_temp3, phi1_hum],
[phi2_temp1, phi2_temp2, phi2_temp3, phi2_hum],
...
[phi72_temp1, phi72_temp2, phi72_temp3, phi72_hum]
[
"""
results = [list() for x in range(72)]
file_path = '/home/kenkichi/kanomika/envmon/%s_envmon.txt' % yymmdd
lines = open(file_path, 'r').readlines()
if len(lines) < 6:
return None
# We are interested only in the last three lines
line_index = len(lines) - 4
#== Go back through the file to avoid partially written data
while True:
if ':' in lines[line_index]: break
line_index -= 1
if line_index < 0:
raise RuntimeError('Corrupted data in %s' % file_path)
#== Extract 3 lines with temperature and humidity information
time_data = lines[line_index ].strip().split(':')
temp_mon_data = lines[line_index+1].split()
hum_mon_data = lines[line_index+2].split()
for i, phi in enumerate(temp_ch):
results[phi-1].append(float(temp_mon_data[i]))
for i, phi in enumerate(hum_ch):
if phi in [28, 70]: continue
if len(results[phi-1]) != 3:
raise RuntimeError('Wrong number of temperature values for '\
'phi%d: expected 3, got %d instead' %
(phi, len(results[phi-1])))
results[phi-1].append(float(hum_mon_data[i]))
return results
################################################
if __name__ == '__main__':
main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment