Giter Site home page Giter Site logo

epics-base / pvapy Goto Github PK

View Code? Open in Web Editor NEW
36.0 36.0 22.0 5.39 MB

pvaPy provides Python bindings for EPICS pvAccess

Home Page: https://epics.anl.gov/extensions/pvaPy/production/index.html

License: Other

Makefile 1.14% Shell 4.31% C++ 67.18% C 0.11% Python 22.12% M4 4.71% Batchfile 0.32% Perl 0.11%
epics python

pvapy's Introduction

---------------------------------------------------------
EPICS Base - the central core of a control system toolkit
---------------------------------------------------------

Copyright UChicago Argonne LLC, as Operator of Argonne
National Laboratory.
Copyright (c) 1991-2003 The Regents of the University of
California, as Operator of Los Alamos National Laboratory.

EPICS Base is distributed subject to a Software License
Agreement found in the file LICENSE that is included with
this distribution.

---------------------------------------------------------

Installation and release information can be found in the
various files in the documentation subdirectory.

Additional information about EPICS including mailing list
archives and subscription instructions, documentation and
training materials, additional components, links to other
websites etc. is available on the EPICS home page at
	https://epics.anl.gov/

$Format:%cD$
$Format:%H$
https://code.launchpad.net/epics-base

pvapy's People

Contributors

abrewe avatar anjohnson avatar bhill-slac avatar dchabot avatar dhickin avatar hhslepicka avatar mdavidsaver avatar mrkraimer avatar ralphlange avatar stevehenke avatar sveseli avatar swelborn avatar tjmaddenargonne avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pvapy's Issues

PvaServer.addRecord not working on Windows 10

I tried pvaccess server on Windows 10 I am unable to add a record to the server.
I tried it with pvapy 4.0.3 and 4.0.2 version.
My python installation is 3.9 on windows
The error is as below.

server.addRecord(sd.ioc+sd.rscan_name+':block_table', blk_tablePV)

Boost.Python.ArgumentError: Python argument types in
PvaServer.addRecord(PvaServer, str, PvObject)
did not match C++ signature:
addRecord(class PvaServer {lvalue}, class std::basic_string<char,struct std::char_traits,class std::allocator > channelName, class PvObject pvObject, class boost::python::api::object onWriteCallback)

configure fails on Debian jessie/testing

Trying to build pvaPy on a 64 bit Debian jessie/testing I get

ralph@debian-testing:~/work/EPICS/V4/pvaPy$ export EPICS_BASE=/usr/lib/epics
ralph@debian-testing:~/work/EPICS/V4/pvaPy$ make configure
cd tools/autoconf && autoreconf --install 
configure.ac:5: installing './compile'
configure.ac:2: installing './install-sh'
configure.ac:2: installing './missing'
cd tools/autoconf && ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for style of include used by make... GNU
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking dependency style of gcc... none
checking for python... /usr/bin/python
checking for a version of Python >= '2.1.0'... yes
checking for a version of Python >=2.6... yes
checking for the distutils Python package... yes
checking for Python include path... -I/usr/include/python2.7
checking for Python library path... -L/usr/lib -lpython2.7
checking for Python site-packages path... /usr/lib/python2.7/dist-packages
checking python extra libraries... -lpthread -ldl  -lutil
checking python extra linking flags... -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
checking consistency of all components of python development environment... yes
checking for g++... g++
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking dependency style of g++... none
./configure: line 4478: syntax error near unexpected token `fi'
./configure: line 4478: `fi'
Makefile:31: recipe for target 'configure' failed
make: *** [configure] Error 2

Question about sub-field ordering

The Normative Types spec says the order of fields matters and must be preserved. This is necessary for NTTable, but (looking at the pvaPy documentation) the column spec gets passed into the PVObject structure using a regular python dictionary, which AIUI doesn't preserve that order. Is this reasoning correct, or is there something else that we haven't understood?

Access security

Is it possible to enable access security using these python bindings?

I wondered if there was an equivalent to doing something like the file based definitions (below) using pvapy.

UAG(uag) {user1,user2}
HAG(hag) {host1,host2}
ASG(DEFAULT) {
    RULE(1,READ)
    RULE(1,WRITE) {
        UAG(uag)
        HAG(hag)
    }
}

Support boost::numpy built into Boost

Since 1.63, Boost includes libboost_numpy and there is no need to install an extra dependency.
However, the headers are under boost/python/numpy.hpp and the namespace is boost::python::numpy.

I've patched the paths and namespaces and haven't seen a problem while building.

Monitored values "freeze" after reconnect

I find that when monitoring a channel which becomes disconected, that after reconnection the callback is invoked when it should be, but the value passed is the last value before disconnect. pvget shows the correct values after reconnect.

#!/usr/bin/env python
import time
import pvaccess as pva
chan = pva.Channel('cnt:x')
def proc(v):
  print v.get()['value']
chan.subscribe('arbitrary', proc)
chan.startMonitor()
while True:
    time.sleep(60)

Note: While this script only prints the value field, I check that no field values are changing after reconnect.

Output with 1 Hz counter PV.

8.0
9.0
10.0
0.0
1.0
2.0
3.0
error cnt:x cnt:x connection state DISCONNECTED
3.0
3.0
3.0
3.0
3.0
3.0
3.0

Output of pvget -m

cnt:x                          8
cnt:x                          9
cnt:x                          10
cnt:x                          0
cnt:x                          1
cnt:x                          2
cnt:x                          3
cnt:x                          *** disconnected
cnt:x                          0
cnt:x                          1
cnt:x                          2
cnt:x                          3
cnt:x                          4
cnt:x                          5
cnt:x                          6
cnt:x                          7

Shared library issue on OSX

The shared library pvaccess.dylib does not work on OSX Yosemite(not sure about other OSX versions but we tested on 4 different machines). The issue goes away if .dylib -> .so linked manually.

PyPI: pvaPy on Raspberry Pi

Hi,
I am unable to get pvaPy from the PyPI repository for my Raspberry Pi.
It would be great if wheel for the Raspberry/ARM are available on PyPI.
Till then I may have to do a manual compile and install.

Thank you in advance
Kuldeep

Compilation without EPICSv4

While trying the examples listed in the Readme I realized it's possible to use pvaPy not only for pvAccess, but also for ChannelAccess. I like the interface of the library even for use with CA. Do you think it would at all be possible to compile a "CA-only"-version of pvaPy, i.e. without EPICSv4 available at compile and/or run time? Features that depend on v4 would of course not be available.

The reason I'm asking is that it would be nice to start using pvaPy in scenarios where only EPICSv3 is available. Later on, as more setups transition to EPICSv4, the Python interface would still be the same and the transition on that end would be easier.

I have not made any attempts at this myself, I wanted to hear your opinion first. I hope it's not too crazy of a question.

putScalarArray fails for numbers > 6 digits

Hi. I am unable to put an array where any value contains a string longer than 6 digits using the method Channel::putScalarArray. However, pvput works fine on the command line.

I also tried constructing a PvScalarArray of type ULONG, but a pvaccess.PvScalarArray is not accepted by Channel::putScalarArray.

Below are the database I used and the commands which can be run to reproduce the error. I am using pvapy 2.2

(dgro_asub) jsparger@spectre:dgro_asub$ pip freeze | grep pvapy
pvapy==2.2.0
record(waveform, "Addresses")
{
    field(DESC, "Addresses")
    field(FTVL, "ULONG")
    field(NELM, "3")
}
In [1]: import pvaccess                                                                              

In [2]: c = pvaccess.Channel("Addresses")                                                            

In [3]: print(c.get())                                                                               
epics:nt/NTScalarArray:1.0 
    uint[] value [123456]
    alarm_t alarm
        int severity 0
        int status 0
        string message NO_ALARM
    time_t timeStamp
        long secondsPastEpoch 1591882692
        int nanoseconds 459499857
        int userTag 0
    structure display
        double limitLow 0
        double limitHigh 0
        string description Addresses
        string units 
        int precision 0
        enum_t form
            int index 0
            string[] choices ["Default", "String", "Binary", "Decimal", "Hex", "Exponential", "Engineering"]
    control_t control
        double limitLow 0
        double limitHigh 0
        double minStep 0
    valueAlarm_t valueAlarm
        boolean active false
        double lowAlarmLimit nan
        double lowWarningLimit nan
        double highWarningLimit nan
        double highAlarmLimit nan
        int lowAlarmSeverity 0
        int lowWarningSeverity 0
        int highWarningSeverity 0
        int highAlarmSeverity 0
        byte hysteresis 0


In [4]: c.putScalarArray([123456])                                                                   

In [5]: c.get()["value"]                                                                             
Out[5]: array([123456], dtype=uint32)

In [6]: c.putScalarArray([1234567])                                                                  
---------------------------------------------------------------------------
PvaException                              Traceback (most recent call last)
<ipython-input-6-4152885d1ebd> in <module>
----> 1 c.putScalarArray([1234567])

PvaException: parseToPOD: Extraneous characters

In [7]: quit()         
                                                                              
(dgro_asub) jsparger@spectre:dgro_asub$ pvput Addresses [1234567]
Old : 2020-06-11 15:39:19.060  [123456]
New : 2020-06-11 15:43:26.610  [1234567]

Requested provider '<all>' not found

Hi,

I am trying to run the examples described at the README file but I am facing the following issue:

(py36) slepicka@dhcp-swlan-public-81-101:~/sandbox/ $ ipython
Python 3.6.2 |Continuum Analytics, Inc.| (default, Jul 20 2017, 13:14:59)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from pvaccess import *

In [2]: pv = PvObject({'x': INT, 'y': INT})

In [3]: pvaServer = PvaServer('pair', pv)
2018-03-13T11:21:58.977 Requested provider '<all>' not found
2018-03-13T11:21:58.977 ServerContext configured with not Providers will do nothing!

VERSION : pvAccess Server v6.0.1-SNAPSHOT
PROVIDER_NAMES :
BEACON_ADDR_LIST :
AUTO_BEACON_ADDR_LIST : 1
BEACON_PERIOD : 15
BROADCAST_PORT : 5076
SERVER_PORT : 5075
RCV_BUFFER_SIZE : 16384
IGNORE_ADDR_LIST:
INTF_ADDR_LIST : 0.0.0.0

Here are some information about versions:

  • python: 3.6.2
  • boost: 1.66.0
  • epics base: R7.0.1.1-50-gd0a5a985f
    • pvAccess: 6.0.0-56-g74fbd22d4
    • pvDatabase: 4.3.0-5-g83101e210
    • pvaClient: 4.3.0-9-g4e4554af4
    • pvData: 7.0.0-19-gf2ad6292f
    • pva2pva: 1.0.0-15-g272b4fb9c
  • pvaPy: 1.0.0-53-g5db28b0

Unqualified setup script names likely to create name clashes

pvaPy installs setup scripts for posix and C shells in INSTALL_BIN, named setup.sh and setup.csh

Such unqualified names are likely to create name clash situations, especially when trying to package pvaPy, which would install these scripts in a larger directory for binaries.

Would it be better to prefix the names, calling them e.g. pvaPy-setup.* ?

Use of MonitorElement after release()

I find that Channel::monitorThread is feeding elements into it's queue, then release()ing them. This allows them to be reused, possible even before they are removed from the queue. The appropriate action is not to call release() for an element until the caller will no longer access it.

std::bad_weak_ptr when removing records

I'm not sure if this a pvapy issue or upstream in EPICS, but removing a record with a connected channel throws an error and causes python to temrinate.

s = pva.PvaServer('foo', pva.PvObject({'value': pva.INT}))
c = pva.Channel('foo')
c.get()
s.removeRecord('foo')

results in

terminate called after throwing an instance of 'std::bad_weak_ptr'
  what():  bad_weak_ptr

I'm using pvapy=1.6.0 and epics-base=7.0.2.2.

make configure does not set the appropriate PVACLIENT and NORMATIVETYPES flags in RELEASE.local (OSX)

EPICS_BASE = /Users/arkilic/epics/base-3.14.12.4
 ⚙ arkilic@gaia  ~/EPICS-CPP-4.5.0-rc1/pvaPy   master  make
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C ./configure install
perl /Users/arkilic/epics/base-3.14.12.4/bin/darwin-x86/makeMakefile.pl O.darwin-x86 ../..
mkdir O.Common
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C O.darwin-x86 -f ../Makefile TOP=../.. T_A=darwin-x86 install
perl /Users/arkilic/epics/base-3.14.12.4/bin/darwin-x86/convertRelease.pl checkRelease

Definition of PVACLIENT conflicts with PVACCESS support.
In this application a RELEASE file defines
    PVACLIENT =
but PVACCESS at /Users/arkilic/EPICS-CPP-4.5.0-rc1/pvAccessCPP defines
    PVACLIENT = /Users/arkilic/EPICS-CPP-4.5.0-rc1/pvaClientCPP
Definition of NORMATIVETYPES conflicts with PVACCESS support.
In this application a RELEASE file defines
    NORMATIVETYPES =
but PVACCESS at /Users/arkilic/EPICS-CPP-4.5.0-rc1/pvAccessCPP defines
    NORMATIVETYPES = /Users/arkilic/EPICS-CPP-4.5.0-rc1/normativeTypesCPP
Definition of PVACLIENT conflicts with PVDATA support.
In this application a RELEASE file defines
    PVACLIENT =
but PVDATA at /Users/arkilic/EPICS-CPP-4.5.0-rc1/pvDataCPP defines
    PVACLIENT = /Users/arkilic/EPICS-CPP-4.5.0-rc1/pvaClientCPP
Definition of NORMATIVETYPES conflicts with PVDATA support.
In this application a RELEASE file defines
    NORMATIVETYPES =
but PVDATA at /Users/arkilic/EPICS-CPP-4.5.0-rc1/pvDataCPP defines
    NORMATIVETYPES = /Users/arkilic/EPICS-CPP-4.5.0-rc1/normativeTypesCPP

make[2]: *** [checkRelease] Error 1
make[1]: *** [install.darwin-x86] Error 2
make: *** [configure.install] Error 2

PvObject set

Hi,

I've encountered an odd issue, but I am not sure if this is a feature or a bug, I am hoping you can clarify.

I notice that when using the set method on PvObject the order of key-value pairs in the dictionary passed to the method can affect subscribers. For example:

pv1 = pvapy.PvObject(.....)

# these two are not the same
pv1.set({'a': 1, 'b': 2})
pv1.set({'b': 2, 'a': 1})

For a full reproducible example, please see the snippet below:

#!/usr/bin/env python

import time
from datetime import datetime

import pvapy as pv

EPOCH = datetime.utcfromtimestamp(0)

def timestampnow():
    dt = datetime.now() - EPOCH
    seconds_since_epoch = int(dt.total_seconds())
    nanoseconds = int(dt.microseconds * 1e3)
    return pv.PvTimeStamp(seconds_since_epoch, nanoseconds)

# my PV
pv1 = pv.PvObject(
    {
        "value": pv.INT,
        "timeStamp": {
            "secondsPastEpoch": pv.LONG,
            "nanoseconds": pv.INT,
            "userTag": pv.INT,
        },
    },
    {
        "value": 0,
        "timeStamp": {
            "secondsPastEpoch": 0,
            "nanoseconds": 0,
            "userTag": 0,
        },
    },
)

# setup a server
server = pv.PvaServer("mypvtest", pv1)

# callback
def echo(x):
    print(
        "** CLIENT **",
        datetime.fromtimestamp(x["timeStamp"]["secondsPastEpoch"]).strftime(
            "%Y-%m-%d %H:%M:%S.%f"
        ),
        x["value"]
    )

# client - subscriber
channel = pv.Channel("mypvtest", pv.ProviderType.PVA)
channel.subscribe("mon", echo)
channel.startMonitor()

counter = 0
while True:
    x = counter
    ts = timestampnow()
    # replace this line with the other below it and notice the difference in output
    pv1.set({"timeStamp": ts, "value": x})
    #pv1.set({"value": x,"timeStamp": ts})
    print(
        "** SERVER **",
        datetime.fromtimestamp(ts["secondsPastEpoch"]).strftime("%Y-%m-%d %H:%M:%S.%f"),
        x
    )
    time.sleep(1)
    counter = counter + 1 if counter < 9 else 0

With timeStamp first we see this output:

** SERVER ** 2021-05-28 14:51:21.000000 0
** CLIENT ** 2021-05-28 14:51:21.000000 0
** SERVER ** 2021-05-28 14:51:22.000000 1
** CLIENT ** 2021-05-28 14:51:22.000000 0
** SERVER ** 2021-05-28 14:51:23.000000 2
** CLIENT ** 2021-05-28 14:51:23.000000 1
** SERVER ** 2021-05-28 14:51:24.000000 3
** CLIENT ** 2021-05-28 14:51:24.000000 2
** SERVER ** 2021-05-28 14:51:25.000000 4
** CLIENT ** 2021-05-28 14:51:25.000000 3
** SERVER ** 2021-05-28 14:51:26.000000 5
** CLIENT ** 2021-05-28 14:51:26.000000 4
** SERVER ** 2021-05-28 14:51:27.000000 6
** CLIENT ** 2021-05-28 14:51:27.000000 5
** SERVER ** 2021-05-28 14:51:28.000000 7
** CLIENT ** 2021-05-28 14:51:28.000000 6
** SERVER ** 2021-05-28 14:51:29.000000 8
** CLIENT ** 2021-05-28 14:51:29.000000 7
** SERVER ** 2021-05-28 14:51:30.000000 9
** CLIENT ** 2021-05-28 14:51:30.000000 8
** SERVER ** 2021-05-28 14:51:31.000000 0
** CLIENT ** 2021-05-28 14:51:31.000000 9
** SERVER ** 2021-05-28 14:51:32.000000 1
** CLIENT ** 2021-05-28 14:51:32.000000 0
** SERVER ** 2021-05-28 14:51:33.000000 2
** CLIENT ** 2021-05-28 14:51:33.000000 1
** SERVER ** 2021-05-28 14:51:34.000000 3
** CLIENT ** 2021-05-28 14:51:34.000000 2

whereas the other way around we see this output.

** SERVER ** 2021-05-28 14:52:59.000000 0
** CLIENT ** 2021-05-28 14:52:59.000000 0
** SERVER ** 2021-05-28 14:53:00.000000 1
** CLIENT ** 2021-05-28 14:52:59.000000 1
** SERVER ** 2021-05-28 14:53:01.000000 2
** CLIENT ** 2021-05-28 14:53:00.000000 2
** SERVER ** 2021-05-28 14:53:02.000000 3
** CLIENT ** 2021-05-28 14:53:01.000000 3
** SERVER ** 2021-05-28 14:53:03.000000 4
** CLIENT ** 2021-05-28 14:53:02.000000 4
** SERVER ** 2021-05-28 14:53:04.000000 5
** CLIENT ** 2021-05-28 14:53:03.000000 5
** SERVER ** 2021-05-28 14:53:05.000000 6
** CLIENT ** 2021-05-28 14:53:04.000000 6
** SERVER ** 2021-05-28 14:53:06.000000 7
** CLIENT ** 2021-05-28 14:53:05.000000 7
** SERVER ** 2021-05-28 14:53:07.000000 8
** CLIENT ** 2021-05-28 14:53:06.000000 8
** SERVER ** 2021-05-28 14:53:08.000000 9
** CLIENT ** 2021-05-28 14:53:07.000000 9
** SERVER ** 2021-05-28 14:53:09.000000 0
** CLIENT ** 2021-05-28 14:53:08.000000 0
** SERVER ** 2021-05-28 14:53:10.000000 1
** CLIENT ** 2021-05-28 14:53:09.000000 1
** SERVER ** 2021-05-28 14:53:11.000000 2
** CLIENT ** 2021-05-28 14:53:10.000000 2
** SERVER ** 2021-05-28 14:53:12.000000 3
** CLIENT ** 2021-05-28 14:53:11.000000 3

You can see in the first one the times are in sync but the values are not, similarly, in the other one the values are in sync but not the times.

My question is, if this is a feature how can I set the both at the same time, so both timestamp and value are in sync with subscribers? If it is a bug, do you know of a workaround?

Thanks,
Tom

Seg fault with arrays

Just installed pvapy 4.0.3 and epics-base 7.0.6 from the epics conda channel with python 3.8. Existing code that was working with previous pvapy versions now fails, and I've traced it back to the following minimal example:

import pvaccess as pva
pva.PvObject({'foo': [pva.STRING]}) # Raises seg. fault

This is not limited to pva.STRING types, but also occurs with pva.INT and possibly others as well. Any suggestions? Otherwise I'll have to roll back.

add custom field to NTSCALAR record

I wondering if it is possible to add a custom field to an NTSCALAR record and still be considered an NTSCALAR record.
I need that for the EPICS archiver appliance because it would archive a PVACCESS record only if it is NTSCALAR, but in my case, I need to add custom fields.

Segmentation Fault

Recently when working with PvaPy I have been getting a Segmentation Fault when trying to create a PV.

I have been working with EPICS version R7.0.5 and pvapy version 3.1.0.

The simplest case where the fault occurs is when running:

from pvaccess import NtScalar, INT
pv = NtScalar(INT)

The backtrace for the above program is:

(gdb) bt
#0  0x00007f7a28e8d2f9 in PyDict_GetItemWithError () from /lib64/libpython3.8.so.1.0
#1  0x00007f7a23ac20bc in PyArray_GetCastingImpl ()
   from /usr/local/lib64/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38-x86_64-linux-gnu.so
#2  0x00007f7a23ac2d88 in PyArray_GetCastSafety ()
   from /usr/local/lib64/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38-x86_64-linux-gnu.so
#3  0x00007f7a23b71765 in PyArray_EquivTypes ()
   from /usr/local/lib64/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38-x86_64-linux-gnu.so
#4  0x00007f7a260c19fa in boost::python::numpy::equivalent(boost::python::numpy::dtype const&, boost::python::numpy::dtype const&) ()
   from /usr/local/lib64/python3.8/site-packages/pvaccess/lib/linux-x86_64/libboost_numpy38.so.1.72.0
#5  0x00007f7a260c230c in ?? () from /usr/local/lib64/python3.8/site-packages/pvaccess/lib/linux-x86_64/libboost_numpy38.so.1.72.0
#6  0x00007f7a262e01ce in boost::python::converter::rvalue_from_python_stage1(_object*, boost::python::converter::registration const&) ()
   from /usr/local/lib64/python3.8/site-packages/pvaccess/lib/linux-x86_64/libboost_python38.so.1.72.0
#7  0x00007f7a2789c8ab in PyPvDataUtility::updateFieldArrayFromInt(boost::python::api::object const&, std::string const&, std::vector<std::tr1::shared_ptr<epics::pvData::Field const>, std::allocator<std::tr1::shared_ptr<epics::pvData::Field const> > >&, std::vector<std::string, std::allocator<std::string> >&) () from /usr/local/lib64/python3.8/site-packages/pvaccess/pvaccess.so
#8  0x00007f7a278a0e44 in PyPvDataUtility::updateFieldArrayFromDict(boost::python::dict const&, std::vector<std::tr1::shared_ptr<epics::pvData::Field const>, std::allocator<std::tr1::shared_ptr<epics::pvData::Field const> > >&, std::vector<std::string, std::allocator<std::string> >&) ()
   from /usr/local/lib64/python3.8/site-packages/pvaccess/pvaccess.so
#9  0x00007f7a278a12e0 in PyPvDataUtility::createStructureFromDict(boost::python::dict const&, std::string const&) ()
   from /usr/local/lib64/python3.8/site-packages/pvaccess/pvaccess.so
#10 0x00007f7a2787e867 in PvObject::PvObject(boost::python::dict const&, std::string const&) ()
   from /usr/local/lib64/python3.8/site-packages/pvaccess/pvaccess.so
#11 0x00007f7a2786db59 in NtType::NtType(boost::python::dict const&, std::string const&) ()
   from /usr/local/lib64/python3.8/site-packages/pvaccess/pvaccess.so
#12 0x00007f7a278693fa in NtScalar::NtScalar(PvType::ScalarType) () from /usr/local/lib64/python3.8/site-packages/pvaccess/pvaccess.so
--Type <RET> for more, q to quit, c to continue without paging--
#13 0x00007f7a27822f5c in boost::python::objects::make_holder<1>::apply<boost::python::objects::value_holder<NtScalar>, boost::mpl::vector1<PvType::ScalarType> >::execute(_object*, PvType::ScalarType) () from /usr/local/lib64/python3.8/site-packages/pvaccess/pvaccess.so
#14 0x00007f7a27800aeb in boost::python::objects::caller_py_function_impl<boost::python::detail::caller<void (*)(_object*, PvType::ScalarType), boost::python::default_call_policies, boost::mpl::vector3<void, _object*, PvType::ScalarType> > >::operator()(_object*, _object*) ()
   from /usr/local/lib64/python3.8/site-packages/pvaccess/pvaccess.so
#15 0x00007f7a262e9611 in boost::python::objects::function::call(_object*, _object*) const ()
   from /usr/local/lib64/python3.8/site-packages/pvaccess/lib/linux-x86_64/libboost_python38.so.1.72.0
#16 0x00007f7a262e9958 in ?? () from /usr/local/lib64/python3.8/site-packages/pvaccess/lib/linux-x86_64/libboost_python38.so.1.72.0
#17 0x00007f7a262f21f3 in boost::python::detail::exception_handler::operator()(boost::function0<void> const&) const ()
   from /usr/local/lib64/python3.8/site-packages/pvaccess/lib/linux-x86_64/libboost_python38.so.1.72.0
#18 0x00007f7a277d4193 in boost::detail::function::function_obj_invoker2<boost::_bi::bind_t<bool, boost::python::detail::translate_exception<PvaException, void (*)(PvaException const&)>, boost::_bi::list3<boost::arg<1>, boost::arg<2>, boost::_bi::value<void (*)(PvaException const&)> > >, bool, boost::python::detail::exception_handler const&, boost::function0<void> const&>::invoke(boost::detail::function::function_buffer&, boost::python::detail::exception_handler const&, boost::function0<void> const&) () from /usr/local/lib64/python3.8/site-packages/pvaccess/pvaccess.so
#19 0x00007f7a262f1fcd in boost::python::handle_exception_impl(boost::function0<void>) ()
   from /usr/local/lib64/python3.8/site-packages/pvaccess/lib/linux-x86_64/libboost_python38.so.1.72.0
#20 0x00007f7a262e6c63 in ?? () from /usr/local/lib64/python3.8/site-packages/pvaccess/lib/linux-x86_64/libboost_python38.so.1.72.0
#21 0x00007f7a28e80f72 in _PyObject_MakeTpCall () from /lib64/libpython3.8.so.1.0
#22 0x00007f7a28e274c9 in method_vectorcall.cold () from /lib64/libpython3.8.so.1.0
#23 0x00007f7a28e8bc3f in PyObject_Call () from /lib64/libpython3.8.so.1.0
#24 0x00007f7a28f24225 in slot_tp_init () from /lib64/libpython3.8.so.1.0
#25 0x00007f7a28e80e0a in _PyObject_MakeTpCall () from /lib64/libpython3.8.so.1.0
#26 0x00007f7a28f3bb97 in _PyEval_EvalFrameDefault () from /lib64/libpython3.8.so.1.0
#27 0x00007f7a28efdf67 in _PyEval_EvalCodeWithName () from /lib64/libpython3.8.so.1.0
#28 0x00007f7a28eff143 in PyEval_EvalCode () from /lib64/libpython3.8.so.1.0
--Type <RET> for more, q to quit, c to continue without paging--
#29 0x00007f7a28f9462a in run_eval_code_obj () from /lib64/libpython3.8.so.1.0
#30 0x00007f7a28fa6d92 in run_mod () from /lib64/libpython3.8.so.1.0
#31 0x00007f7a28e58cf0 in PyRun_FileExFlags () from /lib64/libpython3.8.so.1.0
#32 0x00007f7a28e5fa07 in PyRun_SimpleFileExFlags () from /lib64/libpython3.8.so.1.0
#33 0x00007f7a28fa895f in Py_RunMain () from /lib64/libpython3.8.so.1.0
#34 0x00007f7a28fa8ae9 in Py_BytesMain () from /lib64/libpython3.8.so.1.0
#35 0x00007f7a27de1493 in __libc_start_main () from /lib64/libc.so.6
#36 0x000055f680b3b78e in _start ()

Type IDs cannot be set when creating structures or structure arrays

The current Python API doesn't seem to allow creating a structure with anything other than a default type ID.

If this is the the case pvaPy will not be usable in a real system, since code written in C++/Java is setting the type IDs when creating structures and expecting to them to be set when receiving them.

PvObject does have constructors which take a type ID, so these just need to be exposed in pvaccess.PvObject.cpp

    .def(init<boost::python::dict,const std::string &>(args("structureDict","typeId")))

Which allows structures with type IDs to be created in Python

print PvObject({'value' : DOUBLE}, 'epics:nt/NTScalar:1.0')

However this only allows for creation of top-level IDs. It doesn't allow for setting the type ID of lower-level structures. It looks difficult to create a general structure, including type IDs, using a single dictionary. Since dictionaries, tuples and lists all have special meanings (as structures, unions and arrays) it's not easy to supply an additional string.

It would possible to do it this way

struc3 = PvObject({ 'leaf'   : DOUBLE }, 'type3')
struc2 = PvObject({ 'struc3' : struc3 }, 'type2')
struc1 = PvObject({ 'struc2' : struc2 }, 'type1')

However this requires a change to PyPvDataUtility as the latter loses the type IDs when you use a PvObject to create a subfield. I have this solution for this which generates

type1 
    type2 struc2
        type3 struc3
            double leaf 0

as required. I'll raise the pull request.

Similar comments also apply to structure arrays. I have a similar fix to that for structures, which I'll include in the pull request.

Async functionality should propagate the errors/exceptions to the caller

Recently the asyncGet was added, which works as expected.
But the exceptions (e.g. Timeout) are just logged and not propagated to the user.

I see two possibilities how this could be added (there are probably more):

  • Add a separate callback, which is called on the error.
  • Add extra arguments to the existing callback, which provide the status information.

@sveseli

Question about setting timeStamp

Hello guys! At first, nice work, thank you!

We're trying to update timeStamp of a PV at the moment it is being assigned if I can say that way. The way we're doing seems to be not supported by the library, and we wonder if it would have a good reason to forbid such timeStamp assignment, probably yes... but then, it has a way to do it? We just need to have that timeStamp available at the PV for syncing with another service...

import pvaccess
timeStamp = pvaccess.PvTimeStamp(12345678, 12)
timeStamp
<pvaccess.pvaccess.PvTimeStamp at 0x7f8e6b536050>
print(timeStamp)
time_t 
    long secondsPastEpoch 12345678
    int userTag -1
    int nanoseconds 12
pvTest = pvaccess.PvObject({'value':pvaccess.STRING, 'timeStamp':pvaccess.PvTimeStamp}, {'value':'pvTest001', 'timeStamp':timeStamp})
InvalidArgument: Unrecognized structure type for field name timeStamp

Thank you for any guidance!
/ Douglas B Beniz

PvaClientMonitor::releaseEvent did not call poll

Same test environment as #17 terminated with unhandled exception. Not sure if this issue is with pvaPy or pvaClientCPP. No dis/reconnect involved here.

1.0 1.0
terminate called after throwing an instance of 'std::runtime_error'
  what():  PvaClientMonitor::releaseEvent did not call poll
Aborted

autoconf failure with INSTALL_LOCATION=

Trying to configure pvaPy with INSTALL_LOCATION given

tar -xaf EPICS-CPP-4.6.0.tar.gz
cd EPICS-CPP-4.6.0/
make -j4 EPICS_BASE=/home/mdavidsaver/work/epics/base-git INSTALL_LOCATION=$PWD/root
make -j4  EPICS_BASE=/home/mdavidsaver/work/epics/base-git INSTALL_LOCATION=$PWD/root config.pvaPy
make -j4  EPICS_BASE=/home/mdavidsaver/work/epics/base-git INSTALL_LOCATION=$PWD/root pvaPy
checking for boostlib >= 1.40... yes
configure: Using boost version 105500
checking whether the Boost::Python library is available... yes
checking for exit in -lboost_python... yes
checking for Boost.NumPy library... no
checking how to run the C++ preprocessor... g++ -E
checking for EPICS base directory /home/mdavidsaver/work/epics/base-git... yes
checking for EPICS Base version >= 3.14.12... yes
checking for EPICS Base libraries for linux-x86_64... yes
checking for EPICS4 directory /home/mdavidsaver/work/epics/EPICS-CPP-4.6.0... no
configure: error: "could not find pvAccess installation: no header file /home/mdavidsaver/work/epics/base-git/include/epicsVersion.h"
Makefile:46: recipe for target 'configure' failed
make[1]: *** [configure] Error 1
make[1]: Leaving directory '/home/mdavidsaver/work/epics/EPICS-CPP-4.6.0/pvaPy'
Makefile:140: recipe for target 'pvaPy/configure/RELEASE.local' failed
make: *** [pvaPy/configure/RELEASE.local] Error 2

The epicsVersion.h header does exist at the location mentioned

$ ls /home/mdavidsaver/work/epics/base-git/include/epicsVersion.h
/home/mdavidsaver/work/epics/base-git/include/epicsVersion.h

Possible ref. loops

From the discussion in epics-base/pvAccessCPP#60 I've looked for code using PVA.

@msekoranja states that a Requester should never hold a strong reference (shared_ptr) to the associated Operation. Doing so creates a reference loop which must be explicitly broken as the Operation holds a strong ref. to its Requester. For example, in src/pvaccess/ChannelGetRequesterImpl.h ChannelGetRequesterImpl::channelGet. I haven't look any further than the header, so I don't know if this particular instance is causing a problem. So FYI...

Problem building documentation on RHEL7

pvaPy 2.0.0
Base (C++) 7.0.3.1
Python 2.7

On RHEL7, the sphinx_rtd_theme can be installed from EPEL as python2-sphinx_rtd_theme-0.2.4-3.el7.noarch.rpm. (This pulls a few dependencies for the fonts.)

After that, the pvaPy documentation build still fails with:

make[1]: Entering directory `/home/DCS/langer/work/CODAC/m-python-pvapy/target/pvaPy-2.0.0/documentation'
. /home/DCS/langer/work/CODAC/m-python-pvapy/target/pvaPy-2.0.0/bin/linux-x86_64/pvapy_setup_full.2.7.sh; make -C sphinx default
make[2]: Entering directory `/home/DCS/langer/work/CODAC/m-python-pvapy/target/pvaPy-2.0.0/documentation/sphinx'
export PATH=`dirname /usr/bin/sphinx-build`:/usr/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/DCS/langer/bin && make -f Makefile.sphinx html
make[3]: Entering directory `/home/DCS/langer/work/CODAC/m-python-pvapy/target/pvaPy-2.0.0/documentation/sphinx'
sphinx-build -b html -d _build/doctrees   . _build/html
Running Sphinx v1.1.3
loading pickled environment... not yet created
[ERROR] Theme error:
[WARN] no theme named 'sphinx_rtd_theme' found (missing theme.conf?)
[WARN] make[3]: *** [html] Error 1
make[3]: Leaving directory `/home/DCS/langer/work/CODAC/m-python-pvapy/target/pvaPy-2.0.0/documentation/sphinx'
make[2]: Leaving directory `/home/DCS/langer/work/CODAC/m-python-pvapy/target/pvaPy-2.0.0/documentation/sphinx'
make[1]: Leaving directory `/home/DCS/langer/work/CODAC/m-python-pvapy/target/pvaPy-2.0.0/documentation'
[WARN] make[2]: *** [html] Error 2
[WARN] make[1]: *** [default] Error 2
[WARN] make: *** [doc] Error 2

What am I missing?

Error when requesting multiple fields from the same struct

I'm getting an error when trying to request fields from the same struct. Here is the pv structure:

   structure
        structure obj1
            float[] x
            float[] y
        structure obj2
            float[] x
            float[] y

When I get the PV with the request descriptor 'obj1.x,obj2.y' I get the following error:

ERROR Channel:  channel Ch1 PvaClientChannel::createMonitor invalid pvRequest: Can't construct Structure, duplicate fieldName obj1

Question about alarms

Hello again...

We're now trying to set an alarm to a PV.

Firstly, being honest, I still have a question if pvaPy should do this (in fact I'm helping someone else, so, I'm still understanding the requirements and why they decided to use pvaPy).

Then, what is desired (and my questions are: first, is possible to do it using pvaPy, second, how to do it):

  • set alarms
  • set limits (lolo, lo, hi, hihi)
  • if the value reaches limits, then alarms being set automatically.

Go to what we (they) did (and the alarms were not set automatically, as I expected because we didn't programme anything to set the alarms considering the value):

from pvaccess import *

# assigning some objects
# ----------------------------------------------
# PvTimeStamp(<long secondsPastEpoch>,
#             <int nanoseconds>,
#             <int userTag=-1>)
# ----------------------------------------------
ts      = PvTimeStamp(12345678, 12)
# ----------------------------------------------
# PvAlarm(<int severity>,
#         <int status>,
#         <string message>)
# ----------------------------------------------
alarm   = PvAlarm(13,-1,'testing an error!')

# creating a PV object
pv = PvObject(  {'value':           FLOAT,
                    'timeStamp':    ts,
                    'alarm':        alarm,
                    'descriptor':   STRING,
                    'lo':           FLOAT,
                    'lolo':         FLOAT,
                    'hi':           FLOAT,
                    'hihi':         FLOAT },
                {'value':           250.67
                    'timeStamp':    ts.toDict(),
                    'alarm':        alarm.toDict(),
                    'descriptor':   'A first test PV name 001',
                    'lo':           -321.15,
                    'lolo':         -321.75,
                    'hi':           32.65,
                    'hihi':         33.00} )

print(pv)

# ----------------------------------------------
# output
# ----------------------------------------------
douglasbeniz@douglasbeniz-thinkpad:~/Documents$ python pvaPy_example.py 
structure 
    string descriptor A first test PV name 001
    float hi 32.65
    float lo -321.15
    time_t timeStamp
        long secondsPastEpoch 12345678
        int userTag -1
        int nanoseconds 12
    alarm_t alarm
        int status -1
        string message testing an error!
        int severity 13
    float hihi 33
    float lolo -321.75
    float value 250.67

Review performance testing

Hello, I've written a small Python module https://github.com/ajgdls/EPICSPyClientPerformance to compare the performance of 6 Python based EPICS clients. I have attempted to test each in a consistent way, and the README has some preliminary results for monitoring 1000 records at 10Hz for 1000 samples.

I would really appreciate it if this module owner would review EPICSPyClientPerformance test code for this client implementation to check that I'm actually testing in the correct and most efficient way. I would be happy to make updates that shows an increase in performance for this client.

This testing is driven by Diamond Light Source, and on 1st December the tests will be re-run against latest PyPI versions and then published (probably tech-talk) for further discussion, so if anyone wants to push performance optimisations they will get picked up on that date.

Thanks for taking a look, looking forward to hearing from everyone.

No way to stop PvaServer

There is no way to stop a running PvaServer. There should be an explicit PvaServer.stop() method or similar. It would also be nice if PvaServer was a context manager so we could do

with PvaServer() as server:
    # Do stuff

compile for aarch64

I am trying to compile and install it on NVIDIA Jetson TX2 using the automated compiling solution. but got errors as follow. appreciate if someone can help to figure out a solution

configure: Verifying boost python library
checking whether boost_python37 is the correct library... no
checking whether boost_python37 is the correct library... (cached) no
checking whether boost_python37 is the correct library... (cached) no
checking whether boost_python37 is the correct library... (cached) no
checking whether boost_python37 is the correct library... (cached) no
checking whether boost_python is the correct library... no
checking whether boost_python is the correct library... (cached) no
checking whether boost_python3 is the correct library... no
configure: error: in /home/zliu/pvaPy/tools/local/pvapy-local/build/pvaPy-4.0.3': configure: error: Could not verify boost python library; check your boost installation See config.log' for more details
Makefile:53: recipe for target 'configure' failed
make[2]: *** [configure] Error 1
make[2]: Leaving directory '/home/zliu/pvaPy/tools/local/pvapy-local/build/pvaPy-4.0.3'
Makefile:11: recipe for target 'build' failed
make[1]: *** [build] Error 1
make[1]: Leaving directory '/home/zliu/pvaPy/tools/local/pvapy-local'
Makefile:111: recipe for target 'package-pvapy-local' failed
make: *** [package-pvapy-local] Error 2

Best method for handling reconnections to large numbers of PVs

Hello,

In our group we are using pvapy for a number of applications but primarily to host a number of PvaServers. We then have a separate application that connects to the PVs on these servers using the Channel client to monitor them for changes.

So far, the functionality of both applications has worked well, but we are now facing a number of issues with reconnection protocols. I have tried two different methods to account for PV reconnections so far and both have created their own problems. I'm not sure if these are a result of how I'm doing the reconnection using the library or something in our system...

The methods I've tested so far are:

  1. I create the Channel object for the client, if the PV is down and it times out, we subscribe the onChanges function to monitor for updates anyway and just wait for the channel to connect and start receiving messages at some point in the future

This method works well if the PvaServer is stopped cleanly, but encounters problems if the PvaServer crashes unexpectedly. In this case we stop receiving updates for the PVs through the assigned onChanges function, even though we can see the PVs updating with a pvmonitor on the command line.

  1. I create the Channel object for the client and assign a connection callback using the setConnectionCallback() method. In this method we subscribe the onChanges function and start monitoring the PV. When it disconnects, we stop monitoring the channel.

This second option feels to me to be the cleaner of the two. However, we noticed alternating crashes between the PvaServer and the client application. We haven't yet worked out which of the two programs is responsible for the crashes. We also encountered some segmentation faults using this method.

In your opinion, what is the best way to handle these situations where potentially lots of PVs become disconnected at once? Do you have any advice for how to handle reconnections on the client side, and is there anything you might be able to suggest for the server side to improve the closure of PV connections?

Thanks for your help!

timestamp not updating with pvput for PVs on PvaServer

Hi there, I've been using pvapy to set up my own PV server and update the values of the timestamps and PVs through the PvObject set method as a message arrives from another system. So far this works very well and the timestamps update as expected.

However, I would also like to be able to control the value of PVs through the standard pvput command line tool and I've found that I can do this fine to set the value, but the command doesn't update the timestamp, instead it uses the timestamp declared previously, e.g.

test 1990-01-01 00:00:00.456  -1 0
test 1990-01-01 00:00:00.456  -1 5

I've tried fixing this by setting the timestamp manually using the server.update() method within an onWriteCallback assigned to the PV when it is added to the server (see the code below). What this appears to do is update the value, and then immediately after it updates the timestamp, so when I monitor the channel I receive two updates for every pvput, like this:

test 1990-01-01 00:00:00.456  -1 0
test 1990-01-01 00:00:00.456  -1 5
test 2021-08-13 15:09:29.659  -1 5
test 2021-08-13 15:09:29.659  -1 6
test 2021-08-13 15:09:38.949  -1 6
test 2021-08-13 15:09:38.949  -1 7
test 2021-08-13 15:09:58.518  -1 7

In order to apply some extra formatting to the values from the other system I am using an object that inherits from the PvObject class. I can see that in the onWriteCallback a standard PvObject is passed as the parameter which is why I have to call set on my inherited PvObjects within the callback. I understand this would generate a new update (as a new set method is called), but I'm not sure how to avoid this if I want to manually update the timestamp.

Is it essential that the object is an ordinary PvObject for the server.update method to work, or have I misunderstood how the pvput command relates to the PvaServer and the onWriteCallback, and that actually it isn't supposed to update the timestamp anyway?

I've included some code below that is a representation of how I am currently using the onWriteCallback and inherited classes to help illustrate what I mean. Running this with pvput produces the pvmonitor output shown above.

from pvapy import PvaServer, INT, PvObject, STRING, PvTimeStamp
import time

def extract_seconds_and_nanoseconds_from_timestamp(timestamp):
    seconds = int(timestamp // 1)
    nanoseconds = int((timestamp % 1) * 1e9)
    return seconds, nanoseconds


class ServerManager():
    def __init__(self):
        self.pvaserver = PvaServer()
        self.pv = None

    def create_pv_and_add_to_server(self, name):
        timestamp = PvTimeStamp(123, 456000000)
        pv = InheritedPvObject(
            {'channelname': STRING, 'value': INT, 'timeStamp': timestamp},
            {'channelname': name, 'timeStamp': timestamp.toDict()}
        )
        self.pv = pv
        self.pvaserver.addRecord(name, self.pv.copy(), self.echo)

    def echo(self, pv_object):
        # extract the information from the pvobject that comes through (different type to
        # the inherited one so we can't assign it straight off)
        pv_object_fields = pv_object.get()

        # update the timestamp
        seconds, nanoseconds = extract_seconds_and_nanoseconds_from_timestamp(
            time.time())
        timestamp = PvTimeStamp(seconds, nanoseconds)
        pv_object_fields['timeStamp'] = timestamp.toDict()

        # set the new value in the Inherited object
        self.pv.set(pv_object_fields)

        # update the inherited object on the server with the new information
        channel_name = pv_object_fields.get('channelname')
        self.pvaserver.update(
            channel_name, self.pv)


class InheritedPvObject(PvObject):
    def __init__(self, type_dict, value_dict):
        PvObject.__init__(self, type_dict, value_dict)


if __name__ == '__main__':
    try:
        server = ServerManager()
        server.create_pv_and_add_to_server('test')
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print('stopping server')
    finally:
        server.pvaserver.stop()

I am currently working in Python 3.6.8 with pvapy (3.1.0) on CentOS Linux release 8.4.2105, alongside EPICS version R7.0.5

Any guidance as to why this issue may be arising would be a great help. Thank you.

Setting Timeout for RpcClient

I would like to set timeout for RpcClient, but there seems be no way to set it. The timeout is set as DefaultTimeout and its value is 1. It is convenient if there are getTimeout and setTimeout like Channel class. Do you have any plan for RpcClient timeout?

Channel.450.cpp blocking connect in ctor

Channel.450.cpp has a blocking call to connect() in its constructor (Channel.440.cpp does not). This makes it inefficient to connect multiple channels in parallel, and throws an exception if the channel isn't available at the time of construction.

In my mind there is no need to block until an method is called which needs the connection to be established (eg. 'get()').

PvAlarm and PvTimeStamp do not work for put

The following is putTime.py:

from pvapy import Channel, PvTimeStamp
channel = Channel('PVRdouble')
timestamp = PvTimeStamp(10, 100,1)
print('start value=',channel.get('timeStamp'))
channel.put(timestamp,'record[process=false]field(timeStamp)')
val = channel.get('value,alarm,timeStamp')
print('after put timeStamp value=',channel.get('timeStamp'))

It uses the database from exampleCPP

When the database is started and the following is issued

python putTime.py

The following is the result

start value= structure 
time_t timeStamp
    long secondsPastEpoch 0
    int nanoseconds 0
    int userTag 0

after put timeStamp value= structure 
time_t timeStamp
    long secondsPastEpoch 0
    int nanoseconds 0
    int userTag 0

Maybe the problem is that none of the PvAlarm and PyTimeStamp code has a get method?

Dumping to JSON does not escape strings

PvObject.toJSON() does not properly escape strings which can result in malformed JSON. For example,

>>> pva.PvObject({'foo': pva.STRING}, {'foo': '"bar"'}).toJSON(True)
'{\n "foo": ""bar""\n}'

This cannot be loaded by e.g., json.loads. The correct output is

>>> json.dumps({'foo': '"bar"'})
'{"foo": "\\"bar\\""}'

2 questions about usage

Hi.

Sorry but I have some questions which I am struggling to find answers to.

  1. I can subscribe to a PV and get its value change events, but I cannot seem to find a way to supply a callback for notification when the PV disconnects. Is there a way to do this that I am missing?

  2. Is it possible to do a blocking/waiting put? E.g. something like: chan.put('MY:PV', 10, wait=True)

Thanks

Mirror server slow processing large struct arrays

Problem:
PV servers has difficultly keeping up reading PV objects with very large struct arrays. The same issue appears with both mirror server and p2p.
Steps to reproduce:

  1. IOC is writing PV array with 27000 struct elements to a PV channel at 10hz
  2. Run mirror server mapped to PV channel to a second PV channel
  3. Run pvapy client to read data from the second PV channel

The pvapy client receives the data at 4Hz. The TCP-rx thread in the mirror server is maxed out and the perf profile shows that it is spending most time creating and deleting struct arrays (see graph below):

image

Both the mirror server and pv client can be optimized by caching the PV object structure after the connection is initialized.

deprecated methods of pvaClientCPP

The following deprecated methods of pvaClientCPP are called:
static PvaClientPtr create() EPICS_DEPRECATED
and
static PvaClientMonitorPtr create(
PvaClientPtr const &pvaClient,
std::string const & channelName,
std::string const & providerName,
std::string const & request,
PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester
= PvaClientChannelStateChangeRequesterPtr(),
PvaClientMonitorRequesterPtr const & monitorRequester
= PvaClientMonitorRequesterPtr() ) EPICS_DEPRECATED;

https://github.com/mrkraimer/pvaPy
has changes so that these two methods are no longer called.

I want to do some more testing before a pull request is created.
For now anyone who is interested can clone the mrkraimer repository.

Incomplete definition of distclean

It seems that make distclean does not remove

  • configure/RELEASE.linux-x86_64.Common
  • tools/autoconf/compile

But it should, shouldn't it?

Suppress pvInfo stdout

Hi,

Not sure if this is an issue, but I would like to know how to suppress the std out from the C++ pvAccess library which shows everytime you start up a PvaServer:

pvAccess Server v7.1.2
Active configuration (w/ defaults)
EPICS_PVAS_INTF_ADDR_LIST = 0.0.0.0:5075
EPICS_PVAS_BEACON_ADDR_LIST =
EPICS_PVAS_AUTO_BEACON_ADDR_LIST = YES
EPICS_PVAS_BEACON_PERIOD = 15
EPICS_PVAS_BROADCAST_PORT = 5076
EPICS_PVAS_SERVER_PORT = 5075
EPICS_PVAS_PROVIDER_NAMES = local

I can't find any option in the documentation, but maybe I've been looking in the wrong place.

Any help on this would be greatly appreciated.

NtScalar give segfault with numpy 1.21.0

I just had issues with segfault when using pvapy. In the end (i hope) it turned out that in the installation of pvapy it also installs numpy 1.21.0 and it seem that that version causes a seg fault at least when trying to creeate a pvaccess.NtScalar object.
By reinstalling numpy version 1.20.3 i do not get this issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.