EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: Begginer with EPICSv4
From: "Pearson, Matthew R." <[email protected]>
To: Ricardo Herrero <[email protected]>
Cc: "<[email protected]>" <[email protected]>
Date: Tue, 24 Feb 2015 16:12:33 +0000
Hi,

The V4 developers may be able to give better advice, but I'll have a go since we've been using V4 for several months.

> 
> First: I think that I should try using Monitor to publish/suscribe for automatic onChange working between a PVServer and a Client, AM I right?

That sounds right. Client side Monitor is what we use to get onChange updates.

> Second: The General architecture for monitor seems a bit complex to me and I need some help to Undestand it. Here are my thoughts and I want to Know if I´m right or where I´m mistaken:
> 
> First you start the client with ClientFactory.start(). In the client side you need to get to a ChannelProvider (in this case "pva"). Then you have to create a Channel from the Provider (but you need a ChannelRequester and I don´t know if I just have to create the object or find it in the net).

On the client side I do this once:

if (!p_ChannelProvider) {
    p_ChannelProvider = epics::pvAccess::getChannelProviderRegistry()->getProvider("pva");
    if (!p_ChannelProvider) {
      throw std::runtime_error("No Channel Provider.");
    }
  }

Then I call createChannel for every channel that I want to connect to. I use a custom ChannelRequester object when calling that method, like:

p_Channel[channel] = (shared_ptr<epics::pvAccess::Channel>)
      (p_ChannelProvider->createChannel(pvName, p_ChannelRequester, ADNED_PV_PRIORITY));

connectStatus = p_ChannelRequester->waitUntilConnected(ADNED_PV_TIMEOUT);

where:
#define ADNED_PV_TIMEOUT 2.0
#define ADNED_PV_PRIORITY epics::pvAccess::ChannelProvider::PRIORITY_DEFAULT

I'm not sure if the custom channel requestor is actually required, but it gives me the ability to wait until a Channel::CONNECTED event occurs. I think one of the examples used this model.


> Continuining with the creation of a PVStructure you can then create also the Monitor (But I don´t know if when I create the channel, this channel has to be a ChannelRPC or not). Also, Is the requester of the monitor the same as the requester of the Channel creation?.

Once the channel is created you can setup a monitor, like:

shared_ptr<epics::pvData::PVStructure> pvRequest = epics::pvData::CreateRequest::create()->createRequest(ADNED_PV_REQUEST);

p_Monitor[channel] = p_Channel[channel]->createMonitor(p_MonitorRequester[channel], pvRequest);

p_MonitorRequester[channel]->waitUntilConnected(ADNED_PV_TIMEOUT);

This uses a similar custom MonitorRequestor, and:
#define ADNED_PV_REQUEST "record[queueSize=100]field()"

So in summary, I have:
1 channel provider
1 channel requestor
An array of monitor requestors (which might be specific to my project)
An array of channels (because I connect to multiple channels)
An array of monitors (one for each channel)

> Finally I don´t see the structure of the MonitorElement, and when I create the Monitor, do I have to make a while loop where I write the commando FOR for the monitor and get there the MonitorElement?

When I create each monitor requestor I pass in a pointer to an object p_nED, that I use like:

void nEDMonitorRequester::monitorEvent(MonitorPtr const & monitor)
  {
    shared_ptr<MonitorElement> update;
    while ((update = monitor->poll())) {
      p_nED->eventHandler(update->pvStructurePtr, m_channelID);
      monitor->release(update);
    }
  }


So when a monitor event comes in I call a function in my application (in fact, a function in an Asyn port driver class), and pass the pointer to the pvData structure into it (along with a custom channel ID that I have).

> 
> In the server side I´m even more lost, as I have seen the createMonitor in ChannelRPC, but  I can´t see any of the parameters configuration (such as the term onChange) that it´s mentioned in the documentation about Monitor.
> 

It's the client that defines the request (get, put, monitor, etc).

We started from this (and a lot of e-mails to V4 developers):
http://epics-pvdata.sourceforge.net/docbuild/pvDatabaseCPP/tip/documentation/pvDatabaseCPP.html#exampleserver

Our example code might not be the best to work from, as we build a custom pvStructure rather than use V4 normative types.

Cheers,
Matt

Data Acquisition and Controls Engineer
Spallation Neutron Source
Oak Ridge National Lab





References:
Begginer with EPICSv4 Ricardo Herrero

Navigate by Date:
Prev: Re: "epicsMutex pthread_mutex_unlock failed" with pyepics/pcaspy Michael Davidsaver
Next: Re: Begginer with EPICSv4 Kasemir, Kay
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Begginer with EPICSv4 Ricardo Herrero
Next: Re: Begginer with EPICSv4 Kasemir, Kay
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 16 Dec 2015 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·