#!/usr/bin/python
#
# arch-tag: NPC MV converter module
# Time-stamp: <2006-03-22 10:17:38 mike>
#
from NPCData import adc_offset, dio_offset
from io import IOP, ADC
from elementtree import ElementTree
import xmlenc as xml

__version__ = '2.0'

# Calibration coefficients to convert the A/D input voltage into
# physical units of the sensor, volts or amps. These are default
# values and may be updated at runtime in MV.__init__
COEFF = {'voltage' : [5000, 2000.],
         'current' : [0, 0.25],
         'current_diff' : [0, 0.25],
         'v400a' : [0, 100.],
         'i400a' : [0, 6.25]}

UNITS = {'voltage' : 'mV',
         'current' : 'mA',
         'current_diff' : 'mA',
         'v400a' : 'mV',
         'i400a' : 'mA'}

         
class MV(object):
    analog_in = ('voltage', 'current', 'current_diff')
    digital_in = ('aworking', 'bworking', 'aok', 'bok')
    
    def __init__(self, desc, cal=None):
        self.__dict__.update(desc)

        # Analog inputs
        for name in self.analog_in:
            desc = self.__dict__[name]
            self.__dict__[name] = ADC(**desc)
            if cal and cal.has_key('mv/' + name):
                c,units = cal['mv/' + name]
                COEFF[name] = c

        # Digital inputs
        for name in self.digital_in:
            desc = self.__dict__[name]
            self.__dict__[name] = IOP(**desc)

    def status(self, record):
        """Return a dictionary containing the current state of all
        digital and analog inputs"""
        d = {}
        # Note all analog inputs are multiplied by 1000 after scaling
        # since all units are either mV or mA.
        for name in self.analog_in:
            try:
                v = self.__dict__[name].read(record)
                c = COEFF[name]
                d[name] = int((c[0] + v*c[1])*1000.)
            except KeyError:
                pass
        for name in self.digital_in:
            d[name] = self.__dict__[name].read(record)
        return d

    def as_xml(self):
        """Return the XML description of the MV as an ElementTree object"""
        root = ElementTree.Element('mvconverter')
        root.set('version', __version__)
        for name in self.analog_in:
            root.append(xml.sensor(name, self.__dict__[name],
                                   name='mv/'+name,
                                   units=UNITS[name],
                                   cal=[c*1000 for c in COEFF[name]]))
        cal = [c*1000 for c in COEFF[name]]    
        for name in self.digital_in:
            root.append(xml.switch(self.__dict__[name], 'mv/' + name))
        return root
