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
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") self.assertTrue(response) response = self.boolean_meta.validate("") self.assertFalse(response) def test_given_value_int_then_cast_and_return(self): response = self.boolean_meta.validate(15) self.assertTrue(response) response = self.boolean_meta.validate(0) self.assertFalse(response) def test_given_value_boolean_then_cast_and_return(self): response = self.boolean_meta.validate(True) self.assertTrue(response) response = self.boolean_meta.validate(False) self.assertFalse(response) def test_given_value_None_then_return(self): response = self.boolean_meta.validate(None) self.assertEqual(False, response)
def _create_default_attributes(self): # Add the state, status and busy attributes self.state = ChoiceMeta("State of Block", self.stateMachine.possible_states, label="State").make_attribute() yield "state", self.state, None self.status = StringMeta("Status of Block", label="Status").make_attribute() yield "status", self.status, None self.busy = BooleanMeta("Whether Block busy or not", label="Busy").make_attribute() yield "busy", self.busy, None
def create_attributes(self): """Method that should provide Attribute instances for Block Yields: tuple: (string name, Attribute, callable put_function). """ # Add the state, status and busy attributes self.state = ChoiceMeta("State of Block", self.stateMachine.possible_states, label="State").make_attribute() yield "state", self.state, None self.status = StringMeta("Status of Block", label="Status").make_attribute() yield "status", self.status, None self.busy = BooleanMeta("Whether Block busy or not", label="Busy").make_attribute() yield "busy", self.busy, None
def test_method_also_takes(self): @method_takes("hello", StringMeta(), REQUIRED, "hello2", BooleanMeta(), False) class Thing(object): 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(ElementMap(elements)) itakes.set_required(["hello"]) defaults = OrderedDict() defaults["hello2"] = False self.assertEqual(Thing.MethodMeta.takes.to_dict(), itakes.to_dict()) self.assertEqual(Thing.MethodMeta.returns.to_dict(), MapMeta().to_dict()) self.assertEqual(Thing.MethodMeta.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(ElementMap(elements)) itakes.set_required(["hello", "world"]) defaults = OrderedDict() defaults["hello2"] = True defaults["default"] = "nothing" self.assertEqual(Thing2.MethodMeta.takes.to_dict(), itakes.to_dict()) self.assertEqual(Thing2.MethodMeta.returns.to_dict(), MapMeta().to_dict()) self.assertEqual(Thing2.MethodMeta.defaults, defaults)
from malcolm.core import Part, method_takes, REQUIRED, MethodMeta from malcolm.core.vmetas import StringMeta, NumberMeta, BooleanMeta from malcolm.controllers.defaultcontroller import DefaultController from malcolm.parts.ca.cothreadimporter import CothreadImporter @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"), None, "goodStatus", StringMeta("Good value for status pv"), "", "value", NumberMeta("int32", "value to write to pv when method called"), 1, "wait", BooleanMeta("Wait for caput callback?"), True) class CAActionPart(Part): method = None def __init__(self, process, params): self.cothread, self.catools = CothreadImporter.get_cothread(process) super(CAActionPart, self).__init__(process, params) def create_methods(self): # MethodMeta instance self.method = MethodMeta(self.params.description) # TODO: set widget tag? yield self.params.name, self.method, self.caput @DefaultController.Reset def connect_pvs(self, _): # make the connection in cothread's thread pvs = [self.params.pv]
class LayoutPart(Part): # Child block object child = None # {part_name: visible} saying whether part_name is visible part_visible = None # Layout options x = 0 y = 0 visible = False mri = None name = None def store_params(self, params): self.name = params.name self.child = self.process.get_block(params.child) self.mri = params.child self.part_visible = {} @ManagerController.UpdateLayout @method_takes("layout_table", layout_table_meta, REQUIRED, "outport_table", outport_table_meta, REQUIRED) @method_returns("mri", StringMeta("Malcolm full name of child block"), REQUIRED, "x", NumberMeta("float64", "X Co-ordinate of child block"), REQUIRED, "y", NumberMeta("float64", "X Co-ordinate of child block"), REQUIRED, "visible", BooleanMeta("Whether child block is visible"), REQUIRED) def update_layout_table(self, task, params, returns): for i, name in enumerate(params.layout_table.name): _, _, x, y, visible = params.layout_table[i] if name == self.name: if self.visible and not visible: self.sever_inports(task) self.x = x self.y = y self.visible = visible else: was_visible = self.part_visible.get(name, True) if was_visible and not visible: self.sever_outports(task, name, params.outport_table) self.part_visible[name] = visible returns.mri = self.mri returns.x = self.x returns.y = self.y returns.visible = self.visible return returns def _get_flowgraph_ports(self, direction="out"): # {attr_name: port_tag} ports = OrderedDict() for attr_name in self.child.endpoints: attr = self.child[attr_name] if isinstance(attr, Attribute): for tag in attr.meta.tags: if tag.startswith("flowgraph:%sport" % direction): ports[attr] = tag return ports def sever_inports(self, task): inports = self._get_flowgraph_ports("in") futures = [] for attr in inports: futures += task.put_async(attr, attr.meta.choices[0]) task.wait_all(futures) def sever_outports(self, task, name, outport_table): # Find the outports of this part # {outport_value: typ} e.g. "PCOMP.OUT" -> "bit" outports = {} for i, n in enumerate(outport_table.name): if n == name: outports[outport_table.value[i]] = outport_table.type[i] inports = self._get_flowgraph_ports("in") futures = [] for attr, port_tag in inports.items(): typ = port_tag.split(":")[2] if outports.get(attr.value, None) == typ: futures += task.put_async(attr, attr.meta.choices[0]) task.wait_all(futures) @ManagerController.ListOutports @method_returns("type", StringArrayMeta("Type of outport (e.g. bit or pos)"), REQUIRED, "value", StringArrayMeta("Value of outport (e.g. PULSE1.OUT)"), REQUIRED) def list_outports(self, _, returns): outports = self._get_flowgraph_ports("out") types = [] values = [] for port_tag in outports.values(): _, _, typ, name = port_tag.split(":", 4) types.append(typ) values.append(name) returns.type = types returns.value = values return returns
def setUp(self): self.boolean_meta = BooleanMeta("test description")
from malcolm.parts.builtin.attributepart import AttributePart from malcolm.core.vmetas import StringMeta, ChoiceMeta, BooleanMeta from malcolm.controllers.defaultcontroller import DefaultController from malcolm.parts.ca.cothreadimporter import CothreadImporter from malcolm.tags import widget_types, inport, port_types @method_takes( "name", StringMeta("Name of the created attribute"), REQUIRED, "description", StringMeta("Desc of created attribute"), REQUIRED, "pv", StringMeta("Full pv of demand and default for rbv"), "", "rbv", StringMeta("Override for rbv"), "", "rbvSuff", StringMeta("Set rbv ro pv + rbv_suff"), "", "widget", ChoiceMeta("Widget type", [""] + widget_types), "", "inport", ChoiceMeta("Inport type", [""] + port_types), "", "config", BooleanMeta("Should this field be loaded/saved?"), False) class CAPart(AttributePart): # Camonitor subscription monitor = None def __init__(self, process, params): self.cothread, self.catools = CothreadImporter.get_cothread(process) # Format for all caputs self.ca_format = self.catools.FORMAT_TIME super(CAPart, self).__init__(process, params) def store_params(self, params): if not params.rbv and not params.pv: raise ValueError('Must pass pv or rbv') if not params.rbv: if params.rbvSuff:
from malcolm.core import Part, method_takes, REQUIRED from malcolm.core.vmetas import StringMeta, BooleanMeta, ChoiceMeta from malcolm.tags import widget_types, widget, config @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, "config", BooleanMeta("Should this field be loaded/saved?"), False) class AttributePart(Part): # Attribute instance attr = None def create_attributes(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.make_attribute(initial_value) writeable_func = self.get_writeable_func() yield self.params.name, self.attr, writeable_func def create_meta(self, description, tags): raise NotImplementedError() def get_writeable_func(self): if self.params.writeable:
def create_meta(self, description, tags): return BooleanMeta(description=description, tags=tags)