예제 #1
0
    def __init__(self, directories):
        """Initialise the FileInterface object.

        This constructor initialises the FileInterface object, building a parameter tree.
        """
        # Save arguments

        self.fp_config_files = []
        self.txt_files = []
        self.fr_config_files = []
        self.directories = directories

        self.odin_data_config_dir = directories["odin_data"]

        # Store initialisation time
        self.init_time = time.time()

        # Get package version information
        version_info = get_versions()

        # Store all information in a parameter tree
        self.param_tree = ParameterTree({
            'odin_version':
            version_info['version'],
            'tornado_version':
            tornado.version,
            'server_uptime': (self.get_server_uptime, None),
            'fr_config_files': (self.get_fr_config_files, None),
            'fp_config_files': (self.get_fp_config_files, None),
            'config_dir': (self.odin_data_config_dir, None)
        })
    def __init__(self):

        self.int_rw_param = 4576
        self.int_ro_param = 255374
        self.int_rw_value = 9876
        self.int_wo_param = 0

        self.rw_value_set_called = False

        self.nested_rw_param = 53.752
        self.nested_ro_value = 9.8765

        nested_tree = ParameterTree({
            'nestedRwParam': (self.nestedRwParamGet, self.nestedRwParamSet),
            'nestedRoParam':
            self.nested_ro_value
        })

        self.rw_callable_tree = ParameterTree({
            'intCallableRwParam':
            (self.intCallableRwParamGet, self.intCallableRwParamSet),
            'intCallableRoParam': (self.intCallableRoParamGet, None),
            'intCallableWoParam': (None, self.intCallableWoParamSet),
            'intCallableRwValue':
            (self.int_rw_value, self.intCallableRwValueSet),
            'branch':
            nested_tree
        })
예제 #3
0
    def __init__(self):
        """Initialise the SystemInfo object.

        This constructor initlialises the SystemInfo object, extracting various system-level
        parameters and storing them in a parameter tree to be accessible to clients.
        """
        # Store initialisation time
        self.init_time = time.time()

        # Get package version information
        version_info = get_versions()

        # Extract platform information and store in parameter tree
        (system, node, release, version, machine, processor) = platform.uname()
        platform_tree = ParameterTree({
            'system': system,
            'node': node,
            'release': release,
            'version': version,
            'processor': processor
        })

        # Store all information in a parameter tree
        self.param_tree = ParameterTree({
            'odin_version':
            version_info['version'],
            'tornado_version':
            tornado.version,
            'platform':
            platform_tree,
            'server_uptime': (self.get_server_uptime, None),
        })
예제 #4
0
    def setup_class(cls):

        cls.int_rw_param = 4576
        cls.int_ro_param = 255374
        cls.int_rw_value = 9876
        cls.int_wo_param = 0

        cls.rw_value_set_called = False

        cls.nested_rw_param = 53.752
        cls.nested_ro_value = 9.8765

        nested_tree = ParameterTree({
            'nestedRwParam': (cls.nestedRwParamGet, cls.nestedRwParamSet),
            'nestedRoParam':
            cls.nested_ro_value
        })

        cls.rw_callable_tree = ParameterTree({
            'intCallableRwParam':
            (cls.intCallableRwParamGet, cls.intCallableRwParamSet),
            'intCallableRoParam': (cls.intCallableRoParamGet, None),
            'intCallableWoParam': (None, cls.intCallableWoParamSet),
            'intCallableRwValue':
            (cls.int_rw_value, cls.intCallableRwValueSet),
            'branch':
            nested_tree
        })
예제 #5
0
    def test_mutable_nested_tree_external_change(self, test_tree_mutable):

        new_tree = ParameterTree({
            'immutable_param': "Hello",
            "tree": test_tree_mutable.param_tree
        })

        new_node = {"new": 65}
        path = 'tree/extra'
        test_tree_mutable.param_tree.set('extra', new_node)
        val = new_tree.get(path)
        assert val['extra'] == new_node
예제 #6
0
파일: proxy.py 프로젝트: dw96/odin-control
    def __init__(self, **kwargs):
        """
        Initialise the ProxyAdapter.

        This constructor initialises the adapter instance, parsing configuration
        options out of the keyword arguments it is passed. A ProxyTarget object is
        instantiated for each target specified in the options.

         :param kwargs: keyword arguments specifying options
        """

        # Initialise base class
        super(ProxyAdapter, self).__init__(**kwargs)

        # Set the HTTP request timeout if present in the options
        request_timeout = None
        if TIMEOUT_CONFIG_NAME in self.options:
            try:
                request_timeout = float(self.options[TIMEOUT_CONFIG_NAME])
                logging.debug('ProxyAdapter request timeout set to %f secs', request_timeout)
            except ValueError:
                logging.error(
                    "Illegal timeout specified for ProxyAdapter: %s",
                    self.options[TIMEOUT_CONFIG_NAME]
                    )

        # Parse the list of target-URL pairs from the options, instantiating a ProxyTarget
        # object for each target specified.
        self.targets = []
        if TARGET_CONFIG_NAME in self.options:
            for target_str in self.options[TARGET_CONFIG_NAME].split(','):
                try:
                    (target, url) = target_str.split('=')
                    self.targets.append(ProxyTarget(target.strip(), url.strip(), request_timeout))
                except ValueError:
                    logging.error("Illegal target specification for ProxyAdapter: %s",
                                  target_str.strip())

        # Issue an error message if no targets were loaded
        if self.targets:
            logging.debug("ProxyAdapter with {:d} targets loaded".format(len(self.targets)))
        else:
            logging.error("Failed to resolve targets for ProxyAdapter")

        # Construct the parameter tree returned by this adapter
        tree = {'status': {}}
        for target in self.targets:
            tree['status'][target.name] = target.status_param_tree
            tree[target.name] = target.data_param_tree

        self.param_tree = ParameterTree(tree)
예제 #7
0
    def test_mutable_nested_tree_in_immutable_tree(self, test_tree_mutable):

        new_tree = ParameterTree({
            'immutable_param': "Hello",
            "nest": {
                "tree": test_tree_mutable.param_tree
            }
        })

        new_node = {"new": 65}
        path = 'nest/tree/extra'
        new_tree.set(path, new_node)
        val = new_tree.get(path)
        assert val['extra'] == new_node
예제 #8
0
    def __init__(self):
        # param tree thats set to mutable, with some nodes i guess?
        # make sure to test the different types of node being added/overwritten (inc param-accessor)
        self.read_value = 64
        self.write_value = "test"

        self.param_tree_dict = {
            'extra': 'wibble',
            'bonus': 'win',
            'nest': {
                'double_nest': {
                    'nested_val': 125,
                    'dont_touch': "let me stay!",
                    'write': (self.get_write, self.set_write)
                },
                'list': [0, 1, {
                    'list_test': "test"
                }, 3]
            },
            'read': (self.get_read, ),
            'empty': {}
        }

        self.param_tree = ParameterTree(self.param_tree_dict)
        self.param_tree.mutable = True
예제 #9
0
    def test_bad_tuple_node_raises_error(self):

        bad_node = 'bad'
        bad_data = tuple(range(4))
        bad_tree = {bad_node: bad_data}
        with assert_raises_regexp(ParameterTreeError, "not a valid leaf node"):
            tree = ParameterTree(bad_tree)
예제 #10
0
    def __init__(self, *args, **kwargs):
        """Initilise the QuadData instance.

        This constructor initialises the QuadData instance. If an existing Quad instance
        is passed in as a keyword argument, that is used for accessing data, otherwise
        a new instance is created.

        :param args: positional arguments to be passed if creating a new Quad
        :param kwargs: keyword arguments to be passed if creating a new Quad, or if
        a quad key is present, that is used as an existing quad object instance
        """
        # Is a quad has been passed in keyword arguments use that, otherwise create a new one
        if 'quad' in kwargs:
            self.quad = kwargs['quad']
        else:
            self.quad = Quad(*args, **kwargs)

        # Create data containers for all channels on the quad
        self.channels = [
            ChannelData(self.quad, i) for i in range(self.quad.num_channels)
        ]

        # Build the parameter tree
        self.param_tree = ParameterTree({
            "channels": [
                self.channels[0].param_tree, self.channels[1].param_tree,
                self.channels[2].param_tree, self.channels[3].param_tree
            ],
            "supply": (self.get_supply_voltage, None),
        })
예제 #11
0
    def setup_class(cls):

        cls.int_rw_param = 100
        cls.float_ro_param = 4.6593
        cls.int_ro_param = 1000
        cls.int_enum_param = 0
        cls.int_enum_param_allowed_values = [0, 1, 2, 3, 5, 8, 13]

        cls.int_rw_param_metadata = {
            "min": 0,
            "max": 1000,
            "units": "arbitrary",
            "name": "intCallableRwParam",
            "description": "A callable integer RW parameter"
        }

        cls.metadata_tree_dict = {
            'name':
            'Metadata Tree',
            'description':
            'A paramter tree to test metadata',
            'floatRoParam': (cls.floatRoParamGet, ),
            'intRoParam': (cls.intRoParamGet, {
                "units": "seconds"
            }),
            'intCallableRwParam':
            (cls.intCallableRwParamGet, cls.intCallableRwParamSet,
             cls.int_rw_param_metadata),
            'intEnumParam': (0, {
                "allowed_values":
                cls.int_enum_param_allowed_values
            }),
            'valueParam': (24601, )
        }
        cls.metadata_tree = ParameterTree(cls.metadata_tree_dict)
예제 #12
0
    def __init__(self,
                 fem_id,
                 host_addr,
                 port,
                 data_addr=None,
                 fem=None,
                 state=STATE_DISCONNECTED):

        self.fem_id = fem_id
        self.host_addr = host_addr
        self.port = port
        self.data_addr = data_addr if data_addr is not None else self.DEFAULT_DATA_ADDR
        self.fem = fem
        self.set_chip_enable(self.DEFAULT_CHIP_ENABLE_MASK)

        self.state = self.STATE_DISCONNECTED
        self.connected = False
        self.error_code = FEM_RTN_OK
        self.error_msg = ""
        self.timeout_ms = self.DEFAULT_TIMEOUT_MS

        self.param_tree = ParameterTree({
            'id': (self._get('fem_id'), None),
            'address': (self._get('host_addr'), None),
            'port': (self._get('port'), None),
            'data_address': (self._get('data_addr'), None),
            'timeout_ms': (self._get('timeout_ms'), None),
            'chip_enable_mask': (self._get('chip_enable_mask'), None),
            'chips_enabled': (self._get('chips_enabled'), None),
            'state': (self._get('state'), None),
            'connected': (self._get('connected'), None),
            'error_code': (self._get('error_code'), None),
            'error_msg': (self._get("error_msg"), None),
        })
예제 #13
0
    def __init__(self):
        """Initialise the SystemInfo object.

        This constructor initlialises the SystemInfo object, extracting various system-level
        parameters and storing them in a parameter tree to be accessible to clients.
        """
        # Store initialisation time
        self.init_time = time.time()

        # Get package version information
        version_info = get_versions()

        # Extract platform information and store in parameter tree
        (system, node, release, version, machine, processor) = platform.uname()
        platform_tree = ParameterTree({
            'system': system,
            'node': node,
            'release': release,
            'version': version,
            'processor': processor
        })

        # Store all information in a parameter tree
        self.param_tree = ParameterTree({
            'odin_version': version_info['version'],
            'tornado_version': tornado.version,
            'platform': platform_tree,
            'server_uptime': (self.get_server_uptime, None),
        })
예제 #14
0
    def __init__(self, name, endpoint, drop_warn_cutoff, callback):
        """
        Initialise a Node for the Adapter. The node should subscribe to
        a ZMQ socket and pass any frames received at that socket to the main
        adapter.
        """
        logging.debug("Live View Proxy Node Initialising: %s", endpoint)
        self.name = name
        self.endpoint = endpoint
        self.callback = callback
        self.dropped_frame_count = 0
        self.received_frame_count = 0
        self.last_frame = 0
        self.current_acq = 0
        self.drop_warn_cutoff = drop_warn_cutoff
        self.drop_unwarn_cutoff = drop_warn_cutoff * 0.75
        self.has_warned = False
        # subscribe to the given socket address.
        self.channel = IpcTornadoChannel(IpcTornadoChannel.CHANNEL_TYPE_SUB,
                                         endpoint=endpoint)
        self.channel.subscribe()
        self.channel.connect()
        # callback is called whenever data 'arrives' at the socket. This is driven by the IOLoop
        self.channel.register_callback(self.local_callback)

        self.param_tree = ParameterTree({
            'endpoint': (lambda: self.endpoint, None),
            'dropped_frames': (lambda: self.dropped_frame_count, None),
            'received_frames': (lambda: self.received_frame_count, None),
            'last_frame': (lambda: self.last_frame, None),
            'current_acquisition': (lambda: self.current_acq, None),
        })

        logging.debug("Proxy Connected to Socket: %s", endpoint)
예제 #15
0
    def test_mutable_nested_tree_root_tree_not_affected(
            self, test_tree_mutable):

        new_tree = ParameterTree({
            'immutable_param': "Hello",
            "nest": {
                "tree": test_tree_mutable.param_tree
            }
        })

        new_node = {"new": 65}
        path = 'immutable_param'

        with pytest.raises(ParameterTreeError) as excinfo:
            new_tree.set(path, new_node)

        assert "Type mismatch" in str(excinfo.value)
예제 #16
0
    def setup_class(cls):

        cls.int_value = 1234
        cls.float_value = 3.1415
        cls.bool_value = True
        cls.str_value = 'theString'
        cls.list_values = list(range(4))

        cls.simple_dict = {
            'intParam': cls.int_value,
            'floatParam': cls.float_value,
            'boolParam': cls.bool_value,
            'strParam': cls.str_value,
        }

        cls.simple_tree = ParameterTree(cls.simple_dict)

        # Set up nested dict of parameters for a more complex tree
        cls.nested_dict = cls.simple_dict.copy()
        cls.nested_dict['branch'] = {
            'branchIntParam': 4567,
            'branchStrParam': 'theBranch',
        }
        cls.nested_tree = ParameterTree(cls.nested_dict)

        cls.callback_tree = deepcopy(cls.nested_tree)
        cls.callback_tree.add_callback('branch/', cls.branch_callback)

        cls.branch_callback_count = 0

        cls.complex_tree_branch = ParameterTree(deepcopy(cls.nested_dict))
        cls.complex_tree_branch.add_callback('', cls.branch_callback)

        cls.complex_tree = ParameterTree({
            'intParam':
            cls.int_value,
            'callableRoParam': (lambda: cls.int_value, None),
            'listParam':
            cls.list_values,
            'branch':
            cls.complex_tree_branch,
        })

        cls.list_tree = ParameterTree(
            {'main': [cls.simple_dict.copy(),
                      list(cls.list_values)]})
예제 #17
0
    def __init__(self, file_name, file_dir):
        self.file_dir = file_dir
        self.file_name = file_name
        self.vector_loop_position = 0
        self.vector_length = 0
        self.vector_names = []
        self.vector_data = []

        self.dac_clock_refs = []
        self.dac_data_vector = []

        self.bias = {}

        self.clock_step = 0

        self.get_vector_information()
        self.extract_clock_references()
        self.convert_raw_dac_data()

        self.bias_tree = ParameterTree(
            # dict comprehension, like a one-line for loop
            # basically, for each bias, create a tuple of partial functions
            # that get/set values from the dictionary
            {
                bias_name: (
                    partial(self.get_bias_val, bias_name),
                    partial(self.set_bias_val, bias_name),
                    # metadata ensures the bias val can't go over its 6 bit max
                    {
                        "min": 0,
                        "max": (2**self.BIAS_DEPTH) - 1
                    })
                for bias_name in self.bias.keys()
            })

        self.param_tree = ParameterTree({
            "bias":
            self.bias_tree,
            "file_name": (lambda: self.file_name, self.set_file_name),
            "file_dir": (lambda: self.file_dir, None),
            "length": (lambda: self.vector_length, None),
            "loop_pos": (lambda: self.vector_loop_position, None),
            "save": (None, self.write_vector_file),
            "reset": (None, self.reset_vector_file)
        })
    def test_bad_tuple_node_raises_error(self, test_param_tree):
        """Test that constructing a parameter tree with an immutable tuple raises an error."""
        bad_node = 'bad'
        bad_data = tuple(range(4))
        bad_tree = {bad_node: bad_data}
        with pytest.raises(ParameterTreeError) as excinfo:
            tree = ParameterTree(bad_tree)

        assert "not a valid leaf node" in str(excinfo.value)
예제 #19
0
    def test_mutable_nested_tree_delete(self, test_tree_mutable):

        new_tree = ParameterTree({
            'immutable_param': "Hello",
            "tree": test_tree_mutable.param_tree
        })

        path = 'tree/bonus'
        new_tree.delete(path)

        tree = new_tree.get('')

        assert 'bonus' not in tree['tree']

        with pytest.raises(ParameterTreeError) as excinfo:
            test_tree_mutable.param_tree.get(path)

        assert "Invalid path" in str(excinfo.value)
예제 #20
0
    def __init__(self, background_task_enable, background_task_interval):
        """Initialise the Workshop object.

        This constructor initlialises the Workshop object, building a parameter tree and
        launching a background task if enabled
        """
        # Save arguments
        self.background_task_enable = background_task_enable
        self.background_task_interval = background_task_interval

        # Store initialisation time
        self.init_time = time.time()

        # Get package version information
        version_info = get_versions()

        # Build a parameter tree for the background task
        bg_task = ParameterTree({
            'count': (lambda: self.background_task_counter, None),
            'enable':
            (lambda: self.background_task_enable, self.set_task_enable),
            'interval':
            (lambda: self.background_task_interval, self.set_task_interval),
        })

        # Store all information in a parameter tree
        self.param_tree = ParameterTree({
            'odin_version':
            version_info['version'],
            'tornado_version':
            tornado.version,
            'server_uptime': (self.get_server_uptime, None),
            'background_task':
            bg_task
        })

        # Set the background task counter to zero
        self.background_task_counter = 0

        # Launch the background task if enabled in options
        if self.background_task_enable:
            logging.debug("Launching background task with interval %.2f secs",
                          background_task_interval)
            self.background_task()
예제 #21
0
    def __init__(self, name, url, request_timeout):
        """
        Initialise the BaseProxyTarget object.

        Sets up the default state of the base target object, builds the appropriate parameter tree
        to be handled by the containing adapter and sets up the HTTP client for making requests
        to the target.

        :param name: name of the proxy target
        :param url: URL of the remote target
        :param request_timeout: request timeout in seconds
        """
        self.name = name
        self.url = url
        self.request_timeout = request_timeout

        # Initialise default state
        self.status_code = 0
        self.error_string = 'OK'
        self.last_update = 'unknown'
        self.data = {}
        self.metadata = {}
        self.counter = 0

        # Build a parameter tree representation of the proxy target status
        self.status_param_tree = ParameterTree({
            'url': (lambda: self.url, None),
            'status_code': (lambda: self.status_code, None),
            'error': (lambda: self.error_string, None),
            'last_update': (lambda: self.last_update, None),
        })

        # Build a parameter tree representation of the proxy target data
        self.data_param_tree = ParameterTree((lambda: self.data, None))
        self.meta_param_tree = ParameterTree((lambda: self.metadata, None))

        # Set up default request headers
        self.request_headers = {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
        }
예제 #22
0
class SystemInfo(with_metaclass(Singleton, object)):
    """SystemInfo - class that extracts and stores information about system-level parameters."""

    # __metaclass__ = Singleton

    def __init__(self):
        """Initialise the SystemInfo object.

        This constructor initlialises the SystemInfo object, extracting various system-level
        parameters and storing them in a parameter tree to be accessible to clients.
        """
        # Store initialisation time
        self.init_time = time.time()

        # Get package version information
        version_info = get_versions()

        # Extract platform information and store in parameter tree
        (system, node, release, version, machine, processor) = platform.uname()
        platform_tree = ParameterTree({
            'system': system,
            'node': node,
            'release': release,
            'version': version,
            'processor': processor
        })

        # Store all information in a parameter tree
        self.param_tree = ParameterTree({
            'odin_version':
            version_info['version'],
            'tornado_version':
            tornado.version,
            'platform':
            platform_tree,
            'server_uptime': (self.get_server_uptime, None),
        })

    def get_server_uptime(self):
        """Get the uptime for the ODIN server.

        This method returns the current uptime for the ODIN server.
        """
        return time.time() - self.init_time

    def get(self, path):
        """Get the parameter tree.

        This method returns the parameter tree for use by clients via the SystemInfo adapter.

        :param path: path to retrieve from tree
        """
        return self.param_tree.get(path)
예제 #23
0
    def __init__(self, name, url, request_timeout):
        """
        Initalise the ProxyTarget object.

        Sets up the default state of the target object, builds the
        appropriate parameter tree to be handled by the containing adapter
        and sets up the HTTP client for making requests to the target.
        """
        self.name = name
        self.url = url
        self.request_timeout = request_timeout

        # Initialise default state
        self.status_code = 0
        self.error_string = 'OK'
        self.last_update = 'unknown'
        self.data = {}
        self.metadata = {}
        self.counter = 0

        # Build a parameter tree representation of the proxy target status
        self.status_param_tree = ParameterTree({
            'url': (lambda: self.url, None),
            'status_code': (lambda: self.status_code, None),
            'error': (lambda: self.error_string, None),
            'last_update': (lambda: self.last_update, None),
        })

        # Build a parameter tree representation of the proxy target data
        self.data_param_tree = ParameterTree((lambda: self.data, None))
        self.meta_param_tree = ParameterTree((lambda: self.metadata, None))

        # Create an HTTP client instance and set up default request headers
        self.http_client = tornado.httpclient.HTTPClient()
        self.request_headers = {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
        }
        self.remote_get()  # init the data tree
        self.remote_get(get_metadata=True)  # init the metadata
예제 #24
0
class ProxyTestHandler(RequestHandler):
    """ Tornado request handler for use in test server needed for proxy tests."""

    # Data structure served by request handler
    data = {
        'one':
        (1,
         None),  # this allows for auto generated metadata for testing purposes
        'two': 2.0,
        'pi': 3.14,
        'more': {
            'three': 3.0,
            'replace': 'Replace Me!',
            'even_more': {
                'extra_val': 5.5
            }
        }
    }
    param_tree = ParameterTree(data)

    def initialize(self, server):
        """Increment the server access count every time the request handler is invoked."""
        server.access_count += 1

    def get(self, path=''):
        """Handle GET requests to the test server."""
        try:
            data_ref = self.param_tree.get(path, wants_metadata(self.request))
            self.write(data_ref)
        except ParameterTreeError:
            self.set_status(404)
            self.write_error(404)
        except Exception as other_e:
            logging.error("ProxyTestHandler GET failed: %s", str(other_e))
            self.write_error(500)

    def put(self, path):
        """Handle PUT requests to the test server."""
        response_body = convert_unicode_to_string(
            tornado.escape.json_decode(self.request.body))
        try:
            self.param_tree.set(path, response_body)
            data_ref = self.param_tree.get(path)

            self.write(data_ref)
        except ParameterTreeError:
            self.set_status(404)
            self.write_error(404)
        except Exception as other_e:
            logging.error("ProxyTestHandler PUT failed: %s", str(other_e))
            self.write_error(500)
예제 #25
0
class SystemInfo(with_metaclass(Singleton, object)):
    """SystemInfo - class that extracts and stores information about system-level parameters."""

    # __metaclass__ = Singleton

    def __init__(self):
        """Initialise the SystemInfo object.

        This constructor initlialises the SystemInfo object, extracting various system-level
        parameters and storing them in a parameter tree to be accessible to clients.
        """
        # Store initialisation time
        self.init_time = time.time()

        # Get package version information
        version_info = get_versions()

        # Extract platform information and store in parameter tree
        (system, node, release, version, machine, processor) = platform.uname()
        platform_tree = ParameterTree({
            'system': system,
            'node': node,
            'release': release,
            'version': version,
            'processor': processor
        })

        # Store all information in a parameter tree
        self.param_tree = ParameterTree({
            'odin_version': version_info['version'],
            'tornado_version': tornado.version,
            'platform': platform_tree,
            'server_uptime': (self.get_server_uptime, None),
        })

    def get_server_uptime(self):
        """Get the uptime for the ODIN server.

        This method returns the current uptime for the ODIN server.
        """
        return time.time() - self.init_time

    def get(self, path):
        """Get the parameter tree.

        This method returns the parameter tree for use by clients via the SystemInfo adapter.

        :param path: path to retrieve from tree
        """
        return self.param_tree.get(path)
    def __init__(self):

        self.int_value = 1234
        self.float_value = 3.1415
        self.bool_value = True
        self.str_value = 'theString'
        self.list_values = list(range(4))

        self.simple_dict = {
            'intParam': self.int_value,
            'floatParam': self.float_value,
            'boolParam': self.bool_value,
            'strParam': self.str_value,
        }

        self.accessor_params = {'one': 1, 'two': 2, 'pi': 3.14}
        self.simple_tree = ParameterTree(self.simple_dict)

        # Set up nested dict of parameters for a more complex tree
        self.nested_dict = self.simple_dict.copy()
        self.nested_dict['branch'] = {
            'branchIntParam': 4567,
            'branchStrParam': 'theBranch',
        }
        self.nested_tree = ParameterTree(self.nested_dict)

        self.callback_tree = deepcopy(self.nested_tree)
        self.callback_tree.add_callback('branch/', self.branch_callback)

        self.branch_callback_count = 0

        self.complex_tree_branch = ParameterTree(deepcopy(self.nested_dict))
        self.complex_tree_branch.add_callback('', self.branch_callback)

        self.complex_tree = ParameterTree({
            'intParam':
            self.int_value,
            'callableRoParam': (lambda: self.int_value, None),
            'callableAccessorParam': (self.get_accessor_param, None),
            'listParam':
            self.list_values,
            'branch':
            self.complex_tree_branch,
        })

        self.list_tree = ParameterTree(
            {'main': [self.simple_dict.copy(),
                      list(self.list_values)]})

        self.simple_list_tree = ParameterTree({'list_param': [10, 11, 12, 13]})
예제 #27
0
    def __init__(self, save_file_dir="", save_file_name="", odin_data_dir=""):
        self.adapters = {}
        # self.data_config_dir = config_dir
        # self.fr_config_file = ""
        # self.fp_config_file = ""
        self.file_dir = save_file_dir
        self.file_name = save_file_name
        self.odin_data_dir = odin_data_dir

        self.in_progress = False

        # these varables used to tell when an acquisiton is completed
        self.frame_start_acquisition = 0  # number of frames received at start of acq
        self.frame_end_acquisition = 0  # number of frames at end of acq (start + acq number)

        logging.debug("ODIN DATA DIRECTORY: %s", self.odin_data_dir)
        self.process_list = {}
        self.file_writing = False
        self.config_dir = ""
        self.config_files = {
            "fp": "",
            "fr": ""
        }
        self.param_tree = ParameterTree({
            "receiver": {
                "connected": (self.is_fr_connected, None),
                "configured": (self.is_fr_configured, None),
                "config_file": (self.get_fr_config_file, None)
            },
            "processor": {
                "connected": (self.is_fp_connected, None),
                "configured": (self.is_fp_configured, None),
                "config_file": (self.get_fp_config_file, None)
            },
            "file_info": {
                "enabled": (lambda: self.file_writing, self.set_file_writing),
                "file_name": (lambda: self.file_name, self.set_file_name),
                "file_dir": (lambda: self.file_dir, self.set_data_dir)
            },
            "in_progress": (lambda: self.in_progress, None)
        })
예제 #28
0
    def __init__(self, coarse_calibration_value, fems, daq):
        self.coarse_calibration_value = coarse_calibration_value
        self.qem_fems = fems
        self.qem_daq = daq

        self.max_calibration = 4096
        self.min_calibration = 0
        self.calibration_step = 1

        self.calibration_value = 0

        self.param_tree = ParameterTree({
            "start_calibrate": (None, self.adc_calibrate),
            "start_plot": (None, self.adc_plot),
            "calibration_vals": {
                "max": (lambda: self.max_calibration, self.set_max_calib),
                "min": (lambda: self.min_calibration, self.set_min_calib),
                "step": (lambda: self.calibration_step, self.set_calib_step),
                "current": (lambda: self.calibration_value, None)
            }
        })
예제 #29
0
    def __init__(self, quad, channel_idx):
        """Initialise the data container for a Quad channel.

        This constructor initialises the data container for a LPD Quad output
        channel, creating the parameter tree and associating it with a specified
        quad and channel.

        :param quad: the quad box for this channel
        :param channel_idx: channel index on the specified quad.
        """
        self.quad = quad
        self.channel_idx = channel_idx

        self.param_tree = ParameterTree({
            "voltage": (self.get_voltage, None),
            "current": (self.get_current, None),
            "fusevoltage": (self.get_fuse, None),
            "fuseblown": (self.get_fuse_blown, None),
            "fetfailed": (self.get_fet_failed, None),
            "enabled": (self.get_enable, self.set_enable),
        })
예제 #30
0
    def __init__(self, name, url, request_timeout):
        """
        Initalise the ProxyTarget object.

        Sets up the default state of the target object, builds the
        appropriate parameter tree to be handled by the containing adapter
        and sets up the HTTP client for making requests to the target.
        """
        self.name = name
        self.url = url
        self.request_timeout = request_timeout

        # Initialise default state
        self.status_code = 0
        self.error_string = 'OK'
        self.last_update = 'unknown'
        self.data = {}
        self.counter = 0

        # Build a parameter tree representation of the proxy target status
        self.status_param_tree = ParameterTree({
            'url': (self._get_url, None),
            'status_code': (self._get_status_code, None),
            'error': (self._get_error_string, None),
            'last_update': (self._get_last_update, None),
        })

        # Build a parameter tree representation of the proxy target data
        self.data_param_tree = ParameterTree((self._get_data, None))

        # Create an HTTP client instance and set up default request headers
        self.http_client = tornado.httpclient.HTTPClient()
        self.request_headers = {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
        }

        self.remote_get()  # init the data tree
    def __init__(self):

        self.int_rw_param = 100
        self.float_ro_param = 4.6593
        self.int_ro_param = 1000
        self.int_enum_param = 0
        self.int_enum_param_allowed_values = [0, 1, 2, 3, 5, 8, 13]

        self.int_rw_param_metadata = {
            "min": 0,
            "max": 1000,
            "units": "arbitrary",
            "name": "intCallableRwParam",
            "description": "A callable integer RW parameter"
        }

        self.metadata_tree_dict = {
            'name':
            'Metadata Tree',
            'description':
            'A paramter tree to test metadata',
            'floatRoParam': (self.floatRoParamGet, ),
            'intRoParam': (self.intRoParamGet, {
                "units": "seconds"
            }),
            'intCallableRwParam':
            (self.intCallableRwParamGet, self.intCallableRwParamSet,
             self.int_rw_param_metadata),
            'intEnumParam': (0, {
                "allowed_values":
                self.int_enum_param_allowed_values
            }),
            'valueParam': (24601, ),
            'minNoMaxParam': (1, {
                'min': 0
            })
        }
        self.metadata_tree = ParameterTree(self.metadata_tree_dict)
예제 #32
0
    def __init__(self, pscu, sensor_idx):
        """Initialise the temperature data container for a sensor.

        This constructor initalises the data container for a temperature
        sensor, creating the parameter tree and associating it with a
        particular sensor on the PSCU.

        :param pscu: PSCU object to use to access the sensor
        :param sensor_idx: sensor index on PSCU
        """
        self.param_tree = ParameterTree({
            "temperature": (self.get_temperature, None),
            "temperature_volts": (self.get_temperature_volts, None),
            "setpoint": (self.get_set_point, None),
            "setpoint_volts": (self.get_set_point_volts, None),
            "tripped": (self.get_tripped, None),
            "trace": (self.get_trace, None),
            "disabled": (self.get_disabled, None),
            "name": (self.get_name, None),
            'mode': (self.get_mode, None),
        })

        self.pscu = pscu
        self.sensor_idx = sensor_idx
예제 #33
0
class ProxyTarget(object):
    """
    Proxy adapter target class.

    This class implements a proxy target, its parameter tree and associated
    status information for use in the ProxyAdapter.
    """

    def __init__(self, name, url, request_timeout):
        """
        Initalise the ProxyTarget object.

        Sets up the default state of the target object, builds the
        appropriate parameter tree to be handled by the containing adapter
        and sets up the HTTP client for making requests to the target.
        """
        self.name = name
        self.url = url
        self.request_timeout = request_timeout

        # Initialise default state
        self.status_code = 0
        self.error_string = 'OK'
        self.last_update = 'unknown'
        self.data = {}
        self.counter = 0

        # Build a parameter tree representation of the proxy target status
        self.status_param_tree = ParameterTree({
            'url': (self._get_url, None),
            'status_code': (self._get_status_code, None),
            'error': (self._get_error_string, None),
            'last_update': (self._get_last_update, None),
        })

        # Build a parameter tree representation of the proxy target data
        self.data_param_tree = ParameterTree((self._get_data, None))

        # Create an HTTP client instance and set up default request headers
        self.http_client = tornado.httpclient.HTTPClient()
        self.request_headers = {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
        }

        self.remote_get()  # init the data tree

    def update(self, request, path):
        """
        Update the Proxy Target `ParameterTree` with data from the proxied adapter,
        after issuing a GET or a PUT request to it. It also updates the status code
        and error string if the HTTP request fails.
        """

        try:
            # Request data to/from the target
            response = self.http_client.fetch(request)

            # Update status code and data accordingly
            self.status_code = response.code
            self.error_string = 'OK'
            response_body = tornado.escape.json_decode(response.body)

        except tornado.httpclient.HTTPError as http_err:
            # Handle HTTP errors, updating status information and reporting error
            self.status_code = http_err.code
            self.error_string = http_err.message
            logging.error(
                "Proxy target %s fetch failed: %d %s",
                self.name,
                self.status_code,
                self.error_string
                )
            self.last_update = tornado.httputil.format_timestamp(time.time())
            return

        except IOError as other_err:
            self.status_code = 502
            self.error_string = str(other_err)
            logging.error(
                "Proxy target %s fetch failed: %d %s",
                self.name,
                self.status_code,
                self.error_string
                )
            self.last_update = tornado.httputil.format_timestamp(time.time())
            return

        data_ref = self.data  # reference for modification
        if path:
            # if the path exists, we need to split it so we can navigate the data
            path_elems = path.split('/')
            if path_elems[-1] == '':  # remove empty string caused by trailing slashes
                del path_elems[-1]
            for elem in path_elems[:-1]:
                # for each element, traverse down the data tree
                data_ref = data_ref[elem]

        for key in response_body:
            new_elem = response_body[key]
            data_ref[key] = new_elem
        logging.debug(
            "Proxy target %s fetch succeeded: %d %s",
            self.name,
            self.status_code,
            self.data_param_tree.get(path)
            )

        # Update the timestamp of the last request in standard format
        self.last_update = tornado.httputil.format_timestamp(time.time())

    def remote_get(self, path=''):
        """
        Get data from the remote target.

        This method updates the local proxy target with new data by
        issuing a GET request to the target URL, and then updates the proxy
        target data and status information according to the response.
        """

        # create request to PUT data, send to the target
        request = tornado.httpclient.HTTPRequest(
            url=self.url + path,
            method="GET",
            headers=self.request_headers,
            request_timeout=self.request_timeout
        )
        self.update(request, path)

    def remote_set(self, path, data):
        """
        Set data on the remote target.

        This method updates the local proxy target with new datat by
        issuing a PUT request to the target URL, and then updates the proxy
        target data and status information according to the response.
        """
        # create request to PUT data, send to the target
        request = tornado.httpclient.HTTPRequest(
            url=self.url + path,
            method="PUT",
            body=data,
            headers=self.request_headers,
            request_timeout=self.request_timeout
        )
        self.update(request, path)

    def _get_status_code(self):
        """
        Get the target request status code.

        This internal method is used to retrieve the status code
        of the last target update request for use in the parameter
        tree.
        """
        return self.status_code

    def _get_error_string(self):
        """
        Get the target request error string.

        This internal method is used to retrieve the error string
        of the last target update request for use in the parameter
        tree.
        """
        return self.error_string

    def _get_last_update(self):
        """
        Get the target request last update timestamp.

        This internal method is used to retrieve the timestamp
        of the last target update request for use in the parameter
        tree.
        """
        return self.last_update

    def _get_data(self):
        """
        Get the target request data.

        This internal method is used to retrieve the target updated during last call to update(),
        for use in the parameter tree.
        """
        return self.data

    def _get_url(self):
        return self.url
예제 #34
0
    def initialise_proxy(self, proxy_target_cls):
        """
        Initialise the proxy.

        This method initialises the proxy. The adapter options are parsed to determine the list
        of proxy targets and request timeout, then a proxy target of the specified class is created
        for each target. The data, metadata and status structures and parameter trees associated
        with each target are created.

        :param proxy_target_cls: proxy target class appropriate for the specific implementation
        """
        # Set the HTTP request timeout if present in the options
        request_timeout = None
        if self.TIMEOUT_CONFIG_NAME in self.options:
            try:
                request_timeout = float(self.options[self.TIMEOUT_CONFIG_NAME])
                logging.debug('Proxy adapter request timeout set to %f secs', request_timeout)
            except ValueError:
                logging.error(
                    "Illegal timeout specified for proxy adapter: %s",
                    self.options[self.TIMEOUT_CONFIG_NAME]
                )

        # Parse the list of target-URL pairs from the options, instantiating a proxy target of the
        # specified type for each target specified.
        self.targets = []
        if self.TARGET_CONFIG_NAME in self.options:
            for target_str in self.options[self.TARGET_CONFIG_NAME].split(','):
                try:
                    (target, url) = target_str.split('=')
                    self.targets.append(
                        proxy_target_cls(target.strip(), url.strip(), request_timeout)
                    )
                except ValueError:
                    logging.error("Illegal target specification for proxy adapter: %s",
                                  target_str.strip())

        # Issue an error message if no targets were loaded
        if self.targets:
            logging.debug("Proxy adapter with {:d} targets loaded".format(len(self.targets)))
        else:
            logging.error("Failed to resolve targets for proxy adapter")

        # Build the parameter trees implemented by this adapter for the specified proxy targets
        status_dict = {}
        tree = {}
        meta_tree = {}

        for target in self.targets:
            status_dict[target.name] = target.status_param_tree
            tree[target.name] = target.data_param_tree
            meta_tree[target.name] = target.meta_param_tree

        # Create a parameter tree from the status data for the targets and insert into the
        # data and metadata structures
        self.status_tree = ParameterTree(status_dict)
        tree['status'] = self.status_tree
        meta_tree['status'] = self.status_tree.get("", True)

        # Create the data and metadata parameter trees
        self.param_tree = ParameterTree(tree)
        self.meta_param_tree = ParameterTree(meta_tree)
예제 #35
0
class ProxyAdapter(ApiAdapter):
    """
    Proxy adapter class for ODIN server.

    This class implements a proxy adapter, allowing ODIN server to forward requests to
    other HTTP services.
    """

    def __init__(self, **kwargs):
        """
        Initialise the ProxyAdapter.

        This constructor initialises the adapter instance, parsing configuration
        options out of the keyword arguments it is passed. A ProxyTarget object is
        instantiated for each target specified in the options.

         :param kwargs: keyword arguments specifying options
        """

        # Initialise base class
        super(ProxyAdapter, self).__init__(**kwargs)

        # Set the HTTP request timeout if present in the options
        request_timeout = None
        if TIMEOUT_CONFIG_NAME in self.options:
            try:
                request_timeout = float(self.options[TIMEOUT_CONFIG_NAME])
                logging.debug('ProxyAdapter request timeout set to %f secs', request_timeout)
            except ValueError:
                logging.error(
                    "Illegal timeout specified for ProxyAdapter: %s",
                    self.options[TIMEOUT_CONFIG_NAME]
                    )

        # Parse the list of target-URL pairs from the options, instantiating a ProxyTarget
        # object for each target specified.
        self.targets = []
        if TARGET_CONFIG_NAME in self.options:
            for target_str in self.options[TARGET_CONFIG_NAME].split(','):
                try:
                    (target, url) = target_str.split('=')
                    self.targets.append(ProxyTarget(target.strip(), url.strip(), request_timeout))
                except ValueError:
                    logging.error("Illegal target specification for ProxyAdapter: %s",
                                  target_str.strip())

        # Issue an error message if no targets were loaded
        if self.targets:
            logging.debug("ProxyAdapter with {:d} targets loaded".format(len(self.targets)))
        else:
            logging.error("Failed to resolve targets for ProxyAdapter")

        # Construct the parameter tree returned by this adapter
        tree = {'status': {}}
        for target in self.targets:
            tree['status'][target.name] = target.status_param_tree
            tree[target.name] = target.data_param_tree

        self.param_tree = ParameterTree(tree)

    @request_types('application/json')
    @response_types('application/json', default='application/json')
    def get(self, path, request):
        """
        Handle an HTTP GET request.

        This method handles an HTTP GET request, returning a JSON response.

        :param path: URI path of request
        :param request: HTTP request object
        :return: an ApiAdapterResponse object containing the appropriate response
        """
        # Update the target specified in the path, or all targets if none specified
        if "/" in path:
            path_elem, target_path = path.split('/', 1)
        else:
            path_elem = path
            target_path = ""
        for target in self.targets:
            if path_elem == '' or path_elem == target.name:
                target.remote_get(target_path)

        # Build the response from the adapter parameter tree
        try:
            response = self.param_tree.get(path)
            status_code = 200
        except ParameterTreeError as param_tree_err:
            response = {'error': str(param_tree_err)}
            status_code = 400

        return ApiAdapterResponse(response, status_code=status_code)

    @request_types("application/json", "application/vnd.odin-native")
    @response_types('application/json', default='application/json')
    def put(self, path, request):
        """
        Handle an HTTP PUT request.

        This method handles an HTTP PUT request, returning a JSON response.

        :param path: URI path of request
        :param request: HTTP request object
        :return: an ApiAdapterResponse object containing the appropriate response
        """
        # Update the target specified in the path, or all targets if none specified

        try:
            json_decode(request.body)  # ensure request body is JSON. Will throw a TypeError if not
            if "/" in path:
                path_elem, target_path = path.split('/', 1)
            else:
                path_elem = path
                target_path = ""
            for target in self.targets:
                if path_elem == '' or path_elem == target.name:
                    target.remote_set(target_path, request.body)
            response = self.param_tree.get(path)
            status_code = 200
        except ParameterTreeError as param_tree_err:
            response = {'error': str(param_tree_err)}
            status_code = 400
        except (TypeError, ValueError) as type_val_err:
            response = {'error': 'Failed to decode PUT request body: {}'.format(str(type_val_err))}
            status_code = 415

        return ApiAdapterResponse(response, status_code=status_code)
예제 #36
0
    def __init__(self):
        """Initialise the SystemInfo object.

        This constructor initlialises the SystemInfo object, extracting various system-level
        parameters and storing them in a parameter tree to be accessible to clients.
        """
        # Store initialisation time
        self.init_time = time.time()

        # Get package version information
        version_info = get_versions()

        # Extract platform information and store in parameter tree
        (system, node, release, version, _, processor) = platform.uname()
        platform_tree = ParameterTree({
            'name': 'platform',
            'description': "Information about the underlying platform",
            'system': (lambda: system, {
                "name": "system",
                "description": "operating system name",
            }),
            'node': (lambda: node, {
                "name": "node",
                "description": "node (host) name",
            }),
            'release': (lambda: release, {
                "name": "release",
                "description": "operating system release",
            }),
            'version': (lambda: version, {
                "name": "version",
                "description": "operating system version",
            }),
            'processor': (lambda: processor, {
                "name": "processor",
                "description": "processor (CPU) name",
            }),
        })

        # Store all information in a parameter tree
        self.param_tree = ParameterTree({
            'name': 'system_info',
            'description': 'Information about the system hosting this odin server instance',
            'odin_version': (lambda: version_info['version'], {
                "name": "odin version",
                "description": "ODIN server version",
            }),
            'tornado_version': (lambda: tornado.version, {
                "name": "tornado version",
                "description": "version of tornado used in this server",
            }),
            'python_version': (lambda: platform.python_version(), {
                "name": "python version",
                "description": "version of python running this server",
            }),
            'platform': platform_tree,
            'server_uptime': (self.get_server_uptime, {
                "name": "server uptime",
                "description": "time since the ODIN server started",
                "units": "s",
                "display_precision": 2,
            }),
        })
예제 #37
0
class SystemInfo(with_metaclass(Singleton, object)):
    """SystemInfo - class that extracts and stores information about system-level parameters."""

    # __metaclass__ = Singleton

    def __init__(self):
        """Initialise the SystemInfo object.

        This constructor initlialises the SystemInfo object, extracting various system-level
        parameters and storing them in a parameter tree to be accessible to clients.
        """
        # Store initialisation time
        self.init_time = time.time()

        # Get package version information
        version_info = get_versions()

        # Extract platform information and store in parameter tree
        (system, node, release, version, _, processor) = platform.uname()
        platform_tree = ParameterTree({
            'name': 'platform',
            'description': "Information about the underlying platform",
            'system': (lambda: system, {
                "name": "system",
                "description": "operating system name",
            }),
            'node': (lambda: node, {
                "name": "node",
                "description": "node (host) name",
            }),
            'release': (lambda: release, {
                "name": "release",
                "description": "operating system release",
            }),
            'version': (lambda: version, {
                "name": "version",
                "description": "operating system version",
            }),
            'processor': (lambda: processor, {
                "name": "processor",
                "description": "processor (CPU) name",
            }),
        })

        # Store all information in a parameter tree
        self.param_tree = ParameterTree({
            'name': 'system_info',
            'description': 'Information about the system hosting this odin server instance',
            'odin_version': (lambda: version_info['version'], {
                "name": "odin version",
                "description": "ODIN server version",
            }),
            'tornado_version': (lambda: tornado.version, {
                "name": "tornado version",
                "description": "version of tornado used in this server",
            }),
            'python_version': (lambda: platform.python_version(), {
                "name": "python version",
                "description": "version of python running this server",
            }),
            'platform': platform_tree,
            'server_uptime': (self.get_server_uptime, {
                "name": "server uptime",
                "description": "time since the ODIN server started",
                "units": "s",
                "display_precision": 2,
            }),
        })

    def get_server_uptime(self):
        """Get the uptime for the ODIN server.

        This method returns the current uptime for the ODIN server.
        """
        return time.time() - self.init_time

    def get(self, path, with_metadata=False):
        """Get the parameter tree.

        This method returns the parameter tree for use by clients via the SystemInfo adapter.

        :param path: path to retrieve from tree
        """
        return self.param_tree.get(path, with_metadata)
예제 #38
0
class PSCUData(object):
    """Data container for a PSCU and associated quads.

    This class implements a data container and parameter tree of a PSCU,
    its assocated quad boxes and all sensors contained therein. A PSCUData
    object, asociated with a PSCU instance, forms the primary interface between,
    and data model for, the adapter and the underlying devices.
    """

    def __init__(self, *args, **kwargs):
        """Initialise the PSCUData instance.

        This constructor initialises the PSCUData instance. If an existing PSCU instance
        is passed in as a keyword argument, that is used for accessing data, otherwise
        a new instance is created.

        :param args: positional arguments to be passed if creating a new PSCU
        :param kwargs: keyword arguments to be passed if creating a new PSCU, or if
        a pscu key is present, that is used as an existing PSCU object instance
        """
        # If a PSCU has been passed in keyword arguments use that, otherwise create a new one
        if 'pscu' in kwargs:
            self.pscu = kwargs['pscu']
        else:
            self.pscu = PSCU(*args, **kwargs)

        # Get the QuadData containers associated with the PSCU
        self.quad_data = [QuadData(quad=q) for q in self.pscu.quad]

        # Get the temperature and humidity containers associated with the PSCU
        self.temperature_data = [
            TempData(self.pscu, i) for i in range(self.pscu.num_temperatures)
        ]
        self.humidity_data = [
            HumidityData(self.pscu, i) for i in range(self.pscu.num_humidities)
        ]

        # Build the parameter tree of the PSCU
        self.param_tree = ParameterTree({
            "quad": {
                "quads": [q.param_tree for q in self.quad_data],
                'trace': (self.get_quad_traces, None),
            },
            "temperature": {
                "sensors": [t.param_tree for t in self.temperature_data],
                "overall": (self.pscu.get_temperature_state,  None),
                "latched": (self.pscu.get_temperature_latched,  None),
            },
            "humidity": {
                "sensors": [h.param_tree for h in self.humidity_data],
                "overall": (self.pscu.get_humidity_state, None),
                "latched": (self.pscu.get_humidity_latched, None),
            },
            "fan": {
                "target": (self.pscu.get_fan_target, self.pscu.set_fan_target),
                "currentspeed_volts": (self.pscu.get_fan_speed_volts, None),
                "currentspeed": (self.pscu.get_fan_speed, None),
                "setpoint": (self.pscu.get_fan_set_point, None),
                "setpoint_volts": (self.pscu.get_fan_set_point_volts, None),
                "tripped": (self.pscu.get_fan_tripped, None),
                "overall": (self.pscu.get_fan_state, None),
                "latched": (self.pscu.get_fan_latched, None),
                "mode": (self.pscu.get_fan_mode, None),
            },
            "pump": {
                "flow": (self.pscu.get_pump_flow, None),
                "flow_volts": (self.pscu.get_pump_flow_volts, None),
                "setpoint": (self.pscu.get_pump_set_point, None),
                "setpoint_volts": (self.pscu.get_pump_set_point_volts, None),
                "tripped": (self.pscu.get_pump_tripped, None),
                "overall": (self.pscu.get_pump_state, None),
                "latched": (self.pscu.get_pump_latched, None),
                "mode": (self.pscu.get_pump_mode, None),
            },
            "trace": {
                 "overall": (self.pscu.get_trace_state, None),
                 "latched": (self.pscu.get_trace_latched,  None),
            },
            "position": (self.pscu.get_position, None),
            "position_volts": (self.pscu.get_position_volts, None),
            "overall": (self.pscu.get_health,  None),
            "latched": (self.get_all_latched, None),
            "armed": (self.pscu.get_armed, self.pscu.set_armed),
            "allEnabled": (self.pscu.get_all_enabled, self.pscu.enable_all),
            "enableInterval": (self.pscu.get_enable_interval, None),
            "displayError": (self.pscu.get_display_error, None),
        })

    def get(self, path):
        """Get parameters from the underlying parameter tree.

        This method simply wraps underlying ParameterTree method so that an exceptions can be
        re-raised with an appropriate PSCUDataError.

        :param path: path of parameter tree to get
        :returns: parameter tree at that path as a dictionary
        """
        try:
            return self.param_tree.get(path)
        except ParameterTreeError as e:
            raise PSCUDataError(e)

    def set(self, path, data):
        """Set parameters in underlying parameter tree.

        This method simply wraps underlying ParameterTree method so that an exceptions can be
        re-raised with an appropriate PSCUDataError.

        :param path: path of parameter tree to set values for
        :param data: dictionary of new data values to set in the parameter tree
        """
        try:
            self.param_tree.set(path, data)
        except ParameterTreeError as e:
            raise PSCUDataError(e)

    def get_all_latched(self):
        """Return the global latch status of the PSCU.

        This method returns the global latch status for the PSCU, which is the logical AND of
        PSCU latch channels

        :returns: global latch status as bool
        """
        return all(self.pscu.get_all_latched())

    def get_quad_traces(self):
        """Return the trace status for the quads in the PSCU.

        This method returns a dictionary of the quad trace status values for the PSCU.

        :returns: dictionary of the quad trace status
        """
        return {str(q): self.pscu.get_quad_trace(q) for q in range(self.pscu.num_quads)}
예제 #39
0
    def __init__(self, *args, **kwargs):
        """Initialise the PSCUData instance.

        This constructor initialises the PSCUData instance. If an existing PSCU instance
        is passed in as a keyword argument, that is used for accessing data, otherwise
        a new instance is created.

        :param args: positional arguments to be passed if creating a new PSCU
        :param kwargs: keyword arguments to be passed if creating a new PSCU, or if
        a pscu key is present, that is used as an existing PSCU object instance
        """
        # If a PSCU has been passed in keyword arguments use that, otherwise create a new one
        if 'pscu' in kwargs:
            self.pscu = kwargs['pscu']
        else:
            self.pscu = PSCU(*args, **kwargs)

        # Get the QuadData containers associated with the PSCU
        self.quad_data = [QuadData(quad=q) for q in self.pscu.quad]

        # Get the temperature and humidity containers associated with the PSCU
        self.temperature_data = [
            TempData(self.pscu, i) for i in range(self.pscu.num_temperatures)
        ]
        self.humidity_data = [
            HumidityData(self.pscu, i) for i in range(self.pscu.num_humidities)
        ]

        # Build the parameter tree of the PSCU
        self.param_tree = ParameterTree({
            "quad": {
                "quads": [q.param_tree for q in self.quad_data],
                'trace': (self.get_quad_traces, None),
            },
            "temperature": {
                "sensors": [t.param_tree for t in self.temperature_data],
                "overall": (self.pscu.get_temperature_state,  None),
                "latched": (self.pscu.get_temperature_latched,  None),
            },
            "humidity": {
                "sensors": [h.param_tree for h in self.humidity_data],
                "overall": (self.pscu.get_humidity_state, None),
                "latched": (self.pscu.get_humidity_latched, None),
            },
            "fan": {
                "target": (self.pscu.get_fan_target, self.pscu.set_fan_target),
                "currentspeed_volts": (self.pscu.get_fan_speed_volts, None),
                "currentspeed": (self.pscu.get_fan_speed, None),
                "setpoint": (self.pscu.get_fan_set_point, None),
                "setpoint_volts": (self.pscu.get_fan_set_point_volts, None),
                "tripped": (self.pscu.get_fan_tripped, None),
                "overall": (self.pscu.get_fan_state, None),
                "latched": (self.pscu.get_fan_latched, None),
                "mode": (self.pscu.get_fan_mode, None),
            },
            "pump": {
                "flow": (self.pscu.get_pump_flow, None),
                "flow_volts": (self.pscu.get_pump_flow_volts, None),
                "setpoint": (self.pscu.get_pump_set_point, None),
                "setpoint_volts": (self.pscu.get_pump_set_point_volts, None),
                "tripped": (self.pscu.get_pump_tripped, None),
                "overall": (self.pscu.get_pump_state, None),
                "latched": (self.pscu.get_pump_latched, None),
                "mode": (self.pscu.get_pump_mode, None),
            },
            "trace": {
                 "overall": (self.pscu.get_trace_state, None),
                 "latched": (self.pscu.get_trace_latched,  None),
            },
            "position": (self.pscu.get_position, None),
            "position_volts": (self.pscu.get_position_volts, None),
            "overall": (self.pscu.get_health,  None),
            "latched": (self.get_all_latched, None),
            "armed": (self.pscu.get_armed, self.pscu.set_armed),
            "allEnabled": (self.pscu.get_all_enabled, self.pscu.enable_all),
            "enableInterval": (self.pscu.get_enable_interval, None),
            "displayError": (self.pscu.get_display_error, None),
        })