source: epics2xml/epics2xml.py @ 78

Last change on this file since 78 was 78, checked in by jemian, 14 years ago

Refs #2: cleanup

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Rev Date Author Id Url
File size: 10.4 KB
Line 
1#!/usr/bin/env python
2
3#*************************************************************************
4# Copyright (c) 2009 The University of Chicago, as Operator of Argonne
5#     National Laboratory.
6# Copyright (c) 2009 The Regents of the University of California, as
7#     Operator of Los Alamos National Laboratory.
8# This file is distributed subject to a Software License Agreement found
9# in the file LICENSE that is included with this distribution.
10#*************************************************************************
11
12'''@note: watch EPICS process variables and write them to an XML file
13
14@version:
15########### SVN repository information ###################
16# $Date: 2009-11-06 16:10:08 +0000 (Fri, 06 Nov 2009) $
17# $Author: jemian $
18# $Revision: 78 $
19# $URL$
20# $Id: epics2xml.py 78 2009-11-06 16:10:08Z jemian $
21########### SVN repository information ###################
22
23@note: for help with xml.dom, see http://docs.python.org/library/xml.dom.html
24'''
25
26
27from xml.dom import minidom
28import datetime
29import copy
30import pvConnect
31
32
33class Epics2Xml:
34    '''watch PVs and write to XMl'''
35
36    def __init__(self, configFile=None):
37        '''prepare the settings file
38            @param configFile: [string] name of XML file with settings'''
39        self.rootElement = 'epics2xml'
40        self.Clear()
41        self.SetConfigFile(configFile)
42
43    def GetDb(self):
44        '''@return: database'''
45        return self.db
46
47    def GetConfigFile(self):
48        '''@return: name of XML settings file'''
49        return self.settingsFile
50
51    def SetConfigFile(self, thefile):
52        '''set the name of XML configuration file
53            @param thefile: [string] name of XML file with the configuration'''
54        self.settingsFile = thefile
55
56    def Clear(self):
57        '''reset the internal data representation (db) to empty'''
58        self.db = {}
59
60    def ReadXmlFile(self):
61        '''read the settings from a file into an internal dictionary (self.db)
62
63            @note: this method uses xml.dom.minidom (built into all Pythons)
64            @see: http://docs.python.org/library/xml.dom.minidom.html
65        '''
66        try:
67            doc = minidom.parse(self.settingsFile) # parse an XML file by name
68            assert doc.documentElement.tagName == self.rootElement
69        except IOError:
70            return 'Could not read the XML file: ' + self.settingsFile
71        except AssertionError:
72            return 'XML root element is not ' + self.rootElement
73        #... read all attributes from the root element
74        docElem = doc.documentElement
75        self.Clear()
76        version = self._get_attribute(docElem, "version", "not-specified")
77        try:
78            # only handle v1.0 resource configuration files
79            assert version == u'1.0'
80        except AssertionError:
81            doc.unlink()
82            return 'Cannot handle file version:', version
83        # file verified now
84        for pairNode in docElem.getElementsByTagName("XYpair"):
85            title = self._get_attribute(pairNode, "name", "")
86            selected = self._get_attribute(pairNode, "selected", "")
87            pairnum = self.NewPair(title)
88            if selected.lower() == "true":
89                self.SelectPair(pairnum)
90            self.NewEpicsConfig(pairnum)
91            for EpicsNode in pairNode.getElementsByTagName("EPICS_configuration"):
92                for axisNode in EpicsNode.getElementsByTagName("axis"):
93                    axis = self._get_attribute(axisNode, "name", "")
94                    #isMotorRec
95                    for flagNode in axisNode.getElementsByTagName("flag"):
96                        text = self._get_attribute(flagNode, "isMotorRec", "False")
97                        self.SetEpicsField(pairnum, axis, "isMotorRec", (text == "True"))
98                    for fieldNode in axisNode.getElementsByTagName("field"):
99                        name = self._get_attribute(fieldNode, "name", "")
100                        pv = self._get_attribute(fieldNode, "pv", "")
101                        if (len(name)>0) and (len(pv)>0):
102                            #print pairnum, axis, name, pv
103                            self.SetEpicsField(pairnum, axis, name, pv)
104            for tabNode in pairNode.getElementsByTagName("tab"):
105                title = self._get_attribute(tabNode, "name", "")
106                selected = self._get_attribute(tabNode, "selected", "")
107                tabnum = self.NewTab(pairnum, title)
108                if selected.lower() == "true":
109                    self.SelectTab(pairnum, tabnum)
110                # EPICS settings here
111                for rowNode in tabNode.getElementsByTagName("row"):
112                    title = self._get_attribute(rowNode, "name", "")
113                    selected = self._get_attribute(rowNode, "selected", "")
114                    x = self._get_attribute(rowNode, "x", "")
115                    y = self._get_attribute(rowNode, "y", "")
116                    rownum = self.NewRow(pairnum, tabnum, title)
117                    self.SetRowXY(pairnum, tabnum, rownum, x, y)
118        doc.unlink()  # ensures XML document is disposed cleanly
119        return None
120
121    def _get_attribute(self, node, key, default):
122        '''get a specific attribute or return the default
123            @param node: XML Node object
124            @param key: [string] name of attribute to find
125            @param default: [string] default value to return'''
126        value = default
127        if node.attributes.has_key(key):
128            value = node.attributes[key].value
129        return value
130
131    def SaveXmlFile(self):
132        '''save the internal dictionary (self.db) to an XML file
133           @note: What about using/saving a default stylesheet?
134           @see: http://www.boddie.org.uk/python/XML_intro.html
135        '''
136        out = open(self.settingsFile, 'w')
137        out.write(repr(self))
138        out.close()
139        #
140        # What about a default stylesheet?
141        #
142       
143        return 'Saved settings to ' + self.settingsFile
144
145    def _SetAttr(self, node, attribute, value):
146        '''add attributes that are not empty (but do not strip the whitespace)
147            @param node: XML Node object
148            @param attribute: [string] name of attribute
149            @param value: [string] value of attribute'''
150        if len(value) > 0:
151            node.setAttribute(attribute, value)
152
153    def _makeTextNode(self, doc, tag, value):
154        '''create a text node for the XML file
155            @param doc: [xml.dom.minidom documentElement object]
156            @param tag: [string] element name
157            @param value: [string] element text'''
158        node = doc.createElement(tag)
159        text = doc.createTextNode(value)
160        node.appendChild(text)
161        return node
162
163    def __repr__(self):
164        '''default representation of this structure is XML
165            @return: XML representation of internal database (db)
166            @note: What about a default stylesheet?
167        '''
168        t = datetime.datetime.now()
169        yyyymmdd = t.strftime("%Y-%m-%d")
170        hhmmss = t.strftime("%H:%M:%S")
171
172        # Create the minidom document
173        doc = minidom.Document()
174
175        # Create the root element
176        root = doc.createElement(self.rootElement)
177        self._SetAttr(root, "version", "1.0")
178        self._SetAttr(root, "date", yyyymmdd)
179        self._SetAttr(root, "time", hhmmss)
180        doc.appendChild(root)
181#        selectedpairnum = self.GetSelectedPair()
182#        for pairnum in range(self.CountPairs()):
183#            pairnode = doc.createElement("XYpair")
184#            self._SetAttr(pairnode, "name",
185#                   self.GetPairTitle(pairnum))
186#            if selectedpairnum == pairnum:
187#                self._SetAttr(pairnode, "selected", "True")
188#            if self.db[u"pairs"][pairnum].has_key(u"epics"):
189#                epicsnode = doc.createElement("EPICS_configuration")
190#                epicsdb = self.db[u"pairs"][pairnum][u"epics"]
191#                for axis in epicsdb:
192#                    axisnode = doc.createElement("axis")
193#                    self._SetAttr(axisnode, "name", axis)
194#                    field = "isMotorRec"
195#                    node = doc.createElement("flag")
196#                    self._SetAttr(node, field, str(epicsdb[axis][field]))
197#                    axisnode.appendChild(node)
198#                    for field in wxmtxy_axis.field_list:
199#                        if len(epicsdb[axis][field])>0:
200#                            node = doc.createElement("field")
201#                            self._SetAttr(node, "name", field)
202#                            self._SetAttr(node, "pv", str(epicsdb[axis][field]))
203#                            axisnode.appendChild(node)
204#                    epicsnode.appendChild(axisnode)
205#                pairnode.appendChild(epicsnode)
206#            selectedtabnum = self.GetSelectedTab(pairnum)
207#            for tabnum in range(self.CountTabs(pairnum)):
208#                tabnode = doc.createElement("tab")
209#                self._SetAttr(tabnode, "name", self.GetTabTitle(pairnum, tabnum))
210#                if selectedtabnum == tabnum:
211#                    self._SetAttr(tabnode, "selected", "True")
212#                selectedrownum = self.GetSelectedRow(pairnum, tabnum)
213#                for rownum in range(self.CountRows(pairnum, tabnum)):
214#                    rownode = doc.createElement("row")
215#                    label = self.GetRowTitle(pairnum, tabnum, rownum)
216#                    x, y = self.GetRowXY(pairnum, tabnum, rownum)
217#                    self._SetAttr(rownode, "name", label)
218#                    self._SetAttr(rownode, "x", x)
219#                    self._SetAttr(rownode, "y", y)
220#                    if selectedrownum == rownum:
221#                        self._SetAttr(rownode, "selected", "True")
222#                    tabnode.appendChild(rownode)
223#                pairnode.appendChild(tabnode)
224#            root.appendChild(pairnode)
225        return doc.toprettyxml(indent="  ")
226
227
228if __name__ == '__main__':
229#    rc = Settings("examples/test-settings.xml")
230#    rc.ReadXmlFile()
231#    rc.SetConfigFile('output-test.xml')
232#    rc.SaveXmlFile()
233#
234#    pj = Settings()
235#    pairnum = pj.NewPair("my test pair")
236#    tabnum = pj.NewTab(pairnum, title='my test tab')
237#    tabnum = pj.NewTab(pairnum, title='another')
238#    pj.SelectTab(pairnum, tabnum)
239#    tabnum = pj.NewTab(pairnum, title='another')
240#    tabnum = pj.NewTab(pairnum, title='another')
241#    pairnum = pj.NewPair("another")
242#    pj.SelectPair(pairnum)
243#    tabnum = pj.NewTab(pairnum, title='another')
244#    rownum = pj.NewRow(pairnum, tabnum, "beam center")
245#    pj.SelectRow(pairnum, tabnum, rownum)
246#    tabnum = pj.NewTab(pairnum, title='another')
247#    pairnum = pj.NewPair("another")
248#    print str(pj)
249    print "Hello"
Note: See TracBrowser for help on using the repository browser.