pygpibtoolkit/pygpib.py

changeset 53
8e32c806fcdd
parent 40
1bbea188a7e5
child 54
5c1a312830e7
--- a/pygpibtoolkit/pygpib.py	Sun Feb 17 22:59:59 2008 +0100
+++ b/pygpibtoolkit/pygpib.py	Mon Feb 25 18:38:27 2008 +0100
@@ -5,6 +5,7 @@
 import serial
 from serial.serialutil import SerialException
 import time
+from pygpibtoolkit.tools import AbstractRegister 
 
 class ConnectionError(Exception):
     pass
@@ -30,12 +31,131 @@
         if isinstance(k, basestring):
             k = self.rev_constants[k]
         return self.descriptions[k]
-    
 
 class MODE(Constants):    
     _constants = [(1, "CONTROLLER", "Set device as Controller in Charge"),
                   (0, "DEVICE", "Set device as simple listener"),
                   ]
+
+class ModeCommand(object):
+    def __init__(self, description, name, condition=None):
+        self.name = name
+        self.description = description
+        self.condition = condition
+
+class CommandRegister(object):
+    _instances = {}
+    _registered_type = None #Command
+    def __new__(cls):
+        # implements a singleton *per class*
+        if cls.__name__ not in cls._instances:
+            if cls._registered_type is None:
+                cls._registered_type = Command
+            instance = super(CommandRegister, cls).__new__(cls)
+            instance.registry = {}
+            cls._instances[cls.__name__] = instance
+        return cls._instances[cls.__name__]
+
+    @classmethod
+    def add(cls, registered_cls):
+        for registry in cls._instances.values():
+            if registry.__module__ == registered_cls.__module__:
+                break
+        else:
+            return
+        
+        assert issubclass(registered_cls, registry._registered_type)
+        if registered_cls is registry._registered_type:
+            return
+
+        name = registered_cls.__name__
+        if name not in registry:
+            registry.registry[name] = registered_cls
+            
+    def __contains__(self, key):
+        return key in self.registry
+    def keys(self):
+        return self.registry.keys()
+    def items(self):
+        return self.registry.items()
+    def values(self):
+        return self.registry.values()
+    def __getitem__(self, key):
+        return self.registry[key]
+
+class MetaCommand(type):
+    """
+    Metaclass for HPIB command. Used to register all commands.
+    """
+    _commands = {}
+    def __init__(cls, name, bases, dct):
+        # called at class creation
+        super(MetaCommand, cls).__init__(name, bases, dct)
+        if name not in [ "AbstractCommand","Command"]:
+            CommandRegister().add(cls)
+    
+class AbstractCommand(object):
+    """ Base class for HPIB command descritption"""
+    __metaclass__ = MetaCommand
+    
+
+class Command(AbstractCommand):
+    @classmethod
+    def get_value(self, cnx):
+        res = cnx.send_command(self.__class__.__name__)
+        return self.convert_from(res)
+
+    @classmethod
+    def set_value(self, cnx, value):
+        raise ValueError, "Can't set value for command '%s'"%self.__class__.__name__
+
+    @classmethod
+    def convert_from(self, value):
+        return value
+    
+class AbstractValue(Command):
+    @classmethod
+    def set_value(self, cnx, value):
+        res = cnx.send_command("%s %s"%(self.__class__.__name__,
+                                        self.convert_to(value)))
+        return res
+    @classmethod
+    def convert_to(self, value):
+        return str(value)
+    
+class BoolValue(AbstractValue):
+    _type = bool
+    @classmethod
+    def convert_from(self, value):
+        return value and value.lower() in ['1','true','yes','on']
+    @classmethod
+    def convert_to(self, value):
+        return value and "1" or "0"
+    
+class IntValue(AbstractValue):
+    _type = int
+
+class FloatValue(AbstractValue):
+    _type = float
+
+class PercentageValue(FloatValue):
+    pass #TODO
+
+class FrequencyValue(FloatValue):
+    pass
+
+class DurationValue(FloatValue):
+    pass
+
+class StringValue(AbstractValue):
+    _type = str
+
+class EnumValue(AbstractValue):
+    pass
+
+class Mode(AbstractValue):
+    pass
+
 # TODO
 # class STATUS_BYTE(Constants):
 #     # IEEE 488.2 Status Byte constants

mercurial