Changeset 642


Ignore:
Timestamp:
Oct 4, 2011 1:32:41 AM (12 years ago)
Author:
jemian
Message:

converted CaPython code to PyEpics? - still need to handle widget updates better, needs a separate thread

Location:
moxy/trunk/src/moxy
Files:
1 added
1 deleted
7 edited
1 moved

Legend:

Unmodified
Added
Removed
  • moxy/trunk/src/moxy/examples/USAXS_XY.xml

    r56 r642  
    11<?xml version="1.0" ?>
    2 <?xml-stylesheet type="text/xsl" href="wxmtxy_settings.xsl" ?>
     2<?xml-stylesheet type="text/xsl" href="moxy_settings.xsl" ?>
    33
    44<!--
     
    1212-->
    1313
    14 <wxmtxy date="2009-04-12" time="17:04:29" version="1.0">
     14<moxy date="2009-04-12" time="17:04:29" version="1.0">
    1515  <XYpair name="sample" selected="True">
    1616    <EPICS_configuration>
    1717      <axis name="y">
    1818        <flag isMotorRec="True"/>
    19         <field name="VAL" pv="32idbLAX:m58:c2:m2"/>
     19        <field name="VAL" pv="prj:m2"/>
    2020      </axis>
    2121      <axis name="x">
    2222        <flag isMotorRec="True"/>
    23         <field name="VAL" pv="32idbLAX:m58:c2:m1"/>
     23        <field name="VAL" pv="prj:m1"/>
    2424      </axis>
    2525    </EPICS_configuration>
     
    4949      <axis name="y">
    5050        <flag isMotorRec="True"/>
    51         <field name="VAL" pv="32idbLAX:m58:c2:m5"/>
     51        <field name="VAL" pv="prj:m4"/>
    5252      </axis>
    5353      <axis name="x">
    5454        <flag isMotorRec="True"/>
    55         <field name="VAL" pv="32idbLAX:m58:c2:m4"/>
     55        <field name="VAL" pv="prj:m3"/>
    5656      </axis>
    5757    </EPICS_configuration>
     
    8888    </tab>
    8989  </XYpair>
    90 </wxmtxy>
     90</moxy>
  • moxy/trunk/src/moxy/examples/test-settings.xml

    r56 r642  
    11<?xml version="1.0" ?>
    2 <?xml-stylesheet type="text/xsl" href="wxmtxy_settings.xsl" ?>
     2<?xml-stylesheet type="text/xsl" href="moxy_settings.xsl" ?>
    33
    44<!--
     
    1212-->
    1313
    14 <wxmtxy date="2009-04-21" time="22:42:25" version="1.0">
     14<moxy date="2009-04-21" time="22:42:25" version="1.0">
    1515  <XYpair name="a1y &amp; a2y test motors" selected="True">
    1616    <EPICS_configuration>
    1717      <axis name="y">
    1818        <flag isMotorRec="True"/>
    19         <field name="VAL" pv="32idbLAX:m58:c1:m2"/>
     19        <field name="VAL" pv="prj:m2"/>
    2020      </axis>
    2121      <axis name="x">
    2222        <flag isMotorRec="True"/>
    23         <field name="VAL" pv="32idbLAX:m58:c1:m1"/>
     23        <field name="VAL" pv="prj:m1"/>
    2424      </axis>
    2525    </EPICS_configuration>
     
    3030    </tab>
    3131  </XYpair>
     32  <!--
    3233  <XYpair name="torture set" selected="not True">
    3334    <EPICS_configuration>
     
    8384    <tab/>
    8485  </XYpair>
     86   -->
    8587  <XYpair>
    8688    <EPICS_configuration>
     
    115117      <axis name="y">
    116118        <flag isMotorRec="True"/>
    117         <field name="VAL" pv="32idbLAX:m58:c1:m2.VAL"/>
    118         <field name="RBV" pv="32idbLAX:m58:c1:m2.RBV"/>
    119         <field name="EGU" pv="32idbLAX:m58:c1:m2.EGU"/>
    120         <field name="DESC" pv="32idbLAX:m58:c1:m2.DESC"/>
    121         <field name="DMOV" pv="32idbLAX:m58:c1:m2.DMOV"/>
    122         <field name="STOP" pv="32idbLAX:m58:c1:m2.STOP"/>
     119        <field name="VAL"  pv="prj:m4.VAL"/>
     120        <field name="RBV"  pv="prj:m4.RBV"/>
     121        <field name="EGU"  pv="prj:m4.EGU"/>
     122        <field name="DESC" pv="prj:m4.DESC"/>
     123        <field name="DMOV" pv="prj:m4.DMOV"/>
     124        <field name="STOP" pv="prj:m4.STOP"/>
    123125      </axis>
    124126      <axis name="x">
    125127        <flag isMotorRec="True"/>
    126         <field name="VAL" pv="32idbLAX:m58:c1:m1"/>
     128        <field name="VAL" pv="prj:m3"/>
    127129      </axis>
    128130    </EPICS_configuration>
     
    142144    </tab>
    143145  </XYpair>
    144 </wxmtxy>
     146</moxy>
  • moxy/trunk/src/moxy/moxy.py

    r641 r642  
    5757
    5858
     59# Note:  If you are using Ubuntu 11.04 and cannot see a menubar,
     60#   this is a bug in Ubuntu 11.04. Try setting the environment
     61#   variable: UBUNTU_MENUPROXY=1
     62import os
     63os.environ['UBUNTU_MENUPROXY'] = '1'
     64
     65
    5966import wx
    6067import root
    61 #import pvConnect
    6268import sys
    6369
     
    8692
    8793
    88 #def on_exit(timer, epics_db):
    89 #    '''Exit handler to stop the ca.poll()
    90 #        @param timer: CaPollWx object
    91 #        @param epics_db: Python list of pvConnect.EpicsPv objects to be released'''
    92 #    #print __name__, "exit handler"
    93 #    #for item in epics_db:
    94 #    #    item.release()
    95 #    if pvConnect.IMPORTED_CACHANNEL:
    96 #        pvConnect.on_exit(timer)
    97 
    98 
    9994def main():
    10095    '''operate the tool'''
     
    10499        settingsFile = sys.argv[1]
    105100    root.root(None, settingsFile).Show()
    106     #capoll_timer = None
    107     #if pvConnect.IMPORTED_CACHANNEL:
    108     #    capoll_timer = pvConnect.CaPollWx(0.1)
    109     #    capoll_timer.start()
    110101    application.MainLoop()
    111     #on_exit(capoll_timer, None)
    112102
    113103
  • moxy/trunk/src/moxy/moxy_axis.py

    r641 r642  
    11#!/usr/bin/env python
    2 from compiler.ast import TryExcept
    32
    43#*************************************************************************
     
    1110#*************************************************************************
    1211
    13 '''EPICS PVs and connections for one axis
     12'''
     13EPICS PVs and connections for one axis
     14'''
    1415
    15 @version:
     16
    1617########### SVN repository information ###################
    1718# $Date$
     
    2122# $Id$
    2223########### SVN repository information ###################
    23 '''
    2424
    2525
     
    7979        self.config = copy.deepcopy(config)
    8080
    81     def Connect(self):
     81    def Connect(self, **args):
    8282        '''
    8383        Try to initiate EPICS connection with named PVs
    8484       
     85        :param dict args: table of callback handlers using fields as the keys
    8586        :return: if all axes connected
    8687        :rtype: bool
     
    101102        # Now, connect and monitor each PV
    102103        for field, pv in self.pvname.items():
    103             ch = epics.PV(pv)
    104             self.db[field] = ch
     104            self.db[field] = ch = epics.PV(pv)
    105105            kw = {'index': None,
    106106                  'with_ctrlvars': True,
    107107                  'field': field,
    108108                  }
    109             i = ch.add_callback(onChanges, **kw)
    110             self.cb_index[field] = i        # use later to disconnect
     109            if 'axis' in args:
     110                kw['axis'] = args['axis']
     111            if field in args:
     112                callback = args[field]
     113            else:
     114                callback = onChanges
     115            if callback is not None:
     116                self.cb_index[field] = ch.add_callback(callback, **kw)        # use later to disconnect
    111117
    112118        return failures == 0
     
    138144
    139145
    140 #class _data:
    141 #    '''the internal data associated with a single PV'''
    142 #
    143 #    def __init__(self):
    144 #        '''only create the space'''
    145 #        self.pv = None
    146 #        self.connection = None
    147 #        self.widget = None
    148 #
    149 #    def GetPv(self):
    150 #        ''':return: [string] EPICS PV name'''
    151 #        return self.pv
    152 #
    153 #    def SetPv(self, pv):
    154 #        '''
    155 #        set the PV name
    156 #       
    157 #        :param str pv: EPICS PV name
    158 #        :see: http://cars9.uchicago.edu/software/python/pyepics3/pv.html
    159 #        '''
    160 #        self.pv = pv
    161 #        self.connection = epics.PV(pv)
    162 #
    163 #    def GetConnection(self):
    164 #        '''@return: pyEpics.PV object'''
    165 #        return self.connection
    166 #
    167 #    def GetWidget(self):
    168 #        '''@return: widget object'''
    169 #        return self.widget
    170 #
    171 #    def SetWidget(self, widget):
    172 #        '''set widget object to be used in a callback
    173 #            :param widget: used as self.widget(value)'''
    174 #        self.widget = widget
    175 #
    176 #    def _callback(self, value):
    177 #        '''
    178 #        receive EPICS CA monitor value
    179 #       
    180 #        :param value: from epics_get['pv_value']
    181 #        '''
    182 #        # print __name__, self.pv, value, self.connection.epics_args, self.connection.user_args
    183 #        if self.widget != None:
    184 #            self.widget(value)
    185 
    186 
    187146# example code follows
    188147
     
    196155    print kw['timestamp'], kw['pvname'], kw['value']
    197156
    198 def _main_callback(epics_args, user_args):
    199     '''EPICS monitor event received for test code'''
    200     value = epics_args['pv_value']
    201     pv = user_args[0]
    202     # pprint.pprint(epics_args)
    203     print '_main_callback:', pv, value
    204157
    205 
    206 if __name__ == '__main__':
     158def main ():
    207159    config = {
    208160        'x': {
     
    222174    axes = {}
    223175    for axis in config:
    224 
    225176        axes[axis] = item = Axis()
    226177        item.SetConfigure(config[axis])
     
    239190    for axis in config:
    240191        axes[axis].Disconnect()
     192
     193
     194if __name__ == '__main__':
     195    main()
  • moxy/trunk/src/moxy/pair.py

    r635 r642  
    3030import moxy_axis
    3131import wx.lib.scrolledpanel
    32 #import pvConnect
    3332import copy
    3433import pprint
     
    239238        #self.SetMotorColor("x", True)
    240239        #self.SetMotorColor("y", False)
    241         self.SetEpicsConfig({'x': {}, 'y': {}})
     240        self.SetEpicsConfig({'x': {'isMotorRec': False}, 'y': {'isMotorRec': False}})
    242241
    243242# ################################
     
    353352            self.epics[axis].SetConfigure(copy.deepcopy(config[axis]))
    354353
    355     def CallbackPositions(self, epics_args, user_args):
    356         '''receive a callback on the VAL and RBV fields'''
    357         axis = user_args[0][0]
    358         field = user_args[0][1]
    359         value = epics_args['pv_value']
    360         if epics_args.has_key('pv_precision'):
     354    def onChangePositions(self, **kw):
     355        '''receive a PyEpics callback on the VAL and RBV fields'''
     356        # TODO: logging?
     357        axis = kw['axis']
     358        field = kw['field']
     359        value = kw['value']
     360        print "onChangePositions", axis, field, value
     361        if 'precision' in kw:
    361362            # what about display precision?
    362             fmt = '%.' + str(epics_args['pv_precision'])
     363            fmt = '%.' + str(kw['precision'])
    363364            abs_value = abs(value)
    364365            if abs_value >= 1e5 or (abs_value < 1e-5 and abs_value > 0):
     
    369370        else:
    370371            str_value = str(value)
    371         self.widget[axis][field] .SetLabel(str_value)
     372        # TODO: either callbacks or widget updates should be in a different thread
     373        self.widget[axis][field].SetLabel(str_value)
    372374        self.Layout()
    373375
    374     def CallbackTitle(self, epics_args, user_args):
    375         '''receive a callback on the DESC and EGU fields'''
    376         axis = user_args[0][0]
    377         field = user_args[0][1]
    378         value = epics_args['pv_value']
     376    def onChangeTitle(self, **kw):
     377        '''receive a PyEpics callback on the DESC and EGU fields'''
     378        # TODO: logging?
     379        axis = kw['axis']
     380        field = kw['field']
     381        value = kw['value']
     382        print "onChangePositions", axis, field, value
    379383        self.titles[axis][field] = value
    380384        title = "%s, %s" % (self.titles[axis]['DESC'], self.titles[axis]['EGU'])
    381         self.widget[axis]['title'] .SetLabel(title)
    382 
    383     def CallbackDMOV(self, epics_args, user_args):
    384         '''receive a callback on the DMOV field'''
    385         axis = user_args[0][0]
    386         value = epics_args['pv_value']
     385        # TODO: either callbacks or widget updates should be in a different thread
     386        self.widget[axis]['title'].SetLabel(title)
     387
     388    def onChangeDMOV(self, **kw):
     389        '''receive a PyEpics callback on the DMOV field'''
     390        #print "onChangeDMOV", kw.keys()
     391        # TODO: logging?
     392        axis = kw['axis']
     393        value = kw['value']
     394        # TODO: either callbacks or widget updates should be in a different thread
    387395        self.SetMotorColor(axis, value == 1)
    388396
    389397    def ConnectEpics(self):
    390398        '''try to connect the XY_pair PV names with EPICS'''
    391         #+++++++++++++++++++++++++++++++
    392         # need to replace this starting from the example in moxy_axis.main()
    393         #+++++++++++++++++++++++++++++++
    394         for axis in ['x', 'y']:
    395             cfg = self.epics[axis].GetConfigure()
    396             for field in ['VAL', 'RBV']:
    397                 item = self.epics[axis].db[field]
    398                 item.connection.SetUserCallback(self.CallbackPositions)
    399                 item.connection.SetUserArgs((axis, field))
    400                 item.SetWidget(self.widget[axis][field] .SetLabel)
    401 
    402             # advanced handling
    403             desc = self.epics[axis].db['DESC']
    404             desc.connection.SetUserCallback(self.CallbackTitle)
    405             desc.connection.SetUserArgs((axis, 'DESC'))
    406 
    407             egu = self.epics[axis].db['EGU']
    408             egu.connection.SetUserCallback(self.CallbackTitle)
    409             egu.connection.SetUserArgs((axis, 'EGU'))
    410 
    411             dmov = self.epics[axis].db['DMOV']
    412             dmov.connection.SetUserCallback(self.CallbackDMOV)
    413             dmov.connection.SetUserArgs((axis, 'DMOV'))
    414 
    415             # do not need to setup the STOP button
    416 
    417             cfg['AXIS'] = axis
    418             #pprint.pprint(cfg)
    419             self.epics[axis].Connect()
     399        redirects = {
     400                    'VAL':  self.onChangePositions,
     401                    'RBV':  self.onChangePositions,
     402                    'EGU':  self.onChangeTitle,
     403                    'DESC': self.onChangeTitle,
     404                    'DMOV': self.onChangeDMOV,
     405                    'STOP': None,
     406                    }
     407        for axis in ['x', 'y']:
     408            item = self.epics[axis]
     409            redirects['axis'] = axis
     410            if not item.Connect(**redirects):
     411                raise RuntimeError, "Did not connect %s axis" % axis
    420412
    421413    def ReleaseEpics(self):
  • moxy/trunk/src/moxy/pvsetup.py

    r641 r642  
    579579
    580580
    581 if __name__ == '__main__':
     581def main ():
    582582    '''example of how to set up the caller for this dialog'''
    583583    config = {
     
    608608        dlg.Destroy()
    609609    app.MainLoop()
     610
     611
     612if __name__ == '__main__':
     613    main()
  • moxy/trunk/src/moxy/root.py

    r635 r642  
    1111#*************************************************************************
    1212
    13 '''root: Define the GUI elements and interface (this is the main code)
    14 
    1513########### SVN repository information ###################
    1614# $Date$
     
    2119########### SVN repository information ###################
    2220
    23 @note: for an undo example, see: http://wiki.wxpython.org/AnotherTutorial
     21'''root: Define the GUI elements and interface (this is the main code)
     22
     23:note: for an undo example, see: http://wiki.wxpython.org/AnotherTutorial
    2424'''
    2525
     
    3939    '''created by Boa-constructor'''
    4040    return root(parent)
     41
    4142
    4243#################################
     
    235236        self._init_ctrls(parent)
    236237        self.title = self.GetTitle()
    237         self._dirty(False)    # settings need to be saved to a file if True
    238238        self.pwd = os.getcwd()
    239239        self.settingsFile = settingsFile
     
    243243            self.SetStatusText('opening: %s' % self.settingsFile)
    244244            self.OpenSettingsFile(self.settingsFile)
     245        self._dirty(False)    # settings need to be saved to a file if True
    245246        # disable these menu items until they are implemented
    246247        #self.menuAbout.FindItemById(wxID_ROOTMENUABOUTHELP).Enable(False)
     
    274275    def _dirty(self, state=True):
    275276        '''Declare the settings dirty (means that changes are unsaved)
    276             @param state: [Boolean] True means there are unsaved changes'''
     277       
     278        :param bool state: True means there are unsaved changes
     279        '''
    277280        self.dirty = state
    278281        title = self.title
     
    283286    def NewPair(self, newtab=True):
    284287        '''Create a page for a new X,Y pair
    285             @param newtab: [Boolean] option to create a first tab'''
     288       
     289        :param bool newtab: option to create a first tab
     290        '''
    286291        self.paircounter += 1   # unique for each new page
    287292        name = 'panel' + repr(self.paircounter)
Note: See TracChangeset for help on using the changeset viewer.