Project

General

Profile

Python DPM API

The Python DPM API is available for use on the clx nodes. NOTE: This is still an experimental module. Feedback from our users is greatly appreciated.

Examples

The DPM module supports two styles of programming, blocking and polling. If your script is driven by the arrival of data, you probably want to use the blocking API.

This is a simple, blocking script to print M:OUTTMP at 1Hz:

#!/usr/bin/env python2
import DPM

dpm = DPM.Blocking()
dpm.addEntry(0, 'M:OUTTMP@e,8f')

for ii in dpm.process():
    print ii
#!/usr/bin/env python3
import DPM

dpm = DPM.Blocking()
dpm.add_entry(0, 'M:OUTTMP@e,8f')

for ii in dpm.process():
    print(ii)

If your script does other things and occasionally wants to check if data has arrived, use the polling API. Each call to DPM.pending() returns all the items that have arrived since the previous call. In this example, after processing all the pending data, the script sleeps before looping back and handling more data that has arrived.

#!/usr/bin/env python2
import time
import DPM

dpm = DPM.Polling()
dpm.addEntry(0, "M:OUTTMP@e,8f")
dpm.start()

while True:
    for ii in dpm.pending():
        print ii
    print 'sleeping...'
    time.sleep(1.5)
#!/usr/bin/env python3
import time
import DPM

dpm = DPM.Polling()
dpm.add_entry(0, "M:OUTTMP@e,8f")
dpm.start()

while True:
    for ii in dpm.pending():
        print(ii)
    print('sleeping...')
    time.sleep(1.5)

Context Manager

The DPM class supports Python's context manager protocol, so it can be used in a with-statement. The benefit of this is, when the scope of the with-statement is exited, the DPM object immediately closes its connection with DPM. In the previous examples, the connection gets closed when the garbage collector eventually reclaims the DPM object (of course, this example never exits, so the use of with is unnecessary.)

#!/usr/bin/env python2
import time
import DPM

with DPM.Polling() as dpm:
    dpm.addEntry(0, "M:OUTTMP@e,8f")
    dpm.start()

    while True:
        for ii in dpm.pending():
            print ii
        print 'sleeping...'
        time.sleep(1.5)
#!/usr/bin/env python3
import time
import DPM

with DPM.Polling() as dpm:
    dpm.add_entry(0, "M:OUTTMP@e,8f")
    dpm.start()

    while True:
        for ii in dpm.pending():
            print(ii)
        print('sleeping...')
        time.sleep(1.5)

Use Resources Responsibly

The DPM object creates an underlying acnet.Connection object. For a script that simply uses one DPM object, this is fine. However, if you want to create multiple DPM objects, or if your script uses another (not yet written) Acnet service, you should reduce your resource usage. Specifically, all Acnet services should share one Acnet connection object. The DPM constructors take an optional parameter which specifies an Acnet connection to use rather than create its own. For instance:

con = acnet.Connection()

dpm1 = DPM.Polling(con)
dpm2 = DPM.Polling(con)

Using a Test Node

The DPM object will accept a string as the second argument that defines what "task@node" or "node" should be used in the transaction. This allows users to request that their request be routed through test code.

dpm = DPM.Blocking(None, "VIRT01")

Alternative Data Sources

DPM can provide data other than live data. Alternative data sources can be specified for individual requests in the DRF string or for all requests when passed to the DPM start method. When a data source is specified in the DRF string, it supersedes the data source passed to the start method.

#!/usr/bin/env python3
import DPM

dpm = DPM.Blocking()
dpm.add_entry(0, 'M:OUTTMP@e,8f')

for ii in dpm.process("LOGGERDURATION:60000"):
    print(ii)
#!/usr/bin/env python3
import time
import DPM

dpm = DPM.Polling()
dpm.add_entry(0, "M:OUTTMP@e,8f")
dpm.start("LOGGERDURATION:60000")

while True:
    for ii in dpm.pending():
        print(ii)
    print('sleeping...')
    time.sleep(1.5)

A caveat for running Python 3 on clx nodes

Include the following in your `.bashrc` file to change to Python 3.

source /opt/rh/rh-python36/enable
export X_SCLX="`scl enable rh-python36 'echo $X_SCLS'`"