source: epics2xml/epics2xml.py @ 79

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

Refs #2: progress ...

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Rev Date Author Id Url
File size: 11.5 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:35:02 +0000 (Fri, 06 Nov 2009) $
17# $Author: jemian $
18# $Revision: 79 $
19# $URL$
20# $Id: epics2xml.py 79 2009-11-06 16:35:02Z 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
29#import copy
30#import 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 configuration file'''
49        return self.configFile
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.configFile = thefile
55
56    def Clear(self):
57        '''reset the internal data representation (db) to empty'''
58        self.db = {}
59
60    def ReadConfigFile(self):
61        '''read the configuration 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.configFile) # 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.configFile
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
85    def ReadXmlFile(self):
86        '''read the settings from a file into an internal dictionary (self.db)
87
88            @note: this method uses xml.dom.minidom (built into all Pythons)
89            @see: http://docs.python.org/library/xml.dom.minidom.html
90        '''
91        try:
92            doc = minidom.parse(self.configFile) # parse an XML file by name
93            assert doc.documentElement.tagName == self.rootElement
94        except IOError:
95            return 'Could not read the XML file: ' + self.configFile
96        except AssertionError:
97            return 'XML root element is not ' + self.rootElement
98        #... read all attributes from the root element
99        docElem = doc.documentElement
100        self.Clear()
101        version = self._get_attribute(docElem, "version", "not-specified")
102        try:
103            # only handle v1.0 resource configuration files
104            assert version == u'1.0'
105        except AssertionError:
106            doc.unlink()
107            return 'Cannot handle file version:', version
108        # file verified now
109        for pairNode in docElem.getElementsByTagName("XYpair"):
110            title = self._get_attribute(pairNode, "name", "")
111            selected = self._get_attribute(pairNode, "selected", "")
112            pairnum = self.NewPair(title)
113            if selected.lower() == "true":
114                self.SelectPair(pairnum)
115            self.NewEpicsConfig(pairnum)
116            for EpicsNode in pairNode.getElementsByTagName("EPICS_configuration"):
117                for axisNode in EpicsNode.getElementsByTagName("axis"):
118                    axis = self._get_attribute(axisNode, "name", "")
119                    #isMotorRec
120                    for flagNode in axisNode.getElementsByTagName("flag"):
121                        text = self._get_attribute(flagNode, "isMotorRec", "False")
122                        self.SetEpicsField(pairnum, axis, "isMotorRec", (text == "True"))
123                    for fieldNode in axisNode.getElementsByTagName("field"):
124                        name = self._get_attribute(fieldNode, "name", "")
125                        pv = self._get_attribute(fieldNode, "pv", "")
126                        if (len(name)>0) and (len(pv)>0):
127                            #print pairnum, axis, name, pv
128                            self.SetEpicsField(pairnum, axis, name, pv)
129            for tabNode in pairNode.getElementsByTagName("tab"):
130                title = self._get_attribute(tabNode, "name", "")
131                selected = self._get_attribute(tabNode, "selected", "")
132                tabnum = self.NewTab(pairnum, title)
133                if selected.lower() == "true":
134                    self.SelectTab(pairnum, tabnum)
135                # EPICS settings here
136                for rowNode in tabNode.getElementsByTagName("row"):
137                    title = self._get_attribute(rowNode, "name", "")
138                    selected = self._get_attribute(rowNode, "selected", "")
139                    x = self._get_attribute(rowNode, "x", "")
140                    y = self._get_attribute(rowNode, "y", "")
141                    rownum = self.NewRow(pairnum, tabnum, title)
142                    self.SetRowXY(pairnum, tabnum, rownum, x, y)
143        doc.unlink()  # ensures XML document is disposed cleanly
144        return None
145
146    def _get_attribute(self, node, key, default):
147        '''get a specific attribute or return the default
148            @param node: XML Node object
149            @param key: [string] name of attribute to find
150            @param default: [string] default value to return'''
151        value = default
152        if node.attributes.has_key(key):
153            value = node.attributes[key].value
154        return value
155
156    def SaveXmlFile(self):
157        '''save the internal dictionary (self.db) to an XML file
158           @note: What about using/saving a default stylesheet?
159           @see: http://www.boddie.org.uk/python/XML_intro.html
160        '''
161        out = open(self.configFile, 'w')
162        out.write(repr(self))
163        out.close()
164        #
165        # What about a default stylesheet?
166        #
167       
168        return 'Saved settings to ' + self.configFile
169
170    def _SetAttr(self, node, attribute, value):
171        '''add attributes that are not empty (but do not strip the whitespace)
172            @param node: XML Node object
173            @param attribute: [string] name of attribute
174            @param value: [string] value of attribute'''
175        if len(value) > 0:
176            node.setAttribute(attribute, value)
177
178    def _makeTextNode(self, doc, tag, value):
179        '''create a text node for the XML file
180            @param doc: [xml.dom.minidom documentElement object]
181            @param tag: [string] element name
182            @param value: [string] element text'''
183        node = doc.createElement(tag)
184        text = doc.createTextNode(value)
185        node.appendChild(text)
186        return node
187
188    def __repr__(self):
189        '''default representation of this structure is XML
190            @return: XML representation of internal database (db)
191            @note: What about a default stylesheet?
192        '''
193        t = datetime.datetime.now()
194        yyyymmdd = t.strftime("%Y-%m-%d")
195        hhmmss = t.strftime("%H:%M:%S")
196
197        # Create the minidom document
198        doc = minidom.Document()
199
200        # Create the root element
201        root = doc.createElement(self.rootElement)
202        self._SetAttr(root, "version", "1.0")
203        self._SetAttr(root, "date", yyyymmdd)
204        self._SetAttr(root, "time", hhmmss)
205        doc.appendChild(root)
206#        selectedpairnum = self.GetSelectedPair()
207#        for pairnum in range(self.CountPairs()):
208#            pairnode = doc.createElement("XYpair")
209#            self._SetAttr(pairnode, "name",
210#                   self.GetPairTitle(pairnum))
211#            if selectedpairnum == pairnum:
212#                self._SetAttr(pairnode, "selected", "True")
213#            if self.db[u"pairs"][pairnum].has_key(u"epics"):
214#                epicsnode = doc.createElement("EPICS_configuration")
215#                epicsdb = self.db[u"pairs"][pairnum][u"epics"]
216#                for axis in epicsdb:
217#                    axisnode = doc.createElement("axis")
218#                    self._SetAttr(axisnode, "name", axis)
219#                    field = "isMotorRec"
220#                    node = doc.createElement("flag")
221#                    self._SetAttr(node, field, str(epicsdb[axis][field]))
222#                    axisnode.appendChild(node)
223#                    for field in wxmtxy_axis.field_list:
224#                        if len(epicsdb[axis][field])>0:
225#                            node = doc.createElement("field")
226#                            self._SetAttr(node, "name", field)
227#                            self._SetAttr(node, "pv", str(epicsdb[axis][field]))
228#                            axisnode.appendChild(node)
229#                    epicsnode.appendChild(axisnode)
230#                pairnode.appendChild(epicsnode)
231#            selectedtabnum = self.GetSelectedTab(pairnum)
232#            for tabnum in range(self.CountTabs(pairnum)):
233#                tabnode = doc.createElement("tab")
234#                self._SetAttr(tabnode, "name", self.GetTabTitle(pairnum, tabnum))
235#                if selectedtabnum == tabnum:
236#                    self._SetAttr(tabnode, "selected", "True")
237#                selectedrownum = self.GetSelectedRow(pairnum, tabnum)
238#                for rownum in range(self.CountRows(pairnum, tabnum)):
239#                    rownode = doc.createElement("row")
240#                    label = self.GetRowTitle(pairnum, tabnum, rownum)
241#                    x, y = self.GetRowXY(pairnum, tabnum, rownum)
242#                    self._SetAttr(rownode, "name", label)
243#                    self._SetAttr(rownode, "x", x)
244#                    self._SetAttr(rownode, "y", y)
245#                    if selectedrownum == rownum:
246#                        self._SetAttr(rownode, "selected", "True")
247#                    tabnode.appendChild(rownode)
248#                pairnode.appendChild(tabnode)
249#            root.appendChild(pairnode)
250        return doc.toprettyxml(indent="  ")
251
252
253if __name__ == '__main__':
254    cf = Epics2Xml("config.xml")
255    cf.ReadConfigFile()
256#    rc = Settings("examples/test-settings.xml")
257#    rc.ReadXmlFile()
258#    rc.SetConfigFile('output-test.xml')
259#    rc.SaveXmlFile()
260#
261#    pj = Settings()
262#    pairnum = pj.NewPair("my test pair")
263#    tabnum = pj.NewTab(pairnum, title='my test tab')
264#    tabnum = pj.NewTab(pairnum, title='another')
265#    pj.SelectTab(pairnum, tabnum)
266#    tabnum = pj.NewTab(pairnum, title='another')
267#    tabnum = pj.NewTab(pairnum, title='another')
268#    pairnum = pj.NewPair("another")
269#    pj.SelectPair(pairnum)
270#    tabnum = pj.NewTab(pairnum, title='another')
271#    rownum = pj.NewRow(pairnum, tabnum, "beam center")
272#    pj.SelectRow(pairnum, tabnum, rownum)
273#    tabnum = pj.NewTab(pairnum, title='another')
274#    pairnum = pj.NewPair("another")
275#    print str(pj)
276    print "Hello"
Note: See TracBrowser for help on using the repository browser.