示例#1
0
def make_meta(subtyp, description, tags, writeable=True, labels=None):
    if subtyp == "enum":
        if writeable:
            widget_type = "combo"
        else:
            widget_type = "textupdate"
        tags.append(widget(widget_type))
        meta = ChoiceMeta(description, labels, tags)
    elif subtyp == "bit":
        if writeable:
            widget_type = "checkbox"
        else:
            widget_type = "led"
        tags.append(widget(widget_type))
        meta = BooleanMeta(description, tags)
    else:
        if writeable:
            widget_type = "textinput"
        else:
            widget_type = "textupdate"
        tags.append(widget(widget_type))
        if subtyp == "uint":
            meta = NumberMeta("uint32", description, tags)
        elif subtyp == "int":
            meta = NumberMeta("int32", description, tags)
        elif subtyp == "scalar":
            meta = NumberMeta("float64", description, tags)
        elif subtyp == "lut":
            meta = StringMeta(description, tags)
        elif subtyp in ("pos", "relative_pos"):
            meta = NumberMeta("float64", description, tags)
        else:
            raise ValueError("Unknown subtype %r" % subtyp)
    return meta
示例#2
0
 def create_attribute_models(self):
     for data in super(ManagerController, self).create_attribute_models():
         yield data
     assert os.path.isdir(self.params.configDir), \
         "%s is not a directory" % self.params.configDir
     if not os.path.isdir(os.path.join(self.params.configDir, ".git")):
         # Try and make it a git repo, don't care if it fails
         self._run_git_cmd("init")
         self._run_git_cmd("commit", "--allow-empty", "-m", "Created repo")
     # Create writeable attribute table for the layout info we need
     elements = OrderedDict()
     elements["name"] = StringArrayMeta("Name of layout part")
     elements["mri"] = StringArrayMeta("Malcolm full name of child block")
     elements["x"] = NumberArrayMeta(
         "float64", "X Coordinate of child block")
     elements["y"] = NumberArrayMeta(
         "float64", "Y Coordinate of child block")
     elements["visible"] = BooleanArrayMeta("Whether child block is visible")
     layout_table_meta = TableMeta(
         "Layout of child blocks", elements=elements,
         tags=[widget("flowgraph")])
     layout_table_meta.set_writeable_in(ss.READY)
     self.layout = layout_table_meta.create_attribute_model()
     yield "layout", self.layout, self.set_layout
     # Create writeable attribute for loading an existing layout
     design_meta = ChoiceMeta(
         "Design name to load", tags=[config(), widget("combo")])
     design_meta.set_writeable_in(ss.READY)
     self.design = design_meta.create_attribute_model()
     yield "design", self.design, self.set_design
     # Create writeable attribute table for the exported fields
     elements = OrderedDict()
     elements["name"] = ChoiceArrayMeta("Name of exported block.field")
     elements["exportName"] = StringArrayMeta(
         "Name of the field within current block")
     exports_table_meta = TableMeta(
         "Exported fields of child blocks", tags=[widget("table")],
         elements=elements)
     exports_table_meta.set_writeable_in(ss.READY)
     self.exports = exports_table_meta.create_attribute_model()
     yield "exports", self.exports, self.set_exports
     # Create read-only indicator for when things are modified
     modified_meta = BooleanMeta(
         "Whether the design is modified", tags=[widget("led")])
     self.modified = modified_meta.create_attribute_model()
     yield "modified", self.modified, None
示例#3
0
class TestValidate(unittest.TestCase):
    def setUp(self):
        self.boolean_meta = BooleanMeta("test description")

    def test_given_value_str_then_cast_and_return(self):
        response = self.boolean_meta.validate("TestValue")
        assert response

        response = self.boolean_meta.validate("")
        assert not response

    def test_given_value_int_then_cast_and_return(self):
        response = self.boolean_meta.validate(15)
        assert response

        response = self.boolean_meta.validate(0)
        assert not response

    def test_given_value_boolean_then_cast_and_return(self):
        response = self.boolean_meta.validate(True)
        assert response

        response = self.boolean_meta.validate(False)
        assert not response

    def test_given_value_None_then_return(self):
        response = self.boolean_meta.validate(None)

        assert False == response
示例#4
0
    def test_method_also_takes(self):
        @method_takes("hello", StringMeta(), REQUIRED, "hello2", BooleanMeta(),
                      False)
        class Thing(object):
            def __init__(self):
                pass

        @method_also_takes("world", BooleanMeta(), REQUIRED, "hello2",
                           BooleanMeta(), True, "default", StringMeta(),
                           "nothing")
        class Thing2(Thing):
            pass

        # Check original hasn't been modified
        itakes = MapMeta()
        elements = OrderedDict()
        elements["hello"] = StringMeta()
        elements["hello2"] = BooleanMeta()
        itakes.set_elements(elements)
        itakes.set_required(["hello"])
        defaults = OrderedDict()
        defaults["hello2"] = False
        assert Thing.MethodModel.takes.to_dict() == itakes.to_dict()
        assert Thing.MethodModel.returns.to_dict() == MapMeta().to_dict()
        assert Thing.MethodModel.defaults == defaults

        # Check new one overrides/improves on original
        itakes = MapMeta()
        elements = OrderedDict()
        elements["hello"] = StringMeta()
        elements["hello2"] = BooleanMeta()
        elements["world"] = BooleanMeta()
        elements["default"] = StringMeta()
        itakes.set_elements(elements)
        itakes.set_required(["hello", "world"])
        defaults = OrderedDict()
        defaults["hello2"] = True
        defaults["default"] = "nothing"
        assert Thing2.MethodModel.takes.to_dict() == itakes.to_dict()
        assert Thing2.MethodModel.returns.to_dict() == MapMeta().to_dict()
        assert Thing2.MethodModel.defaults == defaults
示例#5
0
        "Specify that this class will take a parameter name"), REQUIRED,
    "description", StringMeta(
        "Description of this parameter"), REQUIRED,
    "default", NumberMeta("float64", default_desc), OPTIONAL)
def float64(params):
    """Add a float64 parameter to be passed when instantiating this YAML file"""
    return args_for_takes(params, NumberMeta, "float64")


@method_takes(
    "name", StringMeta(
        "Specify that this class will take a parameter name"), REQUIRED,
    "description", StringMeta(
        "Description of this parameter"), REQUIRED,
    "default", NumberMeta("int32", default_desc), OPTIONAL)
def int32(params):
    """Add an int32 parameter to be passed when instantiating this YAML file"""
    return args_for_takes(params, NumberMeta, "int32")


@method_takes(
    "name", StringMeta(
        "Specify that this class will take a parameter name"), REQUIRED,
    "description", StringMeta(
        "Description of this parameter"), REQUIRED,
    "default", BooleanMeta("bool", default_desc), OPTIONAL)
def boolean(params):
    """Add a boolean parameter to be passed when instantiating this YAML file"""
    return args_for_takes(params, BooleanMeta)

示例#6
0
 def setUp(self):
     self.boolean_meta = BooleanMeta("test description")
示例#7
0
from malcolm.core import Part, method_takes, REQUIRED
from malcolm.tags import widget_types, widget, config, group
from malcolm.modules.builtin.vmetas import StringMeta, BooleanMeta, ChoiceMeta


@method_takes("name", StringMeta("Name of the created attribute"), REQUIRED,
              "description",
              StringMeta("Desc of created attribute"), REQUIRED, "widget",
              ChoiceMeta("Widget type", [""] + widget_types), "", "writeable",
              BooleanMeta("Is the attribute writeable?"), False, "group",
              StringMeta("If given, which GUI group should we attach to"), "",
              "config",
              BooleanMeta("If writeable, should this field be loaded/saved?"),
              True)
class AttributePart(Part):
    def __init__(self, params):
        # The created attribute
        self.attr = None
        # Store params
        self.params = params
        super(AttributePart, self).__init__(params.name)

    def create_attribute_models(self):
        # Find the tags
        tags = self.create_tags()
        # Make a meta object for our attribute
        meta = self.create_meta(self.params.description, tags)
        # The attribute we will be publishing
        initial_value = self.get_initial_value()
        self.attr = meta.create_attribute_model(initial_value)
        if self.is_writeable():
示例#8
0
from malcolm.modules.builtin.controllers import ProxyController
from malcolm.core import method_takes, REQUIRED
from malcolm.modules.builtin.vmetas import StringMeta, BooleanMeta


# This is done in python rather than YAML so that we can choose whether or not
# to publish this block via the process
@method_takes("comms", StringMeta("MRI for the comms block"), REQUIRED, "mri",
              StringMeta("MRI for the client block"), REQUIRED, "publish",
              BooleanMeta("Whether to publish this block"), False)
def proxy_block(process, params):
    controller = ProxyController(process, (), params)
    process.add_controller(params.mri, controller, params.publish)
    return controller
示例#9
0
from malcolm.modules.builtin.controllers import StatefulController
from malcolm.core import Part, method_takes, REQUIRED, MethodModel
from malcolm.modules.builtin.vmetas import StringMeta, NumberMeta, BooleanMeta
from .catoolshelper import CaToolsHelper


@method_takes(
    "name", StringMeta("Name of the created method"), REQUIRED,
    "description", StringMeta("desc of created method"), REQUIRED,
    "pv", StringMeta("full pv to write to when method called"), REQUIRED,
    "statusPv", StringMeta("Status pv to see if successful"), "",
    "goodStatus", StringMeta("Good value for status pv"), "",
    "messagePv", StringMeta("PV containing error message if unsuccessful"), "",
    "value", NumberMeta("int32", "value to write to pv when method called"), 1,
    "wait", BooleanMeta("Wait for caput callback?"), True)
class CAActionPart(Part):
    """Group a number of PVs together that represent a method like acquire()"""
    def __init__(self, params):
        """
        Args:
            params (Map): The params to initialize with
        """
        self.method = None
        self.params = params
        self.catools = CaToolsHelper.instance()
        super(CAActionPart, self).__init__(params.name)

    def create_method_models(self):
        # Method instance
        self.method = MethodModel(self.params.description)
        # TODO: set widget tag?
示例#10
0
from paho.mqtt import client

from malcolm.modules.builtin.controllers.servercomms import ServerComms
from malcolm.core import Hook, method_also_takes, Process, Subscribe, Update, Put, Unsubscribe
from malcolm.modules.builtin.vmetas import StringMeta, NumberMeta, BooleanMeta


@method_also_takes(
    "host", StringMeta("Address of MQTT broker"), "localhost",
    "port", NumberMeta("int32", "Port number to connect to the broker on"), 1883,
    "keepalive", NumberMeta("int32", "Number of seconds between pings to broker if no traffic since"), 60,
    "block", StringMeta("Block name to monitor"), "",
    "attribute", StringMeta("Attribute of block to monitor"), "",
    "topic_prefix", StringMeta("Prefix to prepend to MQTT topic (no slash)"), "",
    "read_only", BooleanMeta("Should MQTT only read and not write?"), True)
class MQTTServerComms(ServerComms):
    """A class for communication between Malcolm and an MQTT broker"""
    _server = None
    _spawned = None
    _blockname = None
    _attributename = None
    _topic = None
    _blocking = False
    use_cothread = False

    def do_init(self):
        self.log.warn(self.params.read_only)
        super(MQTTServerComms, self).do_init()
        self._blockname = self.params.block
        self._attributename = self.params.attribute
        self._topic = str.join("", [self.params.topic_prefix, "/", self.params.block, 
示例#11
0
from malcolm.modules.builtin.vmetas import StringMeta, ChoiceMeta, \
    BooleanMeta, NumberMeta
from .catoolshelper import CaToolsHelper


@method_takes(
    "name",
    StringMeta("Name of the created attribute"), REQUIRED, "description",
    StringMeta("Description of created attribute"), REQUIRED, "pv",
    StringMeta("Full pv of demand and default for rbv"), "", "rbv",
    StringMeta("Override for rbv"), "", "rbvSuff",
    StringMeta("Set rbv to pv + rbv_suff"), "", "widget",
    ChoiceMeta("Widget type", [""] + widget_types), "", "inport",
    ChoiceMeta("Inport type", [""] + port_types), "", "group",
    StringMeta("If given, which GUI group should we attach to"), "", "config",
    BooleanMeta("Should this field be loaded/saved?"), True, "minDelta",
    NumberMeta("float64", "Minimum time between attribute updates in seconds"),
    0.05, "timeout",
    NumberMeta("float64",
               "Max time to wait for puts to complete, <0 is forever"), 5.0)
class CAPart(AttributePart):
    """Abstract class for exposing PVs as `Attribute` instances"""
    def __init__(self, params):
        if not params.rbv and not params.pv:
            raise ValueError('Must pass pv or rbv')
        if not params.rbv:
            if params.rbvSuff:
                params.rbv = params.pv + params.rbvSuff
            else:
                params.rbv = params.pv
        # Camonitor subscription
示例#12
0
 def create_meta(self, description, tags):
     return BooleanMeta(description=description, tags=tags)
示例#13
0
    """Define a float64 parameter to be used within this YAML file"""
    return {params.name: params.value}


@method_takes("name", StringMeta("The name of the defined parameter"),
              REQUIRED, "value",
              NumberMeta("int32",
                         "The value of the defined parameter"), REQUIRED)
def int32(params):
    """Define an int32 parameter to be used within this YAML file"""
    return {params.name: params.value}


@method_takes("name", StringMeta("The name of the defined parameter"),
              REQUIRED, "value",
              BooleanMeta("bool",
                          "The value of the defined parameter"), REQUIRED)
def boolean(params):
    """Define a boolean parameter to be used within this YAML file"""
    return {params.name: params.value}


@method_takes("value", StringMeta("The docstring value"), REQUIRED)
def docstring(params):
    """Define the docstring for the YAML file"""
    return {"docstring": params.value}


@method_takes(
    "name", StringMeta("The name of the defined parameter"), REQUIRED, "env",
    StringMeta("The environment variable name to get the value from"),
    REQUIRED)