213 lines
7.3 KiB
Python
213 lines
7.3 KiB
Python
import sys
|
|
import traceback
|
|
import java.lang.System
|
|
import java.lang.Thread
|
|
import java.lang.InterruptedException
|
|
import gov.aps.jca.CAStatus
|
|
import gov.aps.jca.JCALibrary
|
|
import gov.aps.jca.configuration.DefaultConfiguration
|
|
import gov.aps.jca.dbr.DBRType
|
|
import gov.aps.jca.dbr.Severity
|
|
import gov.aps.jca.event.PutListener
|
|
import gov.aps.jca.event.GetListener
|
|
import gov.aps.jca.event.MonitorListener
|
|
import ch.psi.jcae.impl.JcaeProperties
|
|
|
|
version = "PShell wrapper"
|
|
release = "1.0.0"
|
|
revision = "1.0.0"
|
|
error = Exception
|
|
|
|
def dbf_type_is_valid(type):
|
|
return (type >= 0) and (type <= LAST_TYPE)
|
|
def dbr_type_is_valid(type):
|
|
return (type >= 0) and (type <= LAST_BUFFER_TYPE)
|
|
def dbr_type_is_plain(type):
|
|
return (type >= DBR_STRING) and (type <= DBR_DOUBLE)
|
|
def dbr_type_is_STS(type):
|
|
return (type >= DBR_STS_STRING) and (type <= DBR_STS_DOUBLE)
|
|
def dbr_type_is_TIME(type):
|
|
return (type >= DBR_TIME_STRING) and (type <= DBR_TIME_DOUBLE)
|
|
def dbr_type_is_GR(type):
|
|
return (type >= DBR_GR_STRING) and (type <= DBR_GR_DOUBLE)
|
|
def dbr_type_is_CTRL(type):
|
|
return (type >= DBR_CTRL_STRING) and (type <= DBR_CTRL_DOUBLE)
|
|
def dbr_type_is_STRING(type):
|
|
return (type >= 0) and (type <= LAST_BUFFER_TYPE) and (type%(LAST_TYPE+1) == DBR_STRING)
|
|
def dbr_type_is_SHORT(type):
|
|
return (type >= 0) and (type <= LAST_BUFFER_TYPE) and (type%(LAST_TYPE+1) == DBR_SHORT)
|
|
def dbr_type_is_FLOAT(type):
|
|
return (type >= 0) and (type <= LAST_BUFFER_TYPE) and (type%(LAST_TYPE+1) == DBR_FLOAT)
|
|
def dbr_type_is_ENUM(type):
|
|
return (type >= 0) and (type <= LAST_BUFFER_TYPE) and (type%(LAST_TYPE+1) == DBR_ENUM)
|
|
def dbr_type_is_CHAR(type):
|
|
return (type >= 0) and (type <= LAST_BUFFER_TYPE) and (type%(LAST_TYPE+1) == DBR_CHAR)
|
|
def dbr_type_is_LONG(type):
|
|
return (type >= 0) and (type <= LAST_BUFFER_TYPE) and (type%(LAST_TYPE+1) == DBR_LONG)
|
|
def dbr_type_is_DOUBLE(type):
|
|
return (type >= 0) and (type <= LAST_BUFFER_TYPE) and (type%(LAST_TYPE+1) == DBR_DOUBLE)
|
|
|
|
#I am assuming have JCAE, but it is possible to implement over JCA only, prividing the configuration
|
|
properties = ch.psi.jcae.impl.JcaeProperties.getInstance()
|
|
jca= gov.aps.jca.JCALibrary.getInstance()
|
|
context = None
|
|
configuration = gov.aps.jca.configuration.DefaultConfiguration("jython ca context")
|
|
configuration.setAttribute("class", gov.aps.jca.JCALibrary.CHANNEL_ACCESS_JAVA)
|
|
configuration.setAttribute("addr_list", properties.getAddressList())
|
|
configuration.setAttribute("auto_addr_list", str(properties.isAutoAddressList()));
|
|
if properties.getMaxArrayBytes() is not None:
|
|
configuration.setAttribute("max_array_bytes", properties.getMaxArrayBytes())
|
|
if properties.getServerPort() is not None:
|
|
configuration.setAttribute("server_port", properties.getServerPort())
|
|
|
|
def initialize():
|
|
global jca
|
|
global context
|
|
global configuration
|
|
|
|
if context is not None:
|
|
context.destroy()
|
|
|
|
context= jca.createContext(configuration)
|
|
|
|
initialize()
|
|
|
|
|
|
class PutListener(gov.aps.jca.event.PutListener):
|
|
def __init__(self, callback):
|
|
self.callback = callback
|
|
def putCompleted(self, put_ev):
|
|
if put_ev is None:
|
|
self.callback(None , None , None)
|
|
else:
|
|
count = put_ev.getCount()
|
|
status = put_ev.getStatus()
|
|
dbr_type = put_ev.getType()
|
|
self.callback([count, status, dbr_type]) #TODO: Check these: status must be second par
|
|
|
|
def formatCbArgs(status, dbr):
|
|
dbrType = dbr.getType()
|
|
if status <> gov.aps.jca.CAStatus.NORMAL:
|
|
cb_args=[None, status.getValue()]
|
|
else:
|
|
try:
|
|
val = dbr.getValue()
|
|
if val is not None:
|
|
val = val.tolist()
|
|
if len(val) == 1:
|
|
val = val[0]
|
|
if dbr.isSTS():
|
|
cb_args = [val, dbr.getSeverity().getValue(), status.getValue()]
|
|
else:
|
|
cb_args = [val, gov.aps.jca.dbr.Severity.NO_ALARM, status.getValue()]
|
|
if dbr.isTIME():
|
|
timestamp = dbr.getTimeStamp()
|
|
cb_args.append( timestamp.nsec() if (timestamp is not None) else 0.0)
|
|
else:
|
|
cb_args.append(0.0)
|
|
if dbr.isENUM():
|
|
cb_args.append([None, None]) #TODO
|
|
elif dbr.isGR():
|
|
gr=[dbr.getUnits(), dbr.getUpperDispLimit(), dbr.getLowerDispLimit(),
|
|
dbr.getUpperAlarmLimit(), dbr.getUpperWarningLimit(),
|
|
dbr.getLowerAlarmLimit(), dbr.getLowerWarningLimit()]
|
|
if (dbr.isCTRL()):
|
|
gr.append(dbr.getUpperCtrlLimit())
|
|
gr.append(dbr.getLowerCtrlLimit())
|
|
if (dbr.isPRECSION()):
|
|
gr.append(dbr.getPrecision())
|
|
cb_args.append(gr)
|
|
except:
|
|
traceback.print_exc(file=sys.stderr)
|
|
cb_args=[None, None]
|
|
return cb_args
|
|
|
|
|
|
class GetListener(gov.aps.jca.event.GetListener):
|
|
def __init__(self, callback):
|
|
self.callback = callback
|
|
def getCompleted(self, get_ev):
|
|
status = get_ev.getStatus()
|
|
dbr = get_ev.getDBR()
|
|
self.callback(formatCbArgs(status, dbr))
|
|
|
|
class MonitorListener(gov.aps.jca.event.MonitorListener):
|
|
def __init__(self, callback):
|
|
self.callback = callback
|
|
def monitorChanged(self, monitor_ev):
|
|
status = monitor_ev.getStatus()
|
|
dbr = monitor_ev.getDBR()
|
|
self.callback(formatCbArgs(status, dbr))
|
|
#print dbr.getValue()
|
|
|
|
def search(name, callback): #returns channel
|
|
ch= context.createChannel(name)
|
|
context.pendIO(1.0)
|
|
return ch
|
|
|
|
def name(channel):
|
|
return channel.getName()
|
|
|
|
def clear(channel):
|
|
channel.destroy()
|
|
flush()
|
|
|
|
def put(channel, val, not_used, put_callback, req_type):
|
|
type = gov.aps.jca.dbr.DBRType.forValue(req_type)
|
|
if put_callback is not None:
|
|
listener = PutListener(put_callback)
|
|
channel.put(val, listener)
|
|
else:
|
|
channel.put(val)
|
|
flush()
|
|
|
|
def get(channel, get_callback, req_type, count, *args):
|
|
listener = GetListener(get_callback)
|
|
type = gov.aps.jca.dbr.DBRType.forValue(req_type)
|
|
channel.get(type, count, listener)
|
|
flush()
|
|
|
|
|
|
def monitor(channel, event_callback, count, mask, req_type, *args):
|
|
listener = MonitorListener(event_callback)
|
|
type = gov.aps.jca.dbr.DBRType.forValue(req_type)
|
|
monitor = channel.addMonitor(type, count, mask, listener)
|
|
flush()
|
|
return monitor
|
|
|
|
def clear_monitor(event_id):
|
|
event_id.removeMonitorListener(event_id.getMonitorListener())
|
|
flush()
|
|
|
|
def ch_info(channel):
|
|
return (channel.getFieldType().getValue(), channel.getElementCount() ,
|
|
None, channel.getConnectionState().getValue(), channel.getHostName(),
|
|
channel.getReadAccess() , channel.getWriteAccess())
|
|
|
|
|
|
def pend_io(timeout):
|
|
context.pendIO(timeout)
|
|
_checkInterrupted()
|
|
return 0 #for OK
|
|
|
|
|
|
def pend_event(timeout):
|
|
context.pendEvent(timeout)
|
|
_checkInterrupted()
|
|
return 80 #C library always returns ECA_TIMEOUT
|
|
|
|
def poll():
|
|
return pend_event(1e-12)
|
|
|
|
def flush():
|
|
context.flushIO()
|
|
_checkInterrupted()
|
|
return 0
|
|
|
|
|
|
def _checkInterrupted():
|
|
java.lang.Thread.currentThread().sleep(0)
|
|
if java.lang.Thread.currentThread().isInterrupted():
|
|
raise java.lang.InterruptedException()
|
|
|