fandango.callbacks module

Description

## file : callbacks..py ## ## description : This class manages a list of attributes subscribed to events that could have multiple receivers each one. ## It supplies the ATK AttributeList behaviour. ## device.DevChild and those inherited classes depends on that. ## Global objects are: ## _EventsList, _EventReceivers, _StatesList, _AttributesList, GlobalCallback ## ... _EventReceivers must be substituted by DevicesList ## ## project : Tango Control System ## ## $Author: Sergi Rubio Manrique, srubio@cells.es $ ## ## $Revision: 2008 $ ## ## copyleft : ALBA Synchrotron Controls Section, CELLS ## Bellaterra ## Spain ## ############################################################################# ## ## This file is part of Tango Control System ## ## Tango Control System is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as published ## by the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## Tango Control System is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, see <http://www.gnu.org/licenses/>. ###########################################################################

Classes

TAttr

class fandango.callbacks.TAttr(name, dev_name='', proxy=None, event_id=None)[source]

This class is used to keep information about events received, example of usage inside device.DevChild

EventStruct

class fandango.callbacks.EventStruct[source]

EventListener

class fandango.callbacks.EventListener(name, parent=None, source=False)[source]
The EventListener class accepts 3 event hooks:
self.set_event_hook() self.set_error_hook() self.set_value_hook()

All of them need a callable accepting three arguments: src,type,value

In the case of value_hook it will not pass the event object but event.value/rvalue

eventReceived(src, type_, value)[source]

Method to implement the event notification Source will be an object, type a PyTango EventType, evt_value an AttrValue

CachedAttributeProxy

class fandango.callbacks.CachedAttributeProxy(name, keeptime=1000.0, fake=False, parent=None, **kw)[source]

TangoListener

class fandango.callbacks.TangoListener(name, parent=None, source=False)[source]
The EventListener class accepts 3 event hooks:
self.set_event_hook() self.set_error_hook() self.set_value_hook()

All of them need a callable accepting three arguments: src,type,value

In the case of value_hook it will not pass the event object but event.value/rvalue

EventCallback

class fandango.callbacks.EventCallback[source]

It provides persistent storage. lock.acquire and lock.release should be used to prevent threading problems!, Use of the lists inside push_event is safe

EventSource

class fandango.callbacks.EventSource(name, keeptime=1000.0, fake=False, parent=None, **kw)[source]

Simplified implementation of Taurus Attribute/Model and fandango.CachedAttributeProxy classes

It implements CachedAttributeProxy methods but doesnt inherit from it; this regression is due to the lack of reliability of AttributeProxy in PyTango 9.

Documentation at doc/recipes/EventsAndCallbacks.rst

Slow Polling will be always enabled, as a KeepAlive is always kept reading the attribute values at an slow rate.

Well, will be always enabled as long there are Listeners or Forced is True. If not polling will not be activated and it will be simply a CachedAttributeProxy.

In this implementation, just a faster polling will be enabled if the attribute provides no events. But the slow polling will never be fully disabled.

If no events are received after EVENT_TIMEOUT, polling wil be also enabled.

It will also subscribe to all attribute events, not only CHANGE and CONFIG

All types are: ‘CHANGE_EVENT,PERIODIC_EVENT,QUALITY_EVENT,ARCHIVE_EVENT,ATTR_CONF_EVENT,DATA_READY_EVENT,USER_EVENT’

Arguments to EventSource(...) are:

  • name : attribute name (simple or full)
  • parent : device name or proxy
  • enablePolling (force polling by default)
  • pollingPeriod (3000)
  • keeptime (500 ms) min. time (in ms!) between HW reads
  • tango_asynch = True/False ; to use asynchronous Tango reading
  • listeners = a list of listeners to be added at startup
  • persistent = if True, a dummy listener is added to enforce subscription

Arguments are supported in CamelCase and lowercase to keep compatibility with previous apis (CachedProxy and TaurusAttribute).

Keep in mind that if tango_asynch=True; you will not get the latest value when doing read(cache=False). You must use read(cache=False,asynch=False) instead.

@TODO: Listeners should be assignable to only one type of eventl. @TODO: read(cache=False) should trigger fireEvent if not called from poll()

addListener(listener, use_events=True, use_polling=False)[source]

Adds a Listener to this EventSource object. use_events can be a boolean or a list of event types (change,attr_conf,periodic,archive)

changePollingPeriod(period)[source]

change polling period to period miliseconds

checkEvents(tdiff=None, vdiff=None)[source]

tdiff: max time difference allowed between last_event_time and current time vdiff: difference between last event value and current hw value

fireEvent(event_type, event_value, listeners=None)[source]

sends an event to all listeners or a specific one event type filtering is done here poll() events will be allowed to pass through

getMode()[source]

SYNCHRONOUS = 0 EVENTS = 1 POLLED = 2

getPollingPeriod()[source]

returns the polling period

hasListeners()[source]

returns True if anybody is listening to events from this attribute

isPollingEnabled()[source]

It should be called isPollingAllowed instead

isUsingEvents()[source]

This method doesnt tell if it wants to use_events but if it is actually receiving them

read(cache=None, asynch=None, _raise=True)[source]

Read last value acquired, if cache = False or not polled it will trigger a proxy.read_attribute() call.

If asynch=True/False, self.tango_asynch will be overriden for this call.

removeListener(listener, exclude='dummy')[source]

Remove a listener object or callback. :listener: can be object, weakref, sequence or ‘*’

set_cache(value, t=None)[source]

set_cache and fake are used by PyAlarm.update_locals It’s used to emulate alarm state reading from other devices

static thread()[source]

It returns the current EventThread INSTANCE Use EventSource.thread().setup(...) to configure it

write(value, with_read=None)[source]

The with_read argument will trigger a read() call and an update in all listeners

AttrCallback

class fandango.callbacks.AttrCallback(name='fandango.Logger', parent=None, format='%(levelname)-8s %(asctime)s %(name)s: %(message)s', use_tango=True, use_print=True, level='INFO', max_len=0)[source]

TangoAttribute

class fandango.callbacks.TangoAttribute(name, keeptime=1000.0, fake=False, parent=None, **kw)[source]

Simplified implementation of Taurus Attribute/Model and fandango.CachedAttributeProxy classes

It implements CachedAttributeProxy methods but doesnt inherit from it; this regression is due to the lack of reliability of AttributeProxy in PyTango 9.

Documentation at doc/recipes/EventsAndCallbacks.rst

Slow Polling will be always enabled, as a KeepAlive is always kept reading the attribute values at an slow rate.

Well, will be always enabled as long there are Listeners or Forced is True. If not polling will not be activated and it will be simply a CachedAttributeProxy.

In this implementation, just a faster polling will be enabled if the attribute provides no events. But the slow polling will never be fully disabled.

If no events are received after EVENT_TIMEOUT, polling wil be also enabled.

It will also subscribe to all attribute events, not only CHANGE and CONFIG

All types are: ‘CHANGE_EVENT,PERIODIC_EVENT,QUALITY_EVENT,ARCHIVE_EVENT,ATTR_CONF_EVENT,DATA_READY_EVENT,USER_EVENT’

Arguments to EventSource(...) are:

  • name : attribute name (simple or full)
  • parent : device name or proxy
  • enablePolling (force polling by default)
  • pollingPeriod (3000)
  • keeptime (500 ms) min. time (in ms!) between HW reads
  • tango_asynch = True/False ; to use asynchronous Tango reading
  • listeners = a list of listeners to be added at startup
  • persistent = if True, a dummy listener is added to enforce subscription

Arguments are supported in CamelCase and lowercase to keep compatibility with previous apis (CachedProxy and TaurusAttribute).

Keep in mind that if tango_asynch=True; you will not get the latest value when doing read(cache=False). You must use read(cache=False,asynch=False) instead.

@TODO: Listeners should be assignable to only one type of eventl. @TODO: read(cache=False) should trigger fireEvent if not called from poll()

EventThread

class fandango.callbacks.EventThread(period_ms=None, filtered=False, latency=10.0, loglevel='WARNING')[source]

This class processes both Events and Polling. All listeners should implement eventReceived method All sources must have a listeners list On Current EventSource implementation this is a SINGLETONE!!!, its configuration will apply for the whole running process!

The filtered argument will just forward last event received on each loop iteration for each source. It can be set to False, True or a factor of latency.

The latency (ms) specifies a time condition to abort event checking and proceed to callback execution.

The real latency of the system is provided by inherited get_delay and get_avg_delay methods

fireEvent(source, *args)[source]

It just retriggers every EventSource fireEvent method If there’s no method nor listeners, a callable is launched

process()[source]

Currently, this implementation will process 100 events for each polling each time as max.

setup(period_ms=None, filtered=None, latency=None, loglevel=None)[source]

This method allows to reconfigure an already running EventThread

Functions

getEventFor

fandango.callbacks.getEventFor(attname)[source]

getSubscribedItems

fandango.callbacks.getSubscribedItems(receiver)[source]

It returns a list with all devices managed by callbacks to which this receiver is effectively subscribed

setAttributeValue

fandango.callbacks.setAttributeValue(attr_name, attr_value)[source]

inStatesList

fandango.callbacks.inStatesList(devname)[source]

getStateFor

fandango.callbacks.getStateFor(devname)[source]

setStateFor

fandango.callbacks.setStateFor(devname, state)[source]

inAttributesList

fandango.callbacks.inAttributesList(attname)[source]

get_test_objects

fandango.callbacks.get_test_objects(model='controls02:10000/test/sim/tonto/Pressure', period=1.0)[source]

v,tl = fandango.callbacks.get_test_objects()

subscribeDeviceAttributes

fandango.callbacks.subscribeDeviceAttributes(self, dev_name, attrs)[source]

This is how attributes were registered in the old PyStateComposer

__test__

fandango.callbacks.__test__(args)[source]

addTAttr

fandango.callbacks.addTAttr(tattr)[source]

getEventItems

fandango.callbacks.getEventItems()[source]

inEventsList

fandango.callbacks.inEventsList(attname)[source]

getAttrValueFor

fandango.callbacks.getAttrValueFor(attname)[source]

addReceiver

fandango.callbacks.addReceiver(attribute, receiver)[source]

raw autodoc

class fandango.callbacks.AttrCallback(name='fandango.Logger', parent=None, format='%(levelname)-8s %(asctime)s %(name)s: %(message)s', use_tango=True, use_print=True, level='INFO', max_len=0)[source]

Bases: fandango.log.Logger, fandango.objects.Object

attr_read(*args, **kwargs)[source]
class fandango.callbacks.CachedAttributeProxy(name, keeptime=1000.0, fake=False, parent=None, **kw)[source]

Bases: fandango.callbacks.EventSource

class fandango.callbacks.EventCallback[source]

It provides persistent storage. lock.acquire and lock.release should be used to prevent threading problems!, Use of the lists inside push_event is safe

push_event(event)[source]
class fandango.callbacks.EventListener(name, parent=None, source=False)[source]

Bases: fandango.log.Logger, fandango.objects.Object

The EventListener class accepts 3 event hooks:
self.set_event_hook() self.set_error_hook() self.set_value_hook()

All of them need a callable accepting three arguments: src,type,value

In the case of value_hook it will not pass the event object but event.value/rvalue

eventReceived(src, type_, value)[source]

Method to implement the event notification Source will be an object, type a PyTango EventType, evt_value an AttrValue

set_error_hook(callable=None)[source]
set_event_hook(callable=None)[source]
set_value_hook(callable=None)[source]
class fandango.callbacks.EventSource(name, keeptime=1000.0, fake=False, parent=None, **kw)[source]

Bases: fandango.log.Logger, fandango.objects.SingletonMap

Simplified implementation of Taurus Attribute/Model and fandango.CachedAttributeProxy classes

It implements CachedAttributeProxy methods but doesnt inherit from it; this regression is due to the lack of reliability of AttributeProxy in PyTango 9.

Documentation at doc/recipes/EventsAndCallbacks.rst

Slow Polling will be always enabled, as a KeepAlive is always kept reading the attribute values at an slow rate.

Well, will be always enabled as long there are Listeners or Forced is True. If not polling will not be activated and it will be simply a CachedAttributeProxy.

In this implementation, just a faster polling will be enabled if the attribute provides no events. But the slow polling will never be fully disabled.

If no events are received after EVENT_TIMEOUT, polling wil be also enabled.

It will also subscribe to all attribute events, not only CHANGE and CONFIG

All types are: ‘CHANGE_EVENT,PERIODIC_EVENT,QUALITY_EVENT,ARCHIVE_EVENT,ATTR_CONF_EVENT,DATA_READY_EVENT,USER_EVENT’

Arguments to EventSource(...) are:

  • name : attribute name (simple or full)
  • parent : device name or proxy
  • enablePolling (force polling by default)
  • pollingPeriod (3000)
  • keeptime (500 ms) min. time (in ms!) between HW reads
  • tango_asynch = True/False ; to use asynchronous Tango reading
  • listeners = a list of listeners to be added at startup
  • persistent = if True, a dummy listener is added to enforce subscription

Arguments are supported in CamelCase and lowercase to keep compatibility with previous apis (CachedProxy and TaurusAttribute).

Keep in mind that if tango_asynch=True; you will not get the latest value when doing read(cache=False). You must use read(cache=False,asynch=False) instead.

@TODO: Listeners should be assignable to only one type of eventl. @TODO: read(cache=False) should trigger fireEvent if not called from poll()

DEFAULT_EVENTS = ['periodic', 'change', 'archive', 'quality']
DEFAULT_LOG = 'WARNING'
DUMMY = <fandango.callbacks.EventListener object at 0x7eff57513a50>
DefaultPolling = 3000.0
EVENT_TIMEOUT = 900
INSTANCES = []
KeepAlive = 15000.0
PROXIES = defaultdict(<bound method ProxiesDict.__default_factory__ of defaultdict(..., {})>, {})
QUEUE = None
STATES = fandango.Struct({ 'FORCED': 4, 'SUBSCRIBED': 3, 'FAILED': -1, 'UNSUBSCRIBED': 0, 'SUBSCRIBING': 2, 'PENDING': 1, })
TAURUS_EVENTS = ['change', 'attr_conf']
VALUE_EVENTS = ['periodic', 'change', 'archive', 'quality', 'user_event']
activatePolling(period=None, force=None)[source]
addListener(listener, use_events=True, use_polling=False)[source]

Adds a Listener to this EventSource object. use_events can be a boolean or a list of event types (change,attr_conf,periodic,archive)

asynch_hook()[source]
changePollingPeriod(period)[source]

change polling period to period miliseconds

checkEvents(tdiff=None, vdiff=None)[source]

tdiff: max time difference allowed between last_event_time and current time vdiff: difference between last event value and current hw value

checkEventsReceived(types=None)[source]
checkState(*states)[source]
cleanUp()[source]
deactivatePolling()[source]
decodeAttrInfoEx(attr_conf)[source]
disablePolling()[source]
enablePolling(force=False)[source]
fireEvent(event_type, event_value, listeners=None)[source]

sends an event to all listeners or a specific one event type filtering is done here poll() events will be allowed to pass through

forcePolling(period=None)[source]
getMode()[source]

SYNCHRONOUS = 0 EVENTS = 1 POLLED = 2

getParent()[source]
getParentObj()[source]
getPollingPeriod()[source]

returns the polling period

getValueObj()[source]
hasListeners()[source]

returns True if anybody is listening to events from this attribute

isPollingActive()[source]
isPollingEnabled()[source]

It should be called isPollingAllowed instead

isPollingForced()[source]
isUsingEvents()[source]

This method doesnt tell if it wants to use_events but if it is actually receiving them

poll()[source]
push_event(event)[source]
read(cache=None, asynch=None, _raise=True)[source]

Read last value acquired, if cache = False or not polled it will trigger a proxy.read_attribute() call.

If asynch=True/False, self.tango_asynch will be overriden for this call.

removeListener(listener, exclude='dummy')[source]

Remove a listener object or callback. :listener: can be object, weakref, sequence or ‘*’

resetStats()[source]
setState(state)[source]
set_cache(value, t=None)[source]

set_cache and fake are used by PyAlarm.update_locals It’s used to emulate alarm state reading from other devices

static start_thread()[source]
subscribeEvents(types=None, asynchronous=True)[source]
static thread()[source]

It returns the current EventThread INSTANCE Use EventSource.thread().setup(...) to configure it

unsubscribeEvents()[source]
write(value, with_read=None)[source]

The with_read argument will trigger a read() call and an update in all listeners

class fandango.callbacks.EventStruct[source]
event = None
name = ''
receivers = []
class fandango.callbacks.EventThread(period_ms=None, filtered=False, latency=10.0, loglevel='WARNING')[source]

Bases: fandango.log.Logger, fandango.threads.ThreadedObject

This class processes both Events and Polling. All listeners should implement eventReceived method All sources must have a listeners list On Current EventSource implementation this is a SINGLETONE!!!, its configuration will apply for the whole running process!

The filtered argument will just forward last event received on each loop iteration for each source. It can be set to False, True or a factor of latency.

The latency (ms) specifies a time condition to abort event checking and proceed to callback execution.

The real latency of the system is provided by inherited get_delay and get_avg_delay methods

EVENT_POLLING_RATIO = 1000
MinWait = 0.0001
fireEvent(source, *args)[source]

It just retriggers every EventSource fireEvent method If there’s no method nor listeners, a callable is launched

get(*args, **kwargs)[source]
get_pending()[source]
get_source_name(source)[source]
get_source_names(source='.*')[source]
get_sources(source='.*')[source]
has_source(source)[source]
process()[source]

Currently, this implementation will process 100 events for each polling each time as max.

put(*args)[source]
register(source)[source]
set_period_ms(period)[source]
setup(period_ms=None, filtered=None, latency=None, loglevel=None)[source]

This method allows to reconfigure an already running EventThread

wait(tout=None)[source]
class fandango.callbacks.TAttr(name, dev_name='', proxy=None, event_id=None)[source]

Bases: fandango.callbacks.EventStruct

This class is used to keep information about events received, example of usage inside device.DevChild

set(event)[source]
class fandango.callbacks.TangoAttribute(name, keeptime=1000.0, fake=False, parent=None, **kw)[source]

Bases: fandango.callbacks.EventSource

Simplified implementation of Taurus Attribute/Model and fandango.CachedAttributeProxy classes

It implements CachedAttributeProxy methods but doesnt inherit from it; this regression is due to the lack of reliability of AttributeProxy in PyTango 9.

Documentation at doc/recipes/EventsAndCallbacks.rst

Slow Polling will be always enabled, as a KeepAlive is always kept reading the attribute values at an slow rate.

Well, will be always enabled as long there are Listeners or Forced is True. If not polling will not be activated and it will be simply a CachedAttributeProxy.

In this implementation, just a faster polling will be enabled if the attribute provides no events. But the slow polling will never be fully disabled.

If no events are received after EVENT_TIMEOUT, polling wil be also enabled.

It will also subscribe to all attribute events, not only CHANGE and CONFIG

All types are: ‘CHANGE_EVENT,PERIODIC_EVENT,QUALITY_EVENT,ARCHIVE_EVENT,ATTR_CONF_EVENT,DATA_READY_EVENT,USER_EVENT’

Arguments to EventSource(...) are:

  • name : attribute name (simple or full)
  • parent : device name or proxy
  • enablePolling (force polling by default)
  • pollingPeriod (3000)
  • keeptime (500 ms) min. time (in ms!) between HW reads
  • tango_asynch = True/False ; to use asynchronous Tango reading
  • listeners = a list of listeners to be added at startup
  • persistent = if True, a dummy listener is added to enforce subscription

Arguments are supported in CamelCase and lowercase to keep compatibility with previous apis (CachedProxy and TaurusAttribute).

Keep in mind that if tango_asynch=True; you will not get the latest value when doing read(cache=False). You must use read(cache=False,asynch=False) instead.

@TODO: Listeners should be assignable to only one type of eventl. @TODO: read(cache=False) should trigger fireEvent if not called from poll()

class fandango.callbacks.TangoListener(name, parent=None, source=False)[source]

Bases: fandango.callbacks.EventListener

The EventListener class accepts 3 event hooks:
self.set_event_hook() self.set_error_hook() self.set_value_hook()

All of them need a callable accepting three arguments: src,type,value

In the case of value_hook it will not pass the event object but event.value/rvalue

fandango.callbacks.addReceiver(attribute, receiver)[source]
fandango.callbacks.addTAttr(tattr)[source]
fandango.callbacks.getAttrValueFor(attname)[source]
fandango.callbacks.getEventFor(attname)[source]
fandango.callbacks.getEventItems()[source]
fandango.callbacks.getStateFor(devname)[source]
fandango.callbacks.getSubscribedItems(receiver)[source]

It returns a list with all devices managed by callbacks to which this receiver is effectively subscribed

fandango.callbacks.get_test_objects(model='controls02:10000/test/sim/tonto/Pressure', period=1.0)[source]

v,tl = fandango.callbacks.get_test_objects()

fandango.callbacks.inAttributesList(attname)[source]
fandango.callbacks.inEventsList(attname)[source]
fandango.callbacks.inStatesList(devname)[source]
fandango.callbacks.setAttributeValue(attr_name, attr_value)[source]
fandango.callbacks.setStateFor(devname, state)[source]
fandango.callbacks.subscribeDeviceAttributes(self, dev_name, attrs)[source]

This is how attributes were registered in the old PyStateComposer