#!/usr/bin/python
#
# arch-tag: df272d03-5e47-41ac-8059-77ae5aec2d0b
#
# Ground Fault detection module.
#
from io import IOP, ADC
from elementtree import ElementTree
import xmlenc as xml

__version__ = '1.1'

class gfDetector(object):
    """Ground fault detection works by activating the switch corresponding
    to the bus line one wishes to test:

      gf.select(name)      where name is one of v400,v400r,v48,v48r,test

    And then checking the status from the next data record:

      s = gf.status(datarec)

    The status is a two element dictionary, s['current'] is the GF current
    in microamps and s['line'] is the name of the selected line.
    """
    def __init__(self, desc, dsrc):
        sw_names = 'v400 v400r v48 v48r test'.split()
        self.__dict__.update(desc)
        self.current = ADC(dsrc=dsrc, **self.current)
        for name in sw_names:
            params = self.__dict__[name]
            self.__dict__[name] = IOP(dsrc=dsrc, **params)
        self.active = []
        # Deactivate all switches
        for name in sw_names:
            self.__dict__[name].set()
            
    def _to_uA(self, v):
        """Convert A/D voltage to a current value in uA"""
        return int((2.5 - v)*1.0e6/2500.)

    def select(self, which):
        """Select a bus line for ground fault measurement"""
        try:
            sw = self.__dict__[which]
        except KeyError:
            return 0
        sw.clear()
        self.active.append(which)
        return 1
    
    def unselect(self):
        for name in self.active:
            self.__dict__[name].set()
        self.active = []

    def status(self, record):
        s = {}
        s['current'] = self._to_uA(self.current.read(record))
        s['line'] = self.active
        return s

    def as_xml(self):
        """Return the XML description as an ElementTree object"""
        root = ElementTree.Element('gf')
        root.set('version', __version__)
        root.append(xml.sensor('current', self.current, units='uA',
                               cal=[-1000, 400],
                               name='gf/current'))
        sw_names = 'v400 v400r v48 v48r test'.split()
        for name in sw_names:
            root.append(xml.switch(self.__dict__[name], name))
        return root
