Example #1
0
    def set_table_cls(self, table_cls=None):
        # type: (Type[Table]) -> None
        if table_cls is None or table_cls.__name__ == "TableSubclass":
            # Either autogenerated by this function or not set, so make one

            class TableSubclass(Table):
                def __init__(self, **kwargs):
                    # type: (**Any) -> None
                    self.__dict__.update(kwargs)

            table_cls = TableSubclass
            for k, meta in self.elements.items():
                # We can distinguish the type by asking for the default
                # validate value
                default_array = meta.validate(None)  # type: Array
                anno = Anno(meta.description, default_array.typ, k)
                anno.is_array = True
                anno.is_mapping = False
                table_cls.call_types[k] = anno
        else:
            # User supplied, check it matches element names
            assert issubclass(table_cls, Table), \
                "Expecting table subclass, got %s" % (table_cls,)
            missing = set(self.elements) - set(table_cls.call_types)
            assert not missing, "Supplied Table missing fields %s" % (
                missing, )
            extra = set(table_cls.call_types) - set(self.elements)
            assert not extra, "Supplied Table has extra fields %s" % (extra, )
        self.table_cls = table_cls
Example #2
0
    def set_table_cls(self, table_cls: Type[Table] = None) -> None:
        if table_cls is None or table_cls.__name__ == "TableSubclass":
            # Either autogenerated by this function or not set, so make one

            class TableSubclass(Table):
                def __init__(self, **kwargs: Any) -> None:
                    self.__dict__.update(kwargs)

            table_cls = TableSubclass
            for k, meta in self.elements.items():
                # We can distinguish the type by asking for the default
                # validate value
                default_array: Array = meta.validate(None)
                anno = Anno(meta.description, name=k).set_typ(
                    default_array.typ, is_array=True
                )
                table_cls.call_types[k] = anno
        else:
            # User supplied, check it matches element names
            assert Table.matches_type(
                table_cls
            ), f"Expecting table subclass, got {table_cls}"
            missing = set(self.elements) - set(table_cls.call_types)
            assert not missing, f"Supplied Table missing fields {missing}"
            extra = set(table_cls.call_types) - set(self.elements)
            assert not extra, f"Supplied Table has extra fields {extra}"
        self.table_cls = table_cls
Example #3
0
 def __init__(self, generator, axesToMove=None, **kwargs):
     # type: (AGenerator, UAxesToMove, **Any) -> None
     if kwargs:
         # Got some additional args to report
         self.call_types = self.call_types.copy()
         for k in kwargs:
             # We don't use this apart from its presence,
             # so no need to fill in description, typ, etc.
             self.call_types[k] = Anno("")
         self.__dict__.update(kwargs)
     self.generator = generator
     if axesToMove is None:
         axesToMove = generator.axes
     self.axesToMove = AAxesToMove(axesToMove)
Example #4
0
 def set_endpoint_data(self, name, value):
     # type: (str, ModelOrDict) -> Any
     name = deserialize_object(name, str_)
     if name == "meta":
         value = deserialize_object(value, BlockMeta)
     else:
         value = deserialize_object(value, (AttributeModel, MethodModel))
     with self.notifier.changes_squashed:
         if name in self.call_types:
             # Stop the old Model notifying
             getattr(self, name).set_notifier_path(Model.notifier, [])
         else:
             anno = Anno("Field", typ=type(value))
             self.call_types[name] = anno
         value.set_notifier_path(self.notifier, self.path + [name])
         setattr(self, name, value)
         # Tell the notifier what changed
         self.notifier.add_squashed_change(self.path + [name], value)
         self._update_fields()
         return value
Example #5
0
def creator_with_nice_signature(creator, sections, yamlname, yaml_path, docstring):
    takes = _create_takes_arguments(sections)
    args = []
    for anno in takes:
        if anno.default is NO_DEFAULT:
            args.append(anno.name)
        else:
            args.append(f"{anno.name}={anno.default!r}")
    func = f"""
def creator_from_yaml({', '.join(args)}):
    return creator(locals())"""
    # Copied from decorator pypi module
    code = compile(func, yaml_path, "single")
    exec(code, locals())
    ret = locals()["creator_from_yaml"]
    ret.return_type = Anno("Any return value", Any, "return")
    ret.call_types = OrderedDict((anno.name, anno) for anno in takes)
    ret.__doc__ = docstring
    ret.__name__ = yamlname
    ret.yamlname = yamlname
    return ret
Example #6
0
    def __init__(self,
                 generator: AGenerator,
                 axesToMove: UAxesToMove = None,
                 breakpoints: ABreakpoints = None,
                 **kwargs: Any) -> None:
        if kwargs:
            # Got some additional args to report
            self.call_types: Dict[str,
                                  Anno] = ConfigureParams.call_types.copy()
            for k in kwargs:
                # We don't use this apart from its presence,
                # so no need to fill in description, typ, etc.
                self.call_types[k] = Anno("")
            self.__dict__.update(kwargs)
        self.generator = generator
        if axesToMove is None:
            axesToMove = generator.axes
        self.axesToMove = AAxesToMove(axesToMove)

        if breakpoints is None:
            breakpoints = []
        self.breakpoints = ABreakpoints(breakpoints)
Example #7
0
    PreConfigureHook,
    RunHook,
    SeekHook,
    UInfos,
    UParameterTweakInfos,
    ValidateHook,
)
from ..infos import (
    DatasetProducedInfo,
    DetectorMutiframeInfo,
    ParameterTweakInfo,
    RunProgressInfo,
)
from ..util import ADetectorTable, DetectorTable, RunnableStates

with Anno("The initial value of FramesPerStep for this detector at configure"):
    AInitialFramesPerStep = int

# Pull re-used annotypes into our namespace in case we are subclassed
AMri = builtin.parts.AMri
AInitialVisibility = builtin.parts.AInitialVisibility

ss = RunnableStates


class DetectorChildPart(builtin.parts.ChildPart):
    """Part controlling a child detector Block that exposes a configure/run
    interface with fileDir and fileTemplate"""
    def __init__(
        self,
        name: APartName,
Example #8
0
from annotypes import Anno

from malcolm.core import (
    Alarm,
    ChoiceMeta,
    NumberMeta,
    Part,
    PartRegistrar,
    Port,
    StringMeta,
)
from malcolm.modules import builtin, ca

from ..util import CS_AXIS_NAMES

with Anno("PV prefix for CSPort and CSAxis records"):
    APvPrefix = str

# Pull re-used annotypes into our namespace in case we are subclassed
AGroup = ca.util.AGroup


class RawMotorSinkPortsPart(Part):
    """Defines a string `Attribute` representing a asyn port that should be
    depicted as a Source Port on a Block"""
    def __init__(self,
                 pv_prefix: APvPrefix,
                 group: ca.util.AGroup = None) -> None:
        super().__init__("sinkPorts")
        self.pvs = [pv_prefix + ":CsPort", pv_prefix + ":CsAxis"]
        self.rbvs = [
import unittest
import os

from annotypes import add_call_types, Anno
from scanpointgenerator import LineGenerator, CompoundGenerator

from malcolm.core import Part, Process, Context, APartName, PartRegistrar, \
    NumberMeta
from malcolm.modules.builtin.hooks import AContext
from malcolm.modules.builtin.util import set_tags
from malcolm.modules.scanning.hooks import RunHook
from malcolm.modules.scanning.parts import RunnableChildPart
from malcolm.modules.scanning.controllers import RunnableController

with Anno("How long to wait"):
    AWait = float


class WaitingPart(Part):
    def __init__(self, name, wait=0.0):
        # type: (APartName, AWait) -> None
        super(WaitingPart, self).__init__(name)
        meta = NumberMeta("float64", "How long to wait")
        set_tags(meta, writeable=True)
        self.attr = meta.create_attribute_model(wait)
        self.register_hooked(RunHook, self.run)

    def setup(self, registrar):
        # type: (PartRegistrar) -> None
        registrar.add_attribute_model(self.name, self.attr,
                                      self.attr.set_value)
Example #10
0
import os

from annotypes import Anno, add_call_types
from tornado.web import RedirectHandler, StaticFileHandler

from malcolm.core import APartName, Part, PartRegistrar

from ..hooks import ReportHandlersHook, UHandlerInfos
from ..infos import HandlerInfo

www_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "www"))

with Anno("Path to www directory to get files from"):
    APath = str


# Always serve index.html, no matter what the route
class IndexHandler(StaticFileHandler):
    @classmethod
    def get_absolute_path(cls, root, path):
        return super(IndexHandler, cls).get_absolute_path(root, "index.html")


class GuiServerPart(Part):
    """Static file server to be used as a fallback. Must be last part"""

    GuiHandler = IndexHandler

    def __init__(self, name: APartName = "gui", path: APath = www_dir) -> None:
        super().__init__(name)
        self.path = path
Example #11
0
from annotypes import Anno, WithCallTypes, Array, to_array, Union, Sequence

with Anno("The scannable axes, e.g. ['x', 'y'] or 'x'"):
    Axes = Array[str]
with Anno("The first point to be generated, e.g. [0., 2.4] or 1."):
    Start = Array[float]
with Anno("The final point to be generated, e.g. [-8., 6.4] or 5."):
    Stop = Array[float]
with Anno("The number of points to generate, e.g. 5"):
    Size = int
with Anno("The scannable units, e.g. ['mm', 'deg'] or 'mm'"):
    Units = Array[str]
with Anno("Whether to reverse on alternate runs"):
    Alternate = bool

def_units = Units("mm")


class ManyArgs(WithCallTypes):
    def __init__(self,
                 axes: Union[Axes, Sequence[str], str],
                 start: Union[Start, Sequence[float], float],
                 stop: Union[Stop, Sequence[float], float],
                 size: Size,
                 units: Union[Units, Sequence[str], str] = def_units,
                 alternate: Alternate = False):
        self.axes = Axes(axes)
        self.start = Start(start)
        self.stop = Stop(stop)
        self.size = size
        self.units = Units(units)
Example #12
0
from annotypes import Anno

from malcolm.core import (
    Alarm,
    BooleanMeta,
    Part,
    PartRegistrar,
    TimeStamp,
    VMeta,
    snake_to_camel,
)

from ..pandablocksclient import PandABlocksClient

with Anno("Client for setting and getting field"):
    AClient = PandABlocksClient
with Anno("Meta object to create attribute from"):
    AMeta = VMeta
with Anno("Name of Block in TCP server"):
    ABlockName = str
with Anno("Name of Field in TCP server"):
    AFieldName = str
with Anno("Initial value of attribute"):
    AInitialValue = Any


class PandAFieldPart(Part):
    """This will normally be instantiated by the PandABox assembly, not created
    in yaml"""
    def __init__(
from annotypes import Anno, add_call_types

from malcolm.core import PartRegistrar
from malcolm.modules.builtin.hooks import AContext
from malcolm.modules.builtin.parts import AMri, APartName, ChildPart

from .. import hooks

with Anno("Whether to raise a ValueError for a bad status"):
    AErrorOnFail = bool


class DirectoryMonitorPart(ChildPart):
    """Part for checking a directoryMonitor Manager is happy"""
    def __init__(self,
                 name: APartName,
                 mri: AMri,
                 error_on_fail: AErrorOnFail = True) -> None:
        super().__init__(name, mri, initial_visibility=True)
        self.error_on_fail = error_on_fail

    def setup(self, registrar: PartRegistrar) -> None:
        super().setup(registrar)
        # Hooks
        registrar.hook(hooks.ConfigureHook, self.check_directories)

    @add_call_types
    def check_directories(self, context: AContext) -> None:
        child = context.block_view(self.mri)
        try:
            child.managerCheck()
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
#    Charles Mita - initial API and implementation and/or initial documentation
#
###

from annotypes import Anno, Union, Array, Sequence

from math import cos, sin

from scanpointgenerator.core import ROI
from scanpointgenerator.compat import np

with Anno("The start point of the rectangle"):
    AStart = Array[float]
UStart = Union[AStart, Sequence[float]]
with Anno("The width of the rectangle"):
    AWidth = float
with Anno("The height of the rectangle"):
    AHeight = float
with Anno("The angle of the rectangle"):
    AAngle = float


@ROI.register_subclass("scanpointgenerator:roi/RectangularROI:1.0")
class RectangularROI(ROI):
    def __init__(self, start, width, height, angle=0):
        # type: (UStart, AWidth, AHeight, AAngle) -> None
        super(RectangularROI, self).__init__()
Example #15
0

class StatisticsName(Enum):
    MIN = "MIN_VALUE"  # Minimum counts in any element
    MIN_X = "MIN_X"  # X position of minimum counts
    MIN_Y = "MIN_Y"  # Y position of minimum counts
    MAX = "MAX_VALUE"  # Maximum counts in any element
    MAX_X = "MAX_X"  # X position of maximum counts
    MAX_Y = "MAX_Y"  # Y position of maximum counts
    MEAN = "MEAN_VALUE"  # Mean counts of all elements
    SIGMA = "SIGMA_VALUE"  # Sigma of all elements
    SUM = "TOTAL"  # Sum of all elements
    NET = "NET"  # Sum of all elements not in background region


with Anno("Dataset names"):
    ANameArray = Array[str]
with Anno("Filenames of HDF files relative to fileDir"):
    AFilenameArray = Array[str]
with Anno("Types of dataset"):
    ATypeArray = Array[DatasetType]
with Anno("Rank (number of dimensions) of the dataset"):
    ARankArray = Array[np.int32]
with Anno("Dataset paths within HDF files"):
    APathArray = Array[str]
with Anno("UniqueID array paths within HDF files"):
    AUniqueIDArray = Array[str]
UNameArray = Union[ANameArray, Sequence[str]]
UFilenameArray = Union[AFilenameArray, Sequence[str]]
UTypeArray = Union[ATypeArray, Sequence[DatasetType]]
URankArray = Union[ARankArray, Sequence[np.int32]]
Example #16
0
import time

from annotypes import Anno, WithCallTypes

with Anno("The exposure to be active for"):
    Exposure = float
with Anno("The full path to the text file to write"):
    Path = str


class Simple(WithCallTypes):
    def __init__(self, exposure, path="/tmp/file.txt"):
        # type: (Exposure, Path) -> None
        self.exposure = exposure
        self.path = path

    def write_data(self, data):
        # type: (str) -> None
        with open(self.path, "w") as f:
            time.sleep(self.exposure)
            f.write("Data: %s\n" % data)
Example #17
0
class StatisticsName(Enum):
    """The types of statistics calculated by the areaDetector NDPluginStats"""

    MIN = "MIN_VALUE"  #: Minimum counts in any element
    MIN_X = "MIN_X"  #: X position of minimum counts
    MIN_Y = "MIN_Y"  #: Y position of minimum counts
    MAX = "MAX_VALUE"  #: Maximum counts in any element
    MAX_X = "MAX_X"  #: X position of maximum counts
    MAX_Y = "MAX_Y"  #: Y position of maximum counts
    MEAN = "MEAN_VALUE"  #: Mean counts of all elements
    SIGMA = "SIGMA_VALUE"  #: Sigma of all elements
    SUM = "TOTAL"  #: Sum of all elements
    NET = "NET"  #: Sum of all elements not in background region


with Anno("Is the IOC this part connects to running on Windows?"):
    APartRunsOnWindows = bool

with Anno("NDAttribute name to be exported"):
    AAttributeNames = Union[Array[str]]
with Anno("source ID for attribute (PV name for PVAttribute," +
          "asyn param name for paramAttribute)"):
    ASourceIds = Union[Array[str]]
with Anno("PV descriptions"):
    ADescriptions = Union[Array[str]]
with Anno("Types of attribute dataset"):
    AAttributeTypes = Union[Array[AttributeDatasetType]]
with Anno("Type of attribute source"):
    ASourceTypes = Union[Array[SourceType]]
with Anno("Type of attribute data"):
    ADataTypes = Union[Array[DataType]]
Example #18
0
from annotypes import Anno

from malcolm.modules import builtin

from ..util import AClient

with Anno("The field of *METADATA to set when label is changed"):
    AMetadataField = str
ALabelValue = builtin.parts.ALabelValue


class PandALabelPart(builtin.parts.LabelPart):
    def __init__(self, client: AClient, metadata_field: AMetadataField,
                 value: ALabelValue) -> None:
        super().__init__(value)
        self.client = client
        self.metadata_field = metadata_field

    def handle_change(self, value, ts):
        if not value:
            value = self.initial_value
        super().set_label(value, ts)

    def set_label(self, value, ts=None):
        super().set_label(value, ts)
        self.client.set_field("*METADATA", self.metadata_field,
                              self.attr.value)
Example #19
0
    def test_put_attribute_values(self):
        self.o.put_attribute_values(dict(attr=43))
        self.context.put_async.assert_called_once_with(
            ["block", "attr", "value"], 43)
        self.context.wait_all_futures.assert_called_once_with(
            [self.context.put_async.return_value],
            timeout=None,
            event_timeout=None)

    def test_async_call(self):
        self.o.method_async(a=3)
        self.o.method.post_async.assert_called_once_with(a=3)


with Anno("A Param"):
    AParam = str


class MyPart(Part):
    def setup(self, registrar):
        registrar.add_method_model(self.my_method, "myMethod")

    @add_call_types
    def my_method(self, param1: AParam, param2: AParam) -> AParam:
        return param1 + param2


class TestMethod(unittest.TestCase):
    def setUp(self):
        self.process = Process("proc")
Example #20
0
    PreConfigureHook,
    PreRunHook,
    ReportStatusHook,
    RunHook,
    SeekHook,
    ValidateHook,
)
from ..infos import ConfigureParamsInfo, ParameterTweakInfo, RunProgressInfo
from ..util import AGenerator, ConfigureParams, RunnableStates, resolve_generator_tweaks

PartContextParams = Iterable[Tuple[Part, Context, Dict[str, Any]]]
PartConfigureParams = Dict[Part, ConfigureParamsInfo]

ss = RunnableStates

with Anno("The validated configure parameters"):
    AConfigureParams = ConfigureParams
with Anno("Step to mark as the last completed step, -1 for current"):
    ALastGoodStep = int

# Pull re-used annotypes into our namespace in case we are subclassed
AConfigDir = builtin.controllers.AConfigDir
AInitialDesign = builtin.controllers.AInitialDesign
ADescription = builtin.controllers.ADescription
ATemplateDesigns = builtin.controllers.ATemplateDesigns


def update_configure_model(
    configure_model: MethodMeta, part_configure_infos: List[ConfigureParamsInfo]
) -> None:
    # These will not be inserted as they already exist
Example #21
0
from annotypes import Anno

from malcolm.core import Part, PartRegistrar, StringMeta

from ..infos import LabelInfo
from ..util import set_tags

with Anno("Initial value of Block label"):
    ALabelValue = str


class LabelPart(Part):
    """Part representing a the title of the Block a GUI should display"""

    def __init__(self, value: ALabelValue = None) -> None:
        super().__init__("label")
        meta = StringMeta("Label for the block")
        set_tags(meta, writeable=True)
        self.initial_value = value
        self.attr = meta.create_attribute_model(self.initial_value)

    def _report(self):
        self.registrar.report(LabelInfo(self.attr.value))

    def setup(self, registrar: PartRegistrar) -> None:
        super().setup(registrar)
        registrar.add_attribute_model(self.name, self.attr, self.set_label)
        self._report()

    def set_label(self, value, ts=None):
        self.attr.set_value(value, ts=ts)
Example #22
0
import time

from annotypes import Anno, add_call_types

from malcolm.core import PartRegistrar
from malcolm.modules import builtin

# Pull re-used annotypes into our namespace in case we are subclassed
APartName = builtin.parts.APartName
AMri = builtin.parts.AMri

with Anno("The demand value to move our counter motor to"):
    ADemand = float
with Anno("The amount of time to get to the demand position"):
    ADuration = float


class MotorMovePart(builtin.parts.ChildPart):
    """Provides control of a `counter_block` within a `ManagerController`"""
    def __init__(self, name, mri):
        # type: (APartName, AMri) -> None
        super(MotorMovePart, self).__init__(name,
                                            mri,
                                            stateful=False,
                                            initial_visibility=True)

    def setup(self, registrar):
        # type: (PartRegistrar) -> None
        super(MotorMovePart, self).setup(registrar)
        # Method
        registrar.add_method_model(self.move,
Example #23
0
def get_motion_trigger(
    part_info: scanning.hooks.APartInfo, ) -> scanning.infos.MotionTrigger:
    infos: List[
        MotionTriggerInfo] = scanning.infos.MotionTriggerInfo.filter_values(
            part_info)
    if infos:
        assert len(
            infos) == 1, f"Expected 0 or 1 MotionTriggerInfo, got {len(infos)}"
        trigger = infos[0].trigger
    else:
        trigger = scanning.infos.MotionTrigger.EVERY_POINT
    return trigger


with Anno("Minimum turnaround time for non-joined points"):
    AMinTurnaround = float
with Anno("Minimum interval between turnaround points"):
    AMinInterval = float


@dataclass
class MinTurnaround:
    """Dataclass for the Minimum turnaround information.

    This may come from a MinTurnaroundInfo if the scan block has a MinTurnaroundPart
    otherwise MIN_TIME and MIN_INTERVAL are used as default values.
    """

    time: AMinTurnaround
    interval: AMinInterval
Example #24
0
from typing import Any

from annotypes import Anno, WithCallTypes

with Anno("The name of the defined parameter"):
    AName = str
with Anno("The value of the defined parameter"):
    AValue = Any


class Define(WithCallTypes):
    def __init__(self, name: AName, value: AValue) -> None:
        self.name = name
        self.value = value
Example #25
0
from .loggable import Loggable

T = TypeVar("T")


# Clear spawned handles after how many spawns?
SPAWN_CLEAR_COUNT = 1000

# States for how far in start procedure we've got
STOPPED = 0
STARTING = 1
STARTED = 2
STOPPING = 3


with Anno("The list of currently published Controller mris"):
    APublished = Union[Array[str]]


class UnpublishedInfo(Info):
    def __init__(self, mri: str) -> None:
        self.mri = mri


class ProcessPublishHook(Hook):
    """Called when a new block is added"""

    def __init__(self, child: AHookable, published: APublished) -> None:
        super().__init__(child, published=published)

Example #26
0
from annotypes import Anno, Sequence, Array, Union

from malcolm.core import Part, snake_to_camel, PartRegistrar
from ..pandablocksclient import PandABlocksClient

with Anno("Client for setting and getting field"):
    AClient = PandABlocksClient
with Anno("Name of Block in TCP server"):
    ABlockName = str
with Anno("Name of Field in TCP server"):
    AFieldName = str
with Anno("Description for the Method"):
    ADescription = str
with Anno("Tags to be attached to Method"):
    ATags = Array[str]
UTags = Union[ATags, Sequence[str], str]


class PandABlocksActionPart(Part):
    """This will normally be instantiated by the PandABox assembly, not created
    in yaml"""
    def __init__(self, client, block_name, field_name, description, tags):
        # type: (AClient, ABlockName, AFieldName, ADescription, ATags) -> None
        super(PandABlocksActionPart, self).__init__(field_name)
        self.client = client
        self.block_name = block_name
        self.field_name = field_name
        self.description = description
        self.tags = tags
        self.method = None
Example #27
0
from annotypes import Anno, WithCallTypes, Array, add_call_types


class Table(WithCallTypes):
    def validate(self):
        lengths = {a: len(getattr(self, a)) for a in self.call_types}
        assert len(set(lengths.values())) == 1, \
            "Column lengths %s don't match" % lengths

    def __getitem__(self, item):
        self.validate()
        return [getattr(self, a)[item] for a in self.call_types]


with Anno("Name of layout part"):
    Name = Array[str]
with Anno("Malcolm full name of child block"):
    MRI = Array[str]
with Anno("X Coordinate of child block"):
    X = Array[float]
with Anno("Y Coordinate of child block"):
    Y = Array[float]
with Anno("Whether child block is visible"):
    Visible = Array[bool]


class LayoutTable(Table):
    def __init__(self, name: Name, mri: MRI, x: X, y: Y, visible: Visible):
        self.name = name
        self.mri = mri
        self.x = x
Example #28
0
import os
from xml.etree import cElementTree as ET

from annotypes import Anno, add_call_types

from malcolm.compat import et_to_string
from malcolm.core import APartName, PartRegistrar
from malcolm.modules import builtin, scanning

from ..infos import CalculatedNDAttributeDatasetInfo, FilePathTranslatorInfo
from ..util import APartRunsOnWindows, StatisticsName, make_xml_filename

with Anno("Which statistic to capture"):
    AStatsName = StatisticsName
with Anno("Directory to write data to"):
    AFileDir = str

# Pull re-used annotypes into our namespace in case we are subclassed
APartName = APartName


# We will set these attributes on the child block, so don't save them
@builtin.util.no_save("attributesFile", "enableCallbacks", "computeStatistics",
                      "arrayCounter")
class StatsPluginPart(builtin.parts.ChildPart):
    """Part for controlling a `stats_plugin_block` in a Device"""
    def __init__(
        self,
        name: APartName,
        mri: builtin.parts.AMri,
        statistic: AStatsName = StatisticsName.SUM,
Example #29
0
import logging

from annotypes import Anno, Array, Any, TYPE_CHECKING, Mapping, Union, Sequence

from .response import Return, Error, Update, Delta, Response
from .serializable import Serializable, serialize_object

if TYPE_CHECKING:
    from typing import Callable, Tuple, List
    Callback = Callable[[Response], None]

# Create a module level logger
log = logging.getLogger(__name__)

with Anno("ID that should be used for any responses"):
    AId = int
with Anno("Path to target Block substructure"):
    APath = Array[str]
with Anno("Value to put"):
    AValue = Any
with Anno("If set then return the current value in Return when Put completes"):
    AGet = bool
with Anno("Parameters to use in a method Post"):
    AParameters = Mapping[str, Any]
with Anno("Notify of differences only"):
    ADifferences = bool
UPath = Union[APath, Sequence[str], str]


class Request(Serializable):
    """Request object that registers a callback for when action is complete."""
Example #30
0
from annotypes import Anno

from malcolm.core import Part, PartRegistrar, NumberMeta, APartName, \
    AMetaDescription
from ..util import set_tags, AWriteable, AConfig, AGroup, AWidget

with Anno("Initial value of the created attribute"):
    Value = float


class Float64Part(Part):
    """Create a single float64 Attribute on the Block"""
    def __init__(
            self,
            name,  # type: APartName
            description,  # type: AMetaDescription
            writeable=False,  # type: AWriteable
            config=1,  # type: AConfig
            group=None,  # type: AGroup
            widget=None,  # type: AWidget
            value=0.0,  # type: Value
    ):
        # type: (...) -> None
        super(Float64Part, self).__init__(name)
        meta = NumberMeta("float64", description)
        set_tags(meta, writeable, config, group, widget)
        self.attr = meta.create_attribute_model(value)
        self.writeable_func = self.attr.set_value if writeable else None

    def setup(self, registrar):
        # type: (PartRegistrar) -> None