Changeset 81 for epics2xml/epics2xml.py


Ignore:
Timestamp:
Nov 6, 2009 12:22:34 PM (14 years ago)
Author:
jemian
Message:

Refs #2: config file is read now, output file is written now, need to connect with EPICS

File:
1 edited

Legend:

Unmodified
Added
Removed
  • epics2xml/epics2xml.py

    r79 r81  
    3737        '''prepare the settings file
    3838            @param configFile: [string] name of XML file with settings'''
    39         self.rootElement = 'epics2xml'
     39        self.rootElementConfig = 'epics2xml'
     40        self.rootElementPvdata = 'pvdata'
    4041        self.Clear()
    4142        self.SetConfigFile(configFile)
     
    5556
    5657    def Clear(self):
    57         '''reset the internal data representation (db) to empty'''
     58        '''reset the internal data representations (db, pv) to empty'''
    5859        self.db = {}
     60        self.pv = {}
    5961
    6062    def ReadConfigFile(self):
    61         '''read the configuration from a file into an internal dictionary (self.db)
     63        '''read the configuration from an XML file into an internal dictionary (self.db)
    6264
    6365            @note: this method uses xml.dom.minidom (built into all Pythons)
     
    6668        try:
    6769            doc = minidom.parse(self.configFile) # parse an XML file by name
    68             assert doc.documentElement.tagName == self.rootElement
     70            assert doc.documentElement.tagName == self.rootElementConfig
    6971        except IOError:
    7072            return 'Could not read the XML file: ' + self.configFile
    7173        except AssertionError:
    72             return 'XML root element is not ' + self.rootElement
     74            return 'XML root element is not ' + self.rootElementConfig
    7375        #... read all attributes from the root element
    7476        docElem = doc.documentElement
     
    8284            return 'Cannot handle file version:', version
    8385        # 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
     86        self.db['title'] = self._getFirstChildData(docElem, "title", "default title")
     87        tfNode = docElem.getElementsByTagName("targetFile")[0]
     88        tf_db = {}
     89        tf_db['name'] = self._get_attribute(tfNode, "name", "").strip()
     90        tf_db['refreshMinimum'] = self._getFirstChildData(tfNode, "refreshMinimum", "60")
     91        tf_db['stylesheet'] = self._getFirstChildData(tfNode, "stylesheet", "basic-table.xsl")
     92        # refreshMinimum
     93        self.db['targetFile'] = tf_db
     94        pvlist_db = []
     95        for elementNode in docElem.getElementsByTagName("pv"):
     96            pv_db = {}
     97            pv_db['name'] = self._get_attribute(elementNode, "name", "").strip()
     98            pv_db['rate'] = self._get_attribute(elementNode, "rate", "monitor").strip()
     99            pv_db['description'] = self._getFirstChildData(elementNode, "description", "")
     100            pvlist_db.append(pv_db)
     101        self.db['pvList'] = pvlist_db
     102
     103    def _getFirstChildData(self, parent, tag, default):
     104        '''get the full content of the node or return the default
     105            @param parent: XML Node object
     106            @param tag: [string] name of element to find
     107            @param default: [string] default value to return'''
     108        str = default
     109        # need some error checking here
     110        nodeList = parent.getElementsByTagName(tag)
     111        node = nodeList[0]
     112        child = node.firstChild
     113        data = child.data
     114        str = data.strip()
     115        return str
    145116
    146117    def _get_attribute(self, node, key, default):
     
    155126
    156127    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')
     128        '''save the internal data (self.__repr__()) to the target XML file'''
     129        out = open(self.db['targetFile']['name'], 'w')
    162130        out.write(repr(self))
    163131        out.close()
    164         #
    165         # What about a default stylesheet?
    166         #
    167        
    168132        return 'Saved settings to ' + self.configFile
    169133
     
    186150        return node
    187151
     152    def _getDateTime(self):
     153        '''return current date and time as a tuple
     154            @return: yyyy-mm-dd hh:mm:ss
     155        '''
     156        t = datetime.datetime.now()
     157        yyyymmdd = t.strftime("%Y-%m-%d")
     158        hhmmss = t.strftime("%H:%M:%S")
     159        return yyyymmdd, hhmmss
     160
     161    def getPvKey(self, name, key, default):
     162        '''get the internal database representation of the PV key
     163            or the default
     164            @param name: EPICS PV name
     165            @param key: value | date | time
     166            @param default: use if key not defined'''
     167        if self.pv.has_key(name):
     168            pv = self.pv[name]
     169            if pv.has_key(key):
     170                content = pv[key]
     171            else:
     172                content = default
     173        else:
     174            content = default
     175        return content
     176
     177    def setPvKey(self, name, key, value):
     178        '''set the internal database representation of the PV key
     179            @param name: EPICS PV name
     180            @param key: value | date | time
     181            @param value: new content from this EPICS PV
     182        '''
     183        if not self.pv.has_key(name):
     184            self.pv[name] = {}
     185        pv = self.pv[name]
     186        pv[key] = value
     187
     188    def setPv(self, name, value):
     189        '''save this PV now
     190            @param name: EPICS PV name
     191            @param value: new content from this EPICS PV
     192        '''
     193        yyyymmdd, hhmmss = self._getDateTime()
     194        self.setPvKey(name, 'value', value)
     195        self.setPvKey(name, 'date', yyyymmdd)
     196        self.setPvKey(name, 'time', hhmmss)
     197
    188198    def __repr__(self):
    189199        '''default representation of this structure is XML
     
    191201            @note: What about a default stylesheet?
    192202        '''
    193         t = datetime.datetime.now()
    194         yyyymmdd = t.strftime("%Y-%m-%d")
    195         hhmmss = t.strftime("%H:%M:%S")
    196 
    197203        # Create the minidom document
    198204        doc = minidom.Document()
    199205
     206        # Use a stylesheet
     207        target = "xml-stylesheet"
     208        instructions = ' type="text/xsl" href="%s"' % (self.db['targetFile']['stylesheet'])
     209        #
     210        xsltNode = doc.createProcessingInstruction(target, instructions)
     211        doc.appendChild(xsltNode)
     212
    200213        # Create the root element
    201         root = doc.createElement(self.rootElement)
     214        root = doc.createElement(self.rootElementPvdata)
    202215        self._SetAttr(root, "version", "1.0")
     216        yyyymmdd, hhmmss = self._getDateTime()
    203217        self._SetAttr(root, "date", yyyymmdd)
    204218        self._SetAttr(root, "time", hhmmss)
    205219        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)
     220        titleNode = self._makeTextNode(doc, "title", self.db['title'])
     221        root.appendChild(titleNode)
     222        for pv in self.db['pvList']:
     223            pvNode = doc.createElement('pv')
     224            name = pv['name']
     225            pv_value = self.getPvKey(name, "value", "")
     226            pv_date = self.getPvKey(name, "date", "")
     227            pv_time = self.getPvKey(name, "time", "")
     228            self._SetAttr(pvNode, "name", pv['name'])
     229            self._SetAttr(pvNode, "rate", pv['rate'])
     230            self._SetAttr(pvNode, "date", pv_date)
     231            self._SetAttr(pvNode, "time", pv_time)
     232            pvNode.appendChild(self._makeTextNode(doc, "description", pv['description']))
     233            pvNode.appendChild(self._makeTextNode(doc, "value", pv_value))
     234            root.appendChild(pvNode)
    250235        return doc.toprettyxml(indent="  ")
    251236
     
    254239    cf = Epics2Xml("config.xml")
    255240    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"
     241    # load some artificial data to test
     242    cf.setPv("S:SRcurrent:AI", '99.9853')
     243    cf.setPv("APS:BarometricPressure:MBR", '992.083')
     244    print cf.__repr__()
Note: See TracChangeset for help on using the changeset viewer.