source: moxy/trunk/src/moxy/wxlib/pv.py @ 839

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

refactor

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