Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 40 additions & 43 deletions virtaccl/EPICS_Server/ca_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,9 @@
from threading import Thread
from datetime import datetime
from time import sleep

from math import floor
from typing import Any, Dict

from pcaspy import Driver
from pcaspy.cas import epicsTimeStamp
from pcaspy import SimpleServer

from virtaccl.server import Server
from virtaccl.virtual_accelerator import VA_Parser

Expand All @@ -31,31 +26,6 @@ def add_epics_arguments(va_parser: VA_Parser) -> VA_Parser:
return va_parser


def to_epics_timestamp(t: datetime):
if t is None:
return None

epics_tst = t.timestamp() - 631152000.0
tst = epicsTimeStamp()
tst.secPastEpoch = int(floor(epics_tst))
tst.nsec = int((epics_tst % 1) * 1_000_000_000)

return tst


def epics_now(timestamp: datetime):
return to_epics_timestamp(timestamp)


class TDriver(Driver):
def __init__(self):
Driver.__init__(self)

def setParam(self, reason, value, timestamp=None):
super().setParam(reason, value)
if timestamp is not None:
self.pvDB[reason].time = timestamp


class EPICS_Server(Server):
def __init__(self, prefix='', process_delay=0.1, print_pvs=False):
Expand All @@ -81,9 +51,9 @@ def add_parameters(self, new_parameters: Dict[str, Dict[str, Any]]):

def set_parameter(self, reason: str, value: Any, timestamp: datetime = None):
super().set_parameter(reason, value, timestamp)
if timestamp is not None:
timestamp = epics_now(timestamp)
if self.start_flag:
if timestamp is not None:
timestamp = self.driver.to_epics_timestamp(timestamp)
self.driver.setParam(reason, value, timestamp)

def get_parameter(self, reason: str) -> Any:
Expand All @@ -94,19 +64,46 @@ def get_parameter(self, reason: str) -> Any:
return value

def update(self):
self.driver.updatePVs()
if self.driver is not None:
self.driver.updatePVs()

def start(self):
server = SimpleServer()
server.createPV(self.prefix, self.parameter_db)
self.driver = TDriver()
tid = Thread(target=self._CA_events, args=(server,))

# So it will die after main thread is gone
tid.setDaemon(True)
tid.start()
self.run()
self.start_flag = True
try:
from pcaspy import Driver
from pcaspy.cas import epicsTimeStamp
from pcaspy import SimpleServer

class TDriver(Driver):
def __init__(self):
Driver.__init__(self)

def setParam(self, reason, value, timestamp=None):
super().setParam(reason, value)
if timestamp is not None:
self.pvDB[reason].time = timestamp

def to_epics_timestamp(self, t: datetime):
if t is None:
return None
tst = epicsTimeStamp()
epics_tst = t.timestamp() - 631152000.0
tst.secPastEpoch = int(floor(epics_tst))
tst.nsec = int((epics_tst % 1) * 1_000_000_000)
return tst

server = SimpleServer()
server.createPV(self.prefix, self.parameter_db)
self.driver = TDriver()
tid = Thread(target=self._CA_events, args=(server,))

# So it will die after main thread is gone
tid.setDaemon(True)
tid.start()
self.run()
self.start_flag = True
except Exception as e:
print(f'Warning! CA communication is not available because of exception: {e}.')
print(f'Check EPICS (pcaspy) installation.')

def stop(self):
# it's unclear how to gracefully stop the server
Expand Down