def action_startcapture(self, model, tango_dev=None, data_input=None):  # pylint: disable=W0613
        """Triggers the dish to start capturing the data on the configured band.

        :param model: tango_simlib.model.Model
        :param data_input: None
        :raises DevFailed: dishMode is not in any of the allowed modes (OPERATE) or
            configuredBand is (NONE, UNKNOWN, ERROR, UNDEFINED).
        """
        _allowed_modes = ("OPERATE", )
        dish_mode_quantity = model.sim_quantities["dishMode"]
        dish_mode = get_enum_str(dish_mode_quantity)

        if dish_mode in _allowed_modes:
            configuredBand = model.sim_quantities["configuredBand"]
            band_error_labels = ["NONE", "UNKNOWN", "ERROR", "UNDEFINED"]
            if configuredBand in band_error_labels:
                Except.throw_exception(
                    "DISH Command Failed",
                    "configuredBand is {}.".format(configuredBand),
                    "StartCapture()",
                    ErrSeverity.WARN,
                )
            model.sim_quantities["capturing"].set_val(True, model.time_func())
            model.logger.info("Attribute 'capturing' set to True.")
        else:
            self._throw_exception("StartCapture", _allowed_modes)

        model.logger.info("'StartCapture' command executed successfully.")
Esempio n. 2
0
 async def RaiseException(self):
     Except.throw_exception(
         "TestDevice command failed",
         "Something wrong occured.",
         "Do something else",
         ErrSeverity.ERR,
     )
    def _configureband(self, model, band_number):
        _allowed_modes = ("STANDBY_FP", "OPERATE", "STOW")
        ds_indexer_position = model.sim_quantities["dsIndexerPosition"]
        configured_band = model.sim_quantities["configuredBand"]
        dish_mode_quantity = model.sim_quantities["dishMode"]
        dish_mode = get_enum_str(dish_mode_quantity)
        if dish_mode in _allowed_modes:
            set_enum(dish_mode_quantity, "CONFIG", model.time_func())
            model.logger.info(
                "Configuring DISH to operate in frequency band {}.".format(
                    band_number))

            # TODO (p.dube 19-05-2021) Implement sleep in a background thread to allow the
            # dishMode to remain in 'CONFIG' to simulate the real DSH LMC.

            set_enum(ds_indexer_position, "B{}".format(band_number),
                     model.time_func())
            set_enum(configured_band, "B{}".format(band_number),
                     model.time_func())
            model.logger.info(
                "Done configuring DISH to operate in frequency band {}.".
                format(band_number))
            model.logger.info(
                "DISH reverting back to '{}' mode.".format(dish_mode))
            set_enum(dish_mode_quantity, dish_mode, model.time_func())
        else:
            Except.throw_exception(
                "DISH Command Failed",
                "DISH is not in {} mode.".format(_allowed_modes),
                "ConfigureBand{}()".format(band_number),
                ErrSeverity.WARN,
            )
 def _throw_exception(self, command, allowed_modes):
     Except.throw_exception(
         "DISH Command Failed",
         "DISH is not in {} mode.".format(allowed_modes),
         "{}()".format(command),
         ErrSeverity.WARN,
     )
Esempio n. 5
0
 def write_position(self, value):
     self.query('PA' + str(value))
     err = self.get_cmd_error_string()
     if err in self.__ERROR_OUT_OF_RANGE:
         Except.throw_exception('position out of range',
                                'position out of range', 'write_position')
     else:
         self.set_state(DevState.MOVING)
Esempio n. 6
0
def raise_exception(reason, desc, origin, severity=ErrSeverity.ERR):
    """Raise a Tango DevFailed exception.

    :param reason: Reason for the error.
    :param desc: Error description.
    :param origin: Error origin.
    :param severity: Error severity.

    """
    LOG.error("Raising DevFailed exception...")
    LOG.error("Reason: %s", reason)
    LOG.error("Description: %s", desc)
    LOG.error("Origin: %s", origin)
    LOG.error("Severity: %s", severity)
    Except.throw_exception(reason, desc, origin, severity)
Esempio n. 7
0
def validate_input_sizes(command_name, argin):
    """Check the validity of the input parameters passed on to the command specified
    by the command_name parameter.

    Parameters
    ----------
    command_name: str
        The name of the command which is to be executed.
    argin: tango.DevVarLongStringArray
        A tuple of two lists.

    Raises
    ------
    tango.DevFailed: If the two lists are not equal in length.
    """
    capabilities_instances, capability_types = argin
    if len(capabilities_instances) != len(capability_types):
        Except.throw_exception("Command failed!", "Argin value lists size mismatch.",
                               command_name, ErrSeverity.ERR)
 def ensure_within_mechanical_limits(self, next_pos):
     if (next_pos.azim > self.MAX_DESIRED_AZIM
             or next_pos.azim < self.MIN_DESIRED_AZIM):
         Except.throw_exception(
             "Skipping dish movement.",
             "Desired azimuth angle '%s' is out of pointing limits %s." %
             (next_pos.azim, [self.MIN_DESIRED_AZIM, self.MAX_DESIRED_AZIM
                              ]),
             "ensure_within_mechanical_limits()",
             ErrSeverity.WARN,
         )
     elif (next_pos.elev > self.MAX_DESIRED_ELEV
           or next_pos.elev < self.MIN_DESIRED_ELEV):
         Except.throw_exception(
             "Skipping dish movement.",
             "Desired elevation angle '%s' is out of pointing limits %s." %
             (next_pos.elev, [self.MIN_DESIRED_ELEV, self.MAX_DESIRED_ELEV
                              ]),
             "ensure_within_mechanical_limits()",
             ErrSeverity.WARN,
         )
    def action_setoperatemode(self, model, tango_dev=None, data_input=None):  # pylint: disable=W0613
        """This command triggers the Dish to transition to the OPERATE Dish
        Element Mode, and returns to the caller. This mode fulfils the main
        purpose of the Dish, which is to point to designated directions while
        capturing data and transmitting it to CSP.

        :param model: tango_simlib.model.Model
        :param data_input: None
        :raises DevFailed: dishMode is not in any of the allowed modes (STANDBY_FP).
        """
        operate = "OPERATE"
        _allowed_modes = ("STANDBY_FP", )
        dish_mode_quantity = model.sim_quantities["dishMode"]
        dish_mode = get_enum_str(dish_mode_quantity)

        if dish_mode == operate:
            model.logger.info("Dish is already in '%s' mode", operate)
            return

        if dish_mode in _allowed_modes:
            configuredBand = model.sim_quantities["configuredBand"]
            band_error_labels = ["NONE", "UNKNOWN", "ERROR", "UNDEFINED"]
            if configuredBand in band_error_labels:
                Except.throw_exception(
                    "DISH Command Failed",
                    "Configured band is {}.".format(configuredBand),
                    "SetOperateMode()",
                    ErrSeverity.WARN,
                )
            set_enum(dish_mode_quantity, operate, model.time_func())
            model.logger.info("Dish transitioned to the %s Dish Element Mode.",
                              operate)
            pointing_state_quantity = model.sim_quantities["pointingState"]
            set_enum(pointing_state_quantity, "READY", model.time_func())
            model.logger.info("Dish pointing state set to 'READY'.")
        else:
            self._throw_exception("SetOperateMode", _allowed_modes)

        tango_dev.set_state(DevState.ON)
        model.logger.info("Dish state set to 'ON'.")
Esempio n. 10
0
    def _validate_capability_types(self, command_name, capability_types):
        """Check the validity of the input parameter passed on to the command specified
        by the command_name parameter.

        Parameters
        ----------
        command_name: str
            The name of the command which is to be executed.
        capability_types: list
            A list strings representing capability types.

        Raises
        ------
        tango.DevFailed: If any of the capabilities requested are not valid.
        """
        invalid_capabilities = list(
            set(capability_types) - set(self._configured_capabilities))

        if invalid_capabilities:
            Except.throw_exception(
                "Command failed!",
                "Invalid capability types requested {}".format(
                    invalid_capabilities), command_name, ErrSeverity.ERR)
Esempio n. 11
0
    def configure(self, sbi_config_str):
        """Issue an SBI configuration request."""
        # Load the SBI configuration as a dictionary
        try:
            sbi_config = json.loads(sbi_config_str)
        except json.JSONDecodeError as error:
            Except.throw_exception(
                'Unable to decode JSON SBI configuration',
                '{} (position {}, line {}, column {})'.format(
                    error.msg, error.pos, error.lineno,
                    error.colno), 'File "{}", line {}'.format(
                        __file__,
                        inspect.currentframe().f_back.f_lineno))

        # Validate the provided SBI configuration using JSON schema
        try:
            self._validate_sbi_schema(sbi_config)
        except jsonschema.ValidationError as error:
            return self._invalid_sbi_config_response(sbi_config)

        # Check that the SBI (and PBs) are not already registered.
        if sbi_config['id'] in self._sbi_list:
            Except.throw_exception(
                'SBIs must have a unique ID.',
                'SBI with ID "{}" already exists.'.format(sbi_config['id']),
                'File "{}", line {}'.format(
                    __file__,
                    inspect.currentframe().f_back.f_lineno))
        for pb in sbi_config['processing_blocks']:
            if pb['id'] in self._pb_list:
                Except.throw_exception(
                    'PBs must have a unique ID.',
                    'PB with ID "{}" already exists in SBI {}.'.format(
                        pb['id'],
                        self._pb_list[pb['id']]), 'File "{}", line {}'.format(
                            __file__,
                            inspect.currentframe().f_back.f_lineno))

        # Check that the PB workflows are registered.
        # ***

        # Check that there are enough resources
        # ***

        # Check that there are enough PB devices
        # ***

        # Save the data structure in the Configuration database.
        # *** make sure to associate it with the subarray
        self._sbi_list[sbi_config['id']] = sbi_config
        for pb in sbi_config['processing_blocks']:
            self._pb_list[pb['id']] = sbi_config['id']

        # Allocate PB devices
        # ***

        return self._accepted_response(sbi_config['id'])
Esempio n. 12
0
    def _get_cbf_output_link_map(self):
        """Read and validate the CBF output link map.

        This is read from a CSP subarray device attribute.

        """
        # Read the cbfOutputLink attribute.
        configured_scans = [int(scan_id) for scan_id in
                            self._config['scanParameters'].keys()]

        if self.is_feature_active(FeatureToggle.CBF_OUTPUT_LINK):
            cbf_out_link_str = self._read_cbf_output_link()
        else:
            LOG.warning("CBF Output Link feature disabled! Generating mock "
                        "attribute value.")
            cbf_out_link = dict(
                scanID=configured_scans[0],
                fsp=[
                    dict(cbfOutLink=[],
                         fspID=1,
                         frequencySliceID=1)
                ]
            )
            cbf_out_link_str = json.dumps(cbf_out_link)

        # Check the cbfOutputLink map is not empty!
        if not cbf_out_link_str or cbf_out_link_str == json.dumps(dict()):
            message = 'CBF Output Link map is empty!'
            LOG.error(message)
            self._set_obs_state(ObsState.FAULT)
            raise RuntimeError(message)

        # Convert string to dictionary.
        try:
            cbf_output_link = json.loads(cbf_out_link_str)
            LOG.debug('Successfully loaded cbfOutputLinks JSON object as dict')

        except json.JSONDecodeError as error:
            LOG.error('Channel link map JSON load error: %s '
                      '(line %s, column: %s)', error.msg, error.lineno,
                      error.colno)
            self._set_obs_state(ObsState.FAULT)
            raise

        LOG.debug('Validating cbfOutputLinks ...')

        # Validate schema.
        schema_path = join(dirname(__file__), 'schema', 'cbfOutLink.json')
        with open(schema_path, 'r') as file:
            schema = json.loads(file.read())
        try:
            validate(cbf_output_link, schema)
        except exceptions.ValidationError as error:
            frame = getframeinfo(currentframe())
            message = 'cbfOutputLinks validation error: {}, {}'.format(
                error.message, str(error.absolute_path))
            origin = '{}:{}'.format(frame.filename, frame.lineno)
            LOG.error(message)
            Except.throw_exception(message, message, origin)
        LOG.debug('Channel link map validation successful.')

        self._cbf_output_link = cbf_output_link
        return cbf_output_link
Esempio n. 13
0
    def _is_command_allowed(self, command_name):
        """Determine whether the command specified by the command_name parameter should
        be allowed to execute or not.

        Parameters
        ----------
        command_name: str
            The name of the command which is to be executed.

        Returns
        -------
        True or False: boolean
            A True is returned when the device is in the allowed states and modes to
            execute the command. Returns False if the command name is not in the list of
            commands with rules specified for them.

        Raises
        ------
        tango.DevFailed: If the device is not in the allowed states and/modes to
            execute the command.
        """
        dp = DeviceProxy(self.get_name())

        obstate_labels = list(dp.attribute_query('obsState').enum_labels)
        obs_idle = obstate_labels.index('IDLE')
        obs_ready = obstate_labels.index('READY')

        admin_labels = list(dp.attribute_query('adminMode').enum_labels)
        admin_online = admin_labels.index('ON-LINE')
        admin_maintenance = admin_labels.index('MAINTENANCE')
        admin_offline = admin_labels.index('OFF-LINE')
        admin_not_fitted = admin_labels.index('NOT-FITTED')
        current_admin_mode = self.read_adminMode()

        if command_name in ["ReleaseResources", "AssignResources"]:
            if current_admin_mode in [admin_offline, admin_not_fitted]:
                Except.throw_exception(
                    "Command failed!", "Subarray adminMode is"
                    " 'OFF-LINE' or 'NOT-FITTED'.", command_name,
                    ErrSeverity.ERR)

            if self.read_obsState() == obs_idle:
                if current_admin_mode in [admin_online, admin_maintenance]:
                    return True
                else:
                    Except.throw_exception(
                        "Command failed!", "Subarray adminMode not"
                        "'ON-LINE' or not in 'MAINTENANCE'.", command_name,
                        ErrSeverity.ERR)

            else:
                Except.throw_exception("Command failed!",
                                       "Subarray obsState not 'IDLE'.",
                                       command_name, ErrSeverity.ERR)

        elif command_name in [
                'ConfigureCapability', 'DeconfigureCapability',
                'DeconfigureAllCapabilities'
        ]:
            if self.get_state() == DevState.ON and self.read_adminMode(
            ) == admin_online:
                if self.read_obsState() in [obs_idle, obs_ready]:
                    return True
                else:
                    Except.throw_exception(
                        "Command failed!",
                        "Subarray obsState not 'IDLE' or 'READY'.",
                        command_name, ErrSeverity.ERR)
            else:
                Except.throw_exception(
                    "Command failed!",
                    "Subarray State not 'ON' and/or adminMode not"
                    " 'ON-LINE'.", command_name, ErrSeverity.ERR)

        return False