source: moxy/trunk/src/moxy/vc_pv.py @ 758

Last change on this file since 758 was 758, checked in by jemian, 11 years ago

resolved the pv.disconnect() matter, revise computation of axis connected, indicate future plans

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Rev Url
File size: 8.4 KB
Line 
1#!/usr/bin/env python
2
3########### SVN repository information ###################
4# $Date: 2012-01-05 21:52:02 +0000 (Thu, 05 Jan 2012) $
5# $Author: jemian $
6# $Revision: 758 $
7# $URL$
8# $Id: vc_pv.py 758 2012-01-05 21:52:02Z jemian $
9########### SVN repository information ###################
10
11'''
12demo view for EPICS PV connection class: m_pv.PvConnection()
13
14Copyright (c) 2009 - 2011, UChicago Argonne, LLC.
15See LICENSE file for details.
16'''
17
18
19# - - - - - - - - - - - - - - - - - - Imports
20
21
22import wx
23import wx.lib.buttons
24import wx.lib.stattext
25from m_pv import PvConnection
26
27
28# - - - - - - - - - - - - - - - - - - Global
29
30
31__svnid__ = "$Id: vc_pv.py 758 2012-01-05 21:52:02Z jemian $"
32COLOR_MOVING = wx.Colour(179, 250, 142)         # pale green
33COLOR_NOT_MOVING = wx.Colour(200, 191, 140)     # not exactly background color
34COLOR_PALE_PURPLE = wx.Colour(200, 200, 255)    # my name for this
35COLOR_LIGHTGREEN = wx.Colour(200, 255, 200)     # my name for this
36COLOR_LIGHTRED = wx.Colour(255, 200, 200)       # my name for this
37COLOR_BACKGROUND = wx.Colour(237, 233, 227)        # boa-constructor uses this
38
39
40# - - - - - - - - - - - - - - - - - - class
41
42
43class DemoView(wx.Frame):
44    '''
45    Show an EPICS PV connection.
46    Allow it to connect and disconnect.
47    (This is like CA Probe.)
48    '''
49   
50    _cb_counter = 0
51   
52    def __init__(self, pvname = ''):
53        self.pvname = pvname
54        self.value = ''
55        self.state = 'not connected'
56        self.remarks = ''
57        self.pv = None
58       
59        wx.Frame.__init__(self, id=wx.ID_ANY, name=u'Frame1', 
60            parent=None, title=u'PV Connection',)
61        #self.SetClientSize(wx.Size(750, 440))
62        self.SetToolTipString(u'PV Connection')
63       
64        self._init_widgets()
65        self.Bind(wx.EVT_CLOSE, self.OnClose)
66
67    def _init_widgets(self):
68        self.panel = wx.Panel(id=wx.ID_ANY, name='panel1', parent=self)
69        sizer = wx.BoxSizer(orient=wx.VERTICAL)
70        self.panel.SetSizer(sizer)
71       
72        upper = self._Make_Description_Sizer(self.panel)
73        lower = self._Make_Positions_Sizer(self.panel)
74        buttons = self._init_buttons1(self.panel)
75       
76        sizer.AddSizer(upper, 1, flag=wx.EXPAND)
77        sizer.AddSizer(lower, 1, flag=wx.EXPAND)
78        sizer.AddSizer(buttons, 0, flag=wx.EXPAND)
79
80    def _Make_Description_Sizer(self, parent):
81        '''
82        edit the PV name string if not connected
83        '''
84        self.w_pvname = wx.TextCtrl(parent=parent, id=wx.ID_ANY)
85        self.w_pvname.SetEditable(True)
86        self.w_value = wx.TextCtrl(parent=parent, id=wx.ID_ANY)
87        self.w_value.SetEditable(False)
88        self.w_value.SetBackgroundColour( COLOR_BACKGROUND )
89       
90        self.SetPV(self.pvname)
91        self.SetValue(self.value)
92
93        sbox = wx.StaticBox(parent, id=wx.ID_ANY,
94              label='PV name and value', style=0)
95        sbs = wx.StaticBoxSizer(sbox, wx.VERTICAL)
96        fgs = wx.FlexGridSizer(rows=2, cols=2, hgap=4, vgap=4)
97        fgs.AddGrowableCol(1)
98        sbs.Add(fgs, 0, wx.EXPAND|wx.ALIGN_CENTRE|wx.ALL, 5)
99
100        fgs.Add(wx.lib.stattext.GenStaticText(parent, wx.ID_ANY, 'PV name'), 0, flag=wx.EXPAND)
101        fgs.Add(self.w_pvname, 0, flag=wx.EXPAND)
102        fgs.Add(wx.lib.stattext.GenStaticText(parent, wx.ID_ANY, 'value'), 0, flag=wx.EXPAND)
103        fgs.Add(self.w_value, 0, flag=wx.EXPAND)
104
105        return sbs
106
107    def _Make_Positions_Sizer(self, parent):
108        '''
109        show connection state and something else useful
110        '''
111        self.w_state = wx.TextCtrl(parent=parent, id=wx.ID_ANY)
112        self.w_state.SetEditable(False)
113        self.w_remarks = wx.TextCtrl(parent=parent, id=wx.ID_ANY)
114        self.w_remarks.SetEditable(False)
115       
116        self.SetState(self.state)
117        self.SetRemarks(self.remarks)
118       
119        sbox = wx.StaticBox(parent, id=wx.ID_ANY,
120              label='connection status', style=0)
121        sbs = wx.StaticBoxSizer(sbox, wx.VERTICAL)
122        fgs = wx.FlexGridSizer(rows=2, cols=1, hgap=4, vgap=4)
123        fgs.AddGrowableCol(0)
124        sbs.Add(fgs, 0, wx.EXPAND|wx.ALIGN_CENTRE|wx.ALL, 5)
125       
126        fgs.Add(self.w_state, 0, flag=wx.EXPAND)
127        fgs.Add(self.w_remarks, 0, flag=wx.EXPAND)
128
129        return sbs
130   
131    def _init_buttons1(self, parent):
132        '''
133        build the buttons row and place it in a sizer, return the sizer
134        '''
135        self.connectButton = self._Make_My_Button(parent, 
136              label=u'Connect', name='connectButton', 
137              tip=u'Connect with EPICS PV', 
138              binding=self.doConnectButton)
139        self.disconnectButton = self._Make_My_Button(parent, 
140              label=u'Disconnect', name='disconnectButton', 
141              tip=u'Disconnect from EPICS PV', 
142              binding=self.doDisconnectButton)
143
144        sizer = wx.BoxSizer(orient=wx.HORIZONTAL)
145        sizer.AddWindow(self.connectButton, proportion=1, flag=wx.EXPAND)
146        sizer.AddWindow(self.disconnectButton, proportion=1, flag=wx.EXPAND)
147        return sizer
148       
149    def _Make_My_Button(self, parent, label, name, tip, binding):
150        '''
151        Create a button and bind it to a method.
152        Return the button object
153        '''
154        button = wx.lib.buttons.GenButton(id=wx.ID_ANY,
155              label=label, name=name, parent=parent,)
156        button.SetToolTipString(tip)
157        button.Bind(wx.EVT_BUTTON, binding)
158        return button
159
160    def connect(self):
161        self.w_pvname.SetEditable(False)
162        pvname = self.w_pvname.GetValue()
163        if len(pvname.strip()) > 0:
164            self.pvname = pvname
165            self.pv = PvConnection(pvname)
166            self.pv.connect(self.callback, vc_pv = True)
167
168    def disconnect(self):
169        self.w_pvname.SetEditable(True)
170        self.pv.disconnect()
171        self.pv = None      # throw away the PV connection
172        self.SetState( 'not connected' )
173        self.SetRemarks( '' )
174        wx.CallAfter(self.w_value.SetBackgroundColour, COLOR_BACKGROUND)
175
176    def doConnectButton(self, event):
177        self.connect()
178
179    def doDisconnectButton(self, event):
180        self.disconnect()
181
182    def SetPV(self, value):
183        self.pvname = str(value)
184        wx.CallAfter(self.w_pvname.SetValue, self.pvname)
185
186    def SetRemarks(self, value):
187        self.remarks = str(value)
188        wx.CallAfter(self.w_remarks.SetValue, self.remarks)
189
190    def SetState(self, value):
191        self.state = str(value)
192        wx.CallAfter(self.w_state.SetValue, self.state)
193
194    def SetValue(self, value):
195        self.value = str(value)
196        wx.CallAfter(self.w_value.SetValue, self.value)
197   
198    def ColorSelector(self, index):
199        # this makes a gaudy display
200        clut = [ COLOR_NOT_MOVING, COLOR_MOVING, 
201                 COLOR_PALE_PURPLE, COLOR_LIGHTGREEN, COLOR_LIGHTRED,
202                 wx.RED,
203                 'orange',
204                 'yellow',
205                 'green',
206                 'blue',
207                 'indigo',
208                 'violet',
209                 'white',
210                 'salmon',
211                 'bisque',
212                 'goldenrod',
213                 'mintcream',
214                 'skyblue',
215        ]
216        return clut[index % len(clut)]
217   
218    def callback(self, **kw):
219        "generic monitor callback"
220        #print kw
221        if 'conn' in kw.keys():
222            self.SetState({False: 'not connected', True: 'connected'}[kw['conn']])
223            if kw['conn']:
224                value = self.pv.channel.get()
225                self.SetValue( value )
226            else:
227                wx.CallAfter(self.w_value.SetBackgroundColour, COLOR_BACKGROUND)
228                self.SetRemarks( 'disconnect received, IOC is unavailable?' )
229        else:
230            self.SetRemarks(kw['cb_info'])
231            self.SetValue(kw['value'])
232            self._cb_counter += 1   # change the color every update event
233            color = self.ColorSelector(self._cb_counter)
234            wx.CallAfter(self.w_value.SetBackgroundColour, color)
235
236    def OnClose(self, event):
237        dlg = wx.MessageDialog(self, 
238            "Do you really want to close this application?",
239            "Confirm Exit", wx.OK|wx.CANCEL|wx.ICON_QUESTION)
240        result = dlg.ShowModal()
241        dlg.Destroy()
242        if result == wx.ID_OK:
243            if self.pv is not None:
244                self.pv.disconnect()
245            self.Destroy()
246
247
248# - - - - - - - - - - - - - - - - - - methods
249
250
251# - - - - - - - - - - - - - - - - - - main
252
253
254if __name__ == '__main__':
255    app = wx.App()
256    fr = DemoView('Godzilla')
257    fr.SetValue( 'loves Tokyo' )
258    fr.SetState( 'just started' )
259    fr.SetPV('pj:test')
260    fr.SetPV('prj:m1.RBV')
261    fr.Show()
262    app.MainLoop()
Note: See TracBrowser for help on using the repository browser.