Source code for p4p.nt.enum


from __future__ import absolute_import

import sys
import time

from ..wrapper import Type, Value
from .common import alarm, timeStamp, NTBase
from .scalar import _metaHelper, ntwrappercommon

if sys.version_info >= (3, 0):
    unicode = str

class ntenum(ntwrappercommon, int):
    """

    * .severity
    * .status
    * .timestamp - Seconds since 1 Jan 1970 UTC as a float
    * .raw_stamp - A tuple (seconds, nanoseconds)
    * .raw - The underlying :py:class:`p4p.Value`.
    """

    def _store(self, value):
        ntwrappercommon._store(self, value)
        self.choice = None

        return self

    def __str__(self):
        return self.choice or int.__str__(self)

    def __repr__(self):
        return '%s(%d, %s)'%(self.__class__.__name__, int(self), self.choice)

    # TODO: compare with str

[docs] class NTEnum(NTBase): """Describes a string selected from among a list of possible choices. Stored internally as an integer """ Value = Value
[docs] @staticmethod def buildType(extra=[], display=False, control=False, valueAlarm=False): F = [ ('value', ('S', 'enum_t', [ ('index', 'i'), ('choices', 'as'), ])), ('alarm', alarm), ('timeStamp', timeStamp), ] # TODO: different metadata options _metaHelper(F, 'i', display=display, control=control, valueAlarm=valueAlarm) F.extend(extra) return Type(id="epics:nt/NTEnum:1.0", spec=F)
def __init__(self, **kws): self.type = self.buildType(**kws) # cached choices list. # picked up during unwrap self._choices = []
[docs] def wrap(self, value, choices=None, **kws): """Pack python value into Value Accepts dict to explicitly initialize fields by name. Any other type is assigned to the 'value' field via the self.assign() method. """ if isinstance(value, Value): pass elif isinstance(value, ntwrappercommon): kws.setdefault('timestamp', value.timestamp) value = value.raw elif isinstance(value, dict): # if index, choices not in value.keys(), then # use value dict to initalize fields by name if {'index', 'choices'}.isdisjoint(value): value = self.Value(self.type, value) # if value = {'index': ..., 'choices': ...}, then # assign these to value.index, value.choices else: value = self.Value(self.type, {'value': value}) else: # index or string V = self.type() if choices is not None: V['value.choices'] = choices self.assign(V, value) value = V self._choices = value['value.choices'] or self._choices return self._annotate(value, **kws)
[docs] def unwrap(self, value): """Unpack a Value into an augmented python type (selected from the 'value' field) """ if value.changed('value.choices'): self._choices = value['value.choices'] idx = value['value.index'] ret = ntenum(idx)._store(value) try: ret.choice = self._choices[idx] except IndexError: pass # leave it as None return ret
[docs] def assign(self, V, py): """Store python value in Value """ if isinstance(py, (bytes, unicode)): for i,C in enumerate(V['value.choices'] or self._choices): if py==C: V['value.index'] = i return # attempt to parse as integer py = int(py, 0) else: # attempt to cast as integer py = int(py) V['value.index'] = py