Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use pvxslibs #133

Closed
Closed
Show file tree
Hide file tree
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
6 changes: 2 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@
devIocStats_src, devIocStats_os, devIocStats_default
],
dsos = [
'epicscorelibs.lib.qsrv',
'epicscorelibs.lib.pvAccessIOC',
'epicscorelibs.lib.pvAccess',
'epicscorelibs.lib.pvData',
'epicscorelibs.lib.dbRecStd',
'epicscorelibs.lib.dbCore',
'epicscorelibs.lib.ca',
Expand Down Expand Up @@ -95,6 +91,8 @@ def install_for_development(self):
install_requires = [
# Dependency version declared in pyproject.toml
epicscorelibs.version.abi_requires(),
"pvxslibs>=1.2.1a1",
"setuptools_dso>=2.4",
"numpy",
"epicsdbbuilder>=1.4"
],
Expand Down
49 changes: 36 additions & 13 deletions softioc/__init__.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,51 @@
'''Python soft IOC module.'''
import os

from epicscorelibs import path
from epicscorelibs.ioc import \
iocshRegisterCommon, registerRecordDeviceDriver, pdbbase

# Do this as early as possible, in case we happen to use cothread
# This will set the CATOOLS_LIBCA_PATH environment variable in case we use
# cothread.catools. It works even if we don't have cothread installed
import epicscorelibs.path.cothread # noqa

# This import will also pull in the extension, which is needed
# before we call iocshRegisterCommon
from .imports import dbLoadDatabase
from ._version_git import __version__
from .imports import dbLoadDatabase

def load_dbd():
import ctypes
from epicscorelibs import path
from epicscorelibs.ioc import \
iocshRegisterCommon, registerRecordDeviceDriver, pdbbase
import pvxslibs.path
from setuptools_dso.runtime import find_dso

dbd_paths = ':'.join([
os.path.join(path.base_path, 'dbd'),
pvxslibs.path.dbd_path,
os.path.join(os.path.dirname(__file__), "iocStats", "devIocStats"),
])
dbds = [
'base.dbd', # must be first
'devIocStats.dbd',
'pvxsIoc.dbd',
]

# Need to do this before calling anything in device.py
iocshRegisterCommon()
for dbd in dbds:
dbLoadDatabase(dbd, dbd_paths, None)

from ._extension import install_pv_logging
dbRecStd = ctypes.CDLL(find_dso('epicscorelibs.lib.dbRecStd'), ctypes.RTLD_GLOBAL)
pvxsIoc = ctypes.CDLL(find_dso('pvxslibs.lib.pvxsIoc'), ctypes.RTLD_GLOBAL)

# must explicitly enable QSRV while "Feature Preview"
os.environ.setdefault('PVXS_QSRV_ENABLE', 'YES')

# Need to do this before calling anything in device.py
iocshRegisterCommon()
for dbd in ('base.dbd', 'PVAServerRegister.dbd', 'qsrv.dbd'):
dbLoadDatabase(dbd, os.path.join(path.base_path, 'dbd'), None)
iocStats = os.path.join(os.path.dirname(__file__), "iocStats", "devIocStats")
dbLoadDatabase('devIocStats.dbd', iocStats, None)
if registerRecordDeviceDriver(pdbbase):
raise RuntimeError('Error registering')

if registerRecordDeviceDriver(pdbbase):
raise RuntimeError('Error registering')
load_dbd()
del load_dbd

__all__ = ['__version__']
35 changes: 35 additions & 0 deletions softioc/softioc.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,41 @@ def call_f(*args):
and any other value means yes.''',
lib=imports.Com)

class IOCSh(object):
class Caller:
'''
Wrapper around iocshCmd() to translate eg.
iocsh.dbpr("MY-DEVICE-PREFIX:AI", 2)
into
iocshCmd("dbpr MY-DEVICE-PREFIX:AI 2")
'''
iocshCmd = imports.Com.iocshCmd
iocshCmd.argtypes = (auto_encode,)
iocshCmd.restype = c_int
def __init__(self, name):
self.name = name
def __call__(self, *args):
cmd = [self.name]
for arg in args:
# TODO escape quote chars once this would work.
# https://github.com/epics-base/epics-base/issues/362
if isinstance(arg, str) and arg.find(' ')!=-1:
arg = f'"{arg}"'
else:
arg = str(arg)
cmd.append(arg)
cmd = ' '.join(cmd)
ret = self.iocshCmd(cmd)
if ret!=0:
raise RuntimeError(ret)
def __getattr__(self, name):
if name.startswith('__'):
return super().__getattr__(name)
else:
return self.Caller(name)
IOCSh.__doc__ = IOCSh.Caller.__doc__
iocsh = IOCSh()
command_names.append('iocsh')

# Hacked up exit object so that when soft IOC framework sends us an exit command
# we actually exit.
Expand Down