As its name implies, the mirror server provides one to one mapping. However, it should not be difficult to build what you need in a few lines of python code.
I hope the example below helps.
# Terminal 2: Custom PVA Server which listens for a CA PV and updates PVA Channel
$ cat custom_server.py
#!/usr/bin/env python
import time
import pvaccess as pva
class CustomServer(pva.PvaServer):
def __init__(self, caChannelName, pvaChannelName):
self.typeDict = {'current' : pva.DOUBLE, 'previous' : [pva.DOUBLE]}
pva.PvaServer.__init__(self)
self.pvaChannelName = pvaChannelName
self.addRecord(pvaChannelName, pva.PvObject(self.typeDict))
self.sourceCaChannel = pva.Channel(caChannelName, pva.CA)
self.sourceCaChannel.monitor(self.monitor)
self.previousValues = []
self.value = None
def monitor(self, pv):
if self.value is not None:
self.previousValues.append(self.value)
self.value = pv['value']
valueDict = {'current' : self.value, 'previous' : self.previousValues}
pv2 = pva.PvObject(self.typeDict, valueDict)
self.update(self.pvaChannelName, pv2)
if __name__ == '__main__':
typeDict = {'value' : pva.INT, 'previousValues' : [pva.INT]}
s = CustomServer('X1', 'pvapy:X1')
time.sleep(100)
# Run server
$ python custom_server.py
###
# Terminal 3: Run pvget monitor
$ pvget -m -r '' "pvapy:X1"
pvapy:X1 structure
double current 18
double[] previous [14,15,16,17]
pvapy:X1 structure
double current 19
double[] previous [14,15,16,17,18]
pvapy:X1 structure
double current 20
double[] previous [14,15,16,17,18,19]
pvapy:X1 structure
double current 21
double[] previous [14,15,16,17,18,19,20]
...
--
Siniša Veseli
Scientific Software Engineering & Data Management
Advanced Photon Source
Argonne National Laboratory
sveseli at anl.gov
(630)252-9182
Hello Sinisa,
Is the mapping one is to one, as name suggests, or can i add a structure in between to make a composite pva PV.
Regards,
Kuldeep
On Friday, May 6, 2022, Veseli, Sinisa <
sveseli at anl.gov> wrote:
> Hi,
> Not sure if this helps or not, but pvapy comes with mirror server which allows one to expose any CA PV over PVA. You can use it directly via command line, or via the python API, e.g.:
> $ pvapy-mirror-server --channel-map="(pvapy:image,13SIM1:Pva1:Image,PVA)"
>
>>>> import pvaccess as pva
>
>>>> s = pva.PvaMirrorServer()
>
>>>> s.addMirrorRecord('pvapy:image', '13SIM1:Pva1:Image', pva.PVA)
>
> Sinisa
>
> $ pip install pvapy
> $ pvapy-mirror-server -h
> usage: pvapy-mirror-server [-h] [--channel-map CHANNEL_MAP]
> [--runtime RUNTIME] [-v]
> PvaPy Mirror Server
> optional arguments:
> -h, --help show this help message and exit
> --channel-map CHANNEL_MAP, -cm CHANNEL_MAP
> Channel map specification given as a comma-separated
> list of tuples of the form
> (<mirror_channel>,<source_channel>[,source_provider]);
> if specified, source provider must be either "pva" or
> "ca" (default: pva)
> --runtime RUNTIME, -rt RUNTIME
> Server runtime in seconds; values <=0 indicate
> infinite runtime (default: infinite)
> -v, --version show program's version number and exit
>
> --
> Siniša Veseli
> Scientific Software Engineering & Data Management
> Advanced Photon Source
> Argonne National Laboratory
>
sveseli at anl.gov
> (630)252-9182
> ________________________________
> From: Tech-talk <
tech-talk-bounces at aps.anl.gov> on behalf of Mark Rivers via Tech-talk <
tech-talk at aps.anl.gov>
> Sent: Friday, May 6, 2022 7:55 AM
> To:
tech-talk at aps.anl.gov <
tech-talk at aps.anl.gov>; Kuldeep Joshi <
kuldeep.joshi at gmail.com>
> Subject: Re: Embedding pyPVA server in EPICS IOC: How?
>
> Hi Kuldeep,
> There is an areaDetector driver called NDDriverStdArrays that is intended to do more or less what you want, but without Python. It listens for CA monitors on arrays (like those from the sscan record) and puts them into NTNDArrays that can be published with
PVA via NDPluginPva. It has a number of operating options, and so might be able to do what you want.
>
https://areadetector.github.io/master/NDDriverStdArrays/NDDriverStdArraysDoc.html
>
> I realize this does not answer your original question, which is about using Python.
> Mark
> ________________________________
> From: Tech-talk <
tech-talk-bounces at aps.anl.gov> on behalf of Kuldeep Joshi via Tech-talk <
tech-talk at aps.anl.gov>
> Sent: Friday, May 6, 2022 12:09 AM
> To:
tech-talk at aps.anl.gov <
tech-talk at aps.anl.gov>
> Subject: Embedding pyPVA server in EPICS IOC: How?
>
> Hello,
> I am presently having an EPICS IOC with CA protocol, with SynApps toolkit. ( can python softIoc be used with SynApps)
> I wanted the data to be displayed in a Tabular format. For this I set up a separate multi threaded python process, with pyepics on the client side, gathering (monitoring for change) the data from the SynApps SScan Module, this data is processes and published
on a python pvaccess server (pypva) in a tabular format.
> Here I intentionally kept the processing in python code as the user has flexibility to adapt the code without recompiling.
> The EPICS IOC and the python (pyepics client, pypva server) are started as separate processes. I can use procserv to initiate the IOC as well as the python based CA and PVA client-server.
>
> I was wondering if by using pyDevSup or PyDevice, can I directly monitor the SScan data from the IOC and publish it directly to the python pvaccess server. This will save me one external CA connection. ie is it possible in pyDevSup and PyDevice to use the
internal mechanism of IOC for monitoring and acquiring data.
>
> The attempted connection is as below. Is there an easier/elegant way?
>
> <------------------------------------------------------->
> EPICS IOC <--> pyepics <---> pypva <---> phoebus
>
> I tried embedding the above python client server code using pyDevSup and PyDevice I am getting similar warnings in both modules.
> cas warning: Configured TCP port was unavailable.
> cas warning: Using dynamically assigned TCP port 34549,
> cas warning: but now two or more servers share the same UDP port.
> cas warning: Depending on your IP kernel this server may not be
> cas warning: reachable with UDP unicast (a host's IP in EPICS_CA_ADDR_LIST)
> iocRun: All initialization complete
>
> I guess it has to do with the same port used by the IOC and pyepics. How do I separate the port on the client and server side so as to avoid conflict.
>
> Regards,
> Kuldeep Joshi
> PS: I am using the following sequence (in pyepics) as given in the SScan documentation to gather the data
>
> Create local variables to hold cached values of the fields to be monitored, and a local variable (which I'll call "numPoints") to hold the number of data points accumulated.
> Monitor DnnCV, RmCV and VAL (scalar data and control fields).
> Monitor DnnDA, PmRA, DATA, and CPT (array data and control fields).
> Whenever DnnCV, RmCV, or CPT are received, cache the received scalar value in a local variable.
> Whenever DnnDA or PmRA are received, cache the received array value in a local variable.
> When DATA="" is received, clear all data arrays, and reset numPoints to zero.
> When VAL is received, append to all data arrays from cached scalar values, and increment numPoints.
> When DATA="" is received, clear all data arrays and replace with cached array values; set numPoints to the cached value received from CPT.