diff --git a/csp-lmc-common/HISTORY b/csp-lmc-common/HISTORY index 9b9265bc9ff6eff76a07e7b2ac7d567ac0106e78..6a524d31f0586623aa32c93f34a9bec3236df6a5 100644 --- a/csp-lmc-common/HISTORY +++ b/csp-lmc-common/HISTORY @@ -1,3 +1,6 @@ +0.7.2 +- Initialization of CSP Subarray align its state ans obsstate to sub-elements. + 0.7.1 - Off command in Subarray drives each sub-element component to the final OFF/EMPTY state. - CspMaster On/Standby commands are executed synchronously diff --git a/csp-lmc-common/csp_lmc_common/CspSubarray.py b/csp-lmc-common/csp_lmc_common/CspSubarray.py index 889ab06c3dad523f432620c2bbf8cb789250d1cc..afde759c76dacd8b51e9d33053213b683169bc68 100644 --- a/csp-lmc-common/csp_lmc_common/CspSubarray.py +++ b/csp-lmc-common/csp_lmc_common/CspSubarray.py @@ -26,7 +26,7 @@ import json # tango imports import tango -from tango import DebugIt +from tango import DebugIt, EnsureOmniThread from tango.server import run from tango.server import Device from tango.server import attribute, command @@ -38,7 +38,7 @@ from tango import AttrWriteType, DeviceProxy from ska.base import SKASubarray, SKASubarrayStateModel #from ska.base import utils from ska.base.commands import ActionCommand, ResultCode -from ska.base.faults import CapabilityValidationError, CommandError +from ska.base.faults import CapabilityValidationError, CommandError,StateModelError from ska.base.control_model import HealthState, AdminMode, ObsState, ObsMode from .utils.cspcommons import CmdExecState from .utils.decorators import transaction_id @@ -47,30 +47,61 @@ from .csp_manage_json import JsonConfiguration # PROTECTED REGION END # // CspSubarray.additionnal_import __all__ = ["CspSubarray", "main"] -''' + class CspSubarrayStateModel(SKASubarrayStateModel): - _subarray_transitions = { - ('READY', 'goto_idle_succeeded'): ( - "IDLE", - lambda self: self._set_obs_state(ObsState.IDLE) - ), - ('READY', 'goto_idle_started'): ("READY",None), - ('READY', 'goto_idle_failed'): ( - "OBSFAULT", - lambda self: self._set_obs_state(ObsState.FAULT) - ), - } - - def __init__(self, dev_state_callback=None): + """ + Implements the state model for the CSP SKASubarray, + This new State Model use automatic transitions of the ObservationStateMachine. + In addition to any transitions added explicitly, a to_«state»() method + is created automatically whenever a state is added to a Machine instance. + This method transitions to the target state no matter which state the machine is currently in. + Automatic transitions are used at the server re-initialization to + align the CSP Subarray with the current state of its + sub-elements. + """ + + def __init__( + self, + logger, + op_state_callback=None, + admin_mode_callback=None, + obs_state_callback=None, + ): """ Initialises the model. Note that this does not imply moving to INIT state. The INIT state is managed by the model itself. + + :param logger: the logger to be used by this state model. + :type logger: a logger that implements the standard library + logger interface + :param op_state_callback: A callback to be called when a + transition implies a change to op state + :type op_state_callback: callable + :param admin_mode_callback: A callback to be called when a + transition causes a change to device admin_mode + :type admin_mode_callback: callable + :param obs_state_callback: A callback to be called when a + transition causes a change to device obs_state + :type obs_state_callback: callable """ super().__init__( - dev_state_callback=dev_state_callback, + logger, + op_state_callback=op_state_callback, + admin_mode_callback=admin_mode_callback, + obs_state_callback=obs_state_callback, ) - self.update_transitions(self._subarray_transitions) -''' + # add direct transition from EMPTY to another observing state. + self._action_breakdown["force_to_idle"] = ("force_to_idle", None) + self._action_breakdown["force_to_empty"] = ("force_to_empty", None) + self._action_breakdown["force_to_ready"] = ("force_to_ready", None) + self._action_breakdown["force_to_aborted"] = ("force_to_aborted", None) + self._action_breakdown["force_to_scanning"] = ("force_to_scanning", None) + # add transtions to the ObservationStateMachine + self._observation_state_machine.add_transition(trigger='force_to_empty', source='*', dest='EMPTY') + self._observation_state_machine.add_transition(trigger='force_to_idle', source='*', dest='IDLE') + self._observation_state_machine.add_transition(trigger='force_to_ready', source='*', dest='READY') + self._observation_state_machine.add_transition(trigger='force_to_scanning', source='*', dest='SCANNING') + self._observation_state_machine.add_transition(trigger='force_to_aborted', source='*', dest='ABORTED') class CspSubarray(SKASubarray): """ @@ -115,6 +146,72 @@ class CspSubarray(SKASubarray): """ + class ForceObsStateTransitionCommand(ActionCommand): + """ + Class to handle the re-initialization of the Device server. + """ + + def __init__(self, target, state_model, logger=None): + """ + Constructor for ForceObsStateTransition. + It's not a TANGO command. + This command in invoked at CSP.LMC Subarray re-initialization. + + :param target: the object that this command acts upon; for + example, the SKASubarray device for which this class + implements the command + :type target: object + :param state_model: the state model that this command uses + to check that it is allowed to run, and that it drives + with actions. + :type state_model: :py:class:`SKASubarrayStateModel` + :param logger: the logger to be used by this Command. If not + provided, then a default module logger will be used. + :type logger: a logger that implements the standard library + logger interface + """ + super().__init__( + target, state_model, "force", start_action=False, logger=logger + ) + self.action = None + + def __call__(self, argin=None): + """ + Override the __call__ method to set the action to execute when the succeeded method + is called. + """ + self.action = argin + super().__call__(argin) + + def check_allowed(self): + """ + check_allowed is invoked before the do() in the command __call__ method. + The basic behavior is to check for a transition named 'force_succeeded'. + At re-initialization there are several 'succeeded' transitions, depending on + the expected observing state of the CSP Subarray, so it's necessary to modify + the succeeded method name with the one stored in the action attribute. + """ + self.logger.info("check for transition trigger {}".format(self.action)) + self._succeeded_hook = self.action + return super().check_allowed() + + def do(self, argin): + self.action = argin + return (ResultCode.OK, f"Executed {argin}") + + def succeeded(self): + """ + Action to take on successful completion of device server + re-initialization. + """ + self.logger.info("Execute succeeded with arg {}".format(self.action)) + if not self.action: + self.logger.info("Action not specified!!") + self.state_model.perform_action(self.action) + + def failed(self): + self.state_model.perform_action("fatal_error") + class InitCommand(SKASubarray.InitCommand): """ A class for the SKASubarray's init_device() "command". @@ -131,6 +228,8 @@ class CspSubarray(SKASubarray): (result_code, message) = super().do() device = self.target + self.logger.info("CspSubarray INIT COMMAND STARTED!!") + self.logger.info("CspSubarray obs_state: {}".format(device._obs_state)) device._build_state = '{}, {}, {}'.format(release.name, release.version, release.description) device._version_id = release.version # connect to CSP.LMC TANGO DB @@ -214,6 +313,7 @@ class CspSubarray(SKASubarray): # keys: the command name('on, 'off'...) # values: thread instance device._command_thread = {} + device._stop_thread = defaultdict(lambda: False) # _end_scan_event: thread event to signal EndScan device._end_scan_event = threading.Event() @@ -308,18 +408,139 @@ class CspSubarray(SKASubarray): #device._reserved_search_beam_num = 0 device._assigned_timing_beams= [] device._assigned_vlbi_beams = [] - - # Try connection with the CBF sub-array - device.connect_to_subarray_subcomponent(device.CbfSubarray) - # Try connection with the PSS sub-array - device.connect_to_subarray_subcomponent(device.PssSubarray) - + device._command_thread['init'] = threading.Thread(target=self.initialize_thread, + name="Thread-Initialization ObsState Alignment", + args=()) + device._command_thread['init'].start() # to use the push model in command_inout_asynch (the one with the callback parameter), # change the global TANGO model to PUSH_CALLBACK. apiutil = tango.ApiUtil.instance() apiutil.set_asynch_cb_sub_model(tango.cb_sub_model.PUSH_CALLBACK) - self.logger.info(message) - return (result_code, message) + return (ResultCode.STARTED, "CSP Subarray Init STARTED") + + def initialize_thread(self): + try: + with EnsureOmniThread(): + self.logger.info("Init thread started") + device = self.target + args = (device, device.state_model, self.logger) + device.force_cmd_obj = device.ForceObsStateTransitionCommand(*args) + on_handler = device.OnCommand(*args) + + # Try connection with the CBF sub-array + device.connect_to_subarray_subcomponent(device.CbfSubarray) + # TODO: add connection to CSPMaster to get information + # on subarrayMembership for PSS, PST and VLBI beams. + # Try connection with the PSS sub-array + device.connect_to_subarray_subcomponent(device.PssSubarray) + # put the device to OFF/EMPTY: no transition is allowed from INIT state + self.succeeded() + if device._sc_subarray_state[device.CbfSubarray] is not DevState.ON: + return + # put the device to ON/EMPTY + on_handler.succeeded() + + # CASE B: CSP is ON + target_obs_state = device.obs_state_evaluator() + if target_obs_state in ['RESOURCING', 'ABORTING', 'CONFIGURING', 'RESETTING','RESTARTING']: + self.logger.info("Still to implement transitional state different from SCANNINNG") + return + #self.monitor_running_command(target_obs_state) + self.logger.info('CSP is already ON. Aligning to Sub-elements...') + device.set_csp_obs_state(target_obs_state) + if target_obs_state == 'SCANNING': + return self.monitor_running_command(target_obs_state) + except Exception as msg: + self.logger.info(f'error in thread: {msg}') + + def monitor_running_command(self, csp_obs_state): + """ + Helper method to monitor the CSP Subarray observing state at re-initialization if + the observing state is in a transitional state. + NOTE: Currently onlt the SCANNING obsState is handled. + + :param csp_obs_state: the CSP.LMC Subarray observing state. + :type csp_obs_state: string + """ + device = self.target + if csp_obs_state == 'SCANNING': + args = (device, device.state_model, self.logger) + handler = device.ScanCommand(*args) + device._command_thread['scan'] = threading.Thread(target=handler.monitor_scan_execution, + name="Thread-Scan", + args=(device._sc_subarray_fqdn,)) + device._cmd_execution_state['scan'] = CmdExecState.RUNNING + self.logger.info("Start scan thread") + device._command_thread['scan'].start() + + def obs_state_evaluator(self): + """ + Helper method to evaluate the CSP Subarray observing state starting from the + SCM values of its components. + Criteria: If any one of the componts is in a transitional state, the CSP subarray + assumeis that value + If components are in a steady observing state, the values must be equal + otherwise the CSP Subarray is set in FAULT. + A component not ONLINE/MAINTENANCE does not contribute to the observing + state value. + + :return: The observing state. + :rtype: string with the observing state name. + """ + target_obs_state = 'FAULT' + obs_states_list = [] + allowed_coupled = {'RESOURCING': 'IDLE', + 'RESOURCING': 'EMPTY', + 'CONFIGURING': 'READY', + 'SCANNING': 'READY', + 'ABORTING': 'ABORTED', + 'RESETTING': 'IDLE', + 'RESTARTING': 'EMPTY' + } + transitional_states = allowed_coupled.keys() + for fqdn in self._sc_subarray_fqdn: + self.logger.info("fqdn {} admin mode: {}".format(fqdn, self._sc_subarray_admin_mode[fqdn])) + if self._sc_subarray_admin_mode[fqdn] not in [AdminMode.ONLINE, + AdminMode.MAINTENANCE + ]: + continue + obs_state_name = ObsState(self._sc_subarray_obs_state[fqdn]).name + obs_states_list.append(obs_state_name) + self.logger.info("obs_state_evaluator: {}".format(obs_states_list)) + # first creates an intersection list + transitional_present = set(transitional_states) & set(obs_states_list) + self.logger.info("transitional_present: {}".format(transitional_present)) + # CASE 1: Transitional states NOT present + if not transitional_present: + # CASE 1.1: All obsStates are EQUAL + if len(set(obs_states_list)) == 1: + target_obs_state = obs_states_list[0] + else: + state =list(transitional_present)[0] + for sub_elt_obs_state in obs_states_list: + if sub_elt_obs_state is not (state or allowed_coupled[state]): + break + # CASE 2.2: Other obs_states are ALLOWED + else: + target_obs_state = state + self.logger.info("Evaluated CSP Subarray obsState: {}".format(target_obs_state)) + # CASE 1: Transitional states NOT present + return target_obs_state + + def set_csp_obs_state(self, state): + """ + Set the Subarray observing state to the specified value. + + :param state: The target observing state value + :type state: string + :return: None + """ + try: + if state == 'FAULT': + self.force_cmd_obj.failed() + self.force_cmd_obj(f"force_to_{state.lower()}") + except StateModelError as state_error: + self.logger.warning(state_error) class OnCommand(SKASubarray.OnCommand): def do(self): @@ -442,6 +663,7 @@ class CspSubarray(SKASubarray): # the dictionary with the scan configuration + self.logger.info("ConfigureCommand at {}".format(time.time())) target_device = self.target try: # if the stored configuration attribute is not empty, check @@ -594,9 +816,10 @@ class CspSubarray(SKASubarray): device_done = defaultdict(lambda:False) # inside the end-less lop check the obsState of each sub-component device_list = input_arg[0] + self.logger.info("Trhead started at {}".format(time.time())) while True: if target_device._abort_obs_event.is_set(): - self.logger.info("Received and ABORT request during configuration") + self.logger.info("Received and ABORT request during configuration {}".format(time.time())) command_progress = 0 for device in device_list: self.logger.info("Current device {} obsState is {}".format(device, @@ -619,8 +842,9 @@ class CspSubarray(SKASubarray): target_device._reconfiguring)) if target_device._sc_subarray_obs_state[device] == dev_successful_state: if not target_device._reconfiguring: - self.logger.info("Command {} ended with success on device {}.".format(cmd_name, - device)) + self.logger.info("Command {} ended with success on device {} at {}.".format(cmd_name, + device, + time.time())) # update the list and number of device that completed the task target_device._num_dev_completed_task[cmd_name] += 1 target_device._list_dev_completed_task[cmd_name].append(device) @@ -665,7 +889,7 @@ class CspSubarray(SKASubarray): self.logger.info("device {} is in {}: reconfiguring is:{}".format(device, ObsState(target_device._sc_subarray_obs_state[device]).name, target_device._reconfiguring)) if all(value == True for value in device_done.values()): - self.logger.info("All devices have been handled!") + self.logger.info("All devices have been handled at time {}!".format(time.time())) break # check for global timeout expiration # may be this check is not necessary @@ -679,6 +903,7 @@ class CspSubarray(SKASubarray): # end of the while loop # acquire the mutex during the check of configuration success/failure. We don't want # to receive an boart during this phase otherwise could happen strange situation + self.logger.info("GOING To lock mutex at {}".format(time.time())) with target_device._mutex_obs_state: # check for timeout/failure conditions on each sub-component if any(target_device._sc_subarray_cmd_exec_state[device][cmd_name] == CmdExecState.TIMEOUT for device in device_list): @@ -694,8 +919,8 @@ class CspSubarray(SKASubarray): self.logger.info("CspSubarray timeout flag:{}".format(target_device._timeout_expired)) if target_device._abort_obs_event.is_set(): if target_device._timeout_expired or target_device._failure_raised: - return target_device.abort_cmd_obj.failed() - self.logger.info("Abort configure ends with success!!") + return self.failed() + self.logger.info("Abort configure ends with success!! {}".format(time.time())) if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.ABORTED for fqdn in device_list): return target_device.abort_cmd_obj.succeeded() return target_device.abort_cmd_obj.abort_monitoring(device_list) @@ -704,16 +929,16 @@ class CspSubarray(SKASubarray): # if failure/timeout found check if the CBF subarray is configured. In # this case the CSP.LMC Subarray obsState is set to READY. if target_device._sc_subarray_obs_state[target_device.CbfSubarray] == ObsState.READY: - return target_device.configure_cmd_obj.succeeded() + return self.succeeded() self.logger.info("Configure ends with failure") - return target_device.configure_cmd_obj.failed() + return self.failed() if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.READY for fqdn in device_list): target_device._valid_scan_configuration = input_arg[1] target_device._cmd_duration_measured[cmd_name] = time.time() - command_start_time target_device._cmd_progress[cmd_name] = 100 target_device._last_executed_command = cmd_name - self.logger.info("Configure ends with success!!") - return target_device.configure_cmd_obj.succeeded() + self.logger.info("Configure ends with success!! {}".format(time.time())) + return self.succeeded() def validate_scan_configuration(self, argin): """ @@ -790,13 +1015,17 @@ class CspSubarray(SKASubarray): target_device._command_thread['scan'] = threading.Thread(target=self.monitor_scan_execution, name="Thread-Scan", args=(target_device._sc_subarray_assigned_fqdn,)) + self.logger.info("Thread scan: {}".format(target_device._command_thread['scan'])) target_device._cmd_execution_state['scan'] = CmdExecState.RUNNING target_device._command_thread['scan'].start() return (ResultCode.STARTED, "Scan command started") def monitor_scan_execution(self, device_list): + self.logger.info("Starting scan thread") cmd_name = 'scan' target_device = self.target + target_device._end_scan_event.clear() + target_device._abort_obs_event.clear() dev_successful_state = ObsState.READY target_device._num_dev_completed_task[cmd_name] = 0 target_device._list_dev_completed_task[cmd_name] = [] @@ -812,12 +1041,14 @@ class CspSubarray(SKASubarray): elapsed_time = 0 starting_time = time.time() stop_scan = False - target_device._end_scan_event.clear() - target_device._abort_obs_event.clear() # inside the end-less loop check the obsState of each sub-component while True: - self.logger.info("abort:{}".format(target_device._abort_obs_event.is_set())) - self.logger.info("end:{}".format(target_device._end_scan_event.is_set())) + #self.logger.info("abort:{}".format(target_device._abort_obs_event.is_set())) + #self.logger.info("end:{}".format(target_device._end_scan_event.is_set())) + if target_device._stop_thread[cmd_name]: + target_device._stop_thread[cmd_name] = False + self.logger.info("STOPPING THE THREAD!!!") + return if target_device._end_scan_event.is_set() or target_device._abort_obs_event.is_set(): if not stop_scan: stop_scan = True @@ -857,7 +1088,6 @@ class CspSubarray(SKASubarray): def do(self): target_device = self.target device_list = target_device._sc_subarray_assigned_fqdn - self.logger.info("EndScan assigned_fqdn: {}".format(device_list)) if not any(target_device._sc_subarray_assigned_fqdn): # need to add a check also on PSTBeams belonging to subarray device_list = target_device._sc_subarray_fqdn @@ -876,7 +1106,7 @@ class CspSubarray(SKASubarray): self.logger.error("device {}: {}-{}".format(reply.dev_name(), err.desc, err.reason)) else: (result_code,msg) = reply.get_data() - self.logger.error("device {}: {}".format(reply.dev_name(), msg)) + self.logger.info("device {}: {}".format(reply.dev_name(), msg)) if any(target_device._sc_subarray_obs_state[device]== ObsState.FAULT for device in device_list): return (ResultCode.FAILED, "EndScan Command FAILED") return (ResultCode.OK, "EndScan command executed OK") @@ -930,6 +1160,10 @@ class CspSubarray(SKASubarray): device_done = defaultdict(lambda:False) # inside the end-less loop check the obsState of each sub-component while True: + if target_device._stop_thread[cmd_name]: + target_device._stop_thread[cmd_name] = False + self.logger.info("STOPPING THE THREAD!!!") + return time.sleep(0.1) for device in device_list: if device_done[device] == True: @@ -959,13 +1193,13 @@ class CspSubarray(SKASubarray): # end of the while loop # check for timeout/failure conditions on each sub-component if target_device._failure_raised or target_device._timeout_expired: - return target_device.obsreset_cmd_obj.failed() + return self.failed() if all(target_device._sc_subarray_obs_state[fqdn] == dev_successful_state for fqdn in device_list): target_device._cmd_progress[cmd_name] = 100 target_device._last_executed_command = cmd_name self.logger.info("ObsReset ends with success") - return target_device.obsreset_cmd_obj.succeeded() + return self.succeeded() class AbortCommand(SKASubarray.AbortCommand): @@ -1040,13 +1274,13 @@ class CspSubarray(SKASubarray): # end of the while loop # check for timeout/failure conditions on each sub-component if target_device._failure_raised or target_device._timeout_expired: - return target_device.abort_cmd_obj.failed() + return self.failed() if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.ABORTED for fqdn in device_list): target_device._cmd_progress[cmd_name] = 100 target_device._last_executed_command = cmd_name self.logger.info("Abort ends with success") - return target_device.abort_cmd_obj.succeeded() + return self.succeeded() class RestartCommand(SKASubarray.RestartCommand): @@ -1089,6 +1323,10 @@ class CspSubarray(SKASubarray): elapsed_time = 0 starting_time = time.time() while True: + if target_device._stop_thread[cmd_name]: + target_device._stop_thread[cmd_name] = False + self.logger.info("STOPPING THE THREAD!!!") + return for device in device_list: if device_done[device] == True: continue @@ -1123,216 +1361,14 @@ class CspSubarray(SKASubarray): # end of the while loop # check for timeout/failure conditions on each sub-component if target_device._failure_raised or target_device._timeout_expired: - return target_device.restart_cmd_obj.failed() + return self.failed() if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.EMPTY for fqdn in device_list): target_device._cmd_progress[cmd_name] = 100 target_device._last_executed_command = cmd_name self.logger.info("Restart ends with success") - return target_device.restart_cmd_obj.succeeded() - - ''' - class GoToIdleCommand(ActionCommand): - """ - A class for the CSPSubarray's GoToIdle() command. - """ - def __init__(self, target, state_model, logger=None): - super().__init__( - target, state_model, "goto_idle", start_action=True, logger=logger - ) - def do(self): - """ - Stateless hook for GoToIdle() command functionality. - - :return: A tuple containing a return code and a string - message indicating status. The message is for - information purpose only. - :rtype: (ResultCode, str) - """ - target_device = self.target - device_list = target_device._sc_subarray_assigned_fqdn - if not any(target_device._sc_subarray_assigned_fqdn): - # need to add a check also on PSTBeams belonging to subarray - device_list = target_device._sc_subarray_fqdn - for device in device_list: - # TODO: check if the device is running - # set to 3 sec. the duration expected - target_device._sc_subarray_cmd_duration_expected[device]['gotoidle'] = 3 - target_device._cmd_duration_expected['gotoidle'] - try: - proxy = target_device._sc_subarray_proxies[device] - # register the starting time for the command - target_device._sc_subarray_cmd_starting_time[device] = time.time() - target_device._timeout_expired = False - target_device._failure_raised = False - proxy.command_inout_asynch("GoToIdle", target_device._cmd_ended_cb) - # read the timeout attribute configured for this command - # if not implemented an AttributeError exception is thrown - # and the default value is used - target_device._sc_subarray_cmd_duration_expected[device]['gotoidle'] = proxy.gotoIdleCmdDurationExpected - except KeyError as key_err: - msg = "GoToIdle execution:no key {} found".format(str(key_err)) - self.logger.warning(msg) - return (ResultCode.FAILED, msg) - except tango.DevFailed as tango_err: - msg = "GotToIdle execution: {}".format(tango_err.args[0].desc) - self.logger.warning(msg) - return (ResultCode.FAILED, msg) - except AttributeError as attr_err: - self.logger.info("Attribute {} not exported by device {}".format(str(attr_err), - device)) - target_device._sc_subarray_cmd_exec_state[device]['gotoidle'] = CmdExecState.RUNNING - if target_device._sc_subarray_cmd_duration_expected[device]['gotoidle'] > target_device._cmd_duration_expected['gotoidle']: - target_device._cmd_duration_expected['gotoidle'] = target_device._sc_subarray_cmd_duration_expected[device]['gotoidle'] - # invoke the constructor for the command thread - target_device._command_thread['gotoidle'] = threading.Thread(target=self._gotoidle, - name="Thread-GotoIdle", - args=(target_device._sc_subarray_assigned_fqdn,)) - target_device._cmd_execution_state['gotoidle'] = CmdExecState.RUNNING - target_device._command_thread['gotoidle'].start() - # sleep for a while to let the thread start - #time.sleep(0.2) - # TODO: - # add some check on command exeuction: end state has to be IDLE for each - # sub-array sub-component - message = "GoToIdle command STARTED" - self.logger.info(message) - return (ResultCode.STARTED, message) + return self.succeeded() - def _gotoidle(self, device_list, **args_dict): - """ - Thread target function invoked from GoToIdle method. - It monitors the obsState value of each sub-array sub-component - looking for timeout or failure conditions. - - :param device_list: the FQDNs of the sub-array sub-components - - :return: None - """ - target_device = self.target - cmd_name = 'gotoidle' - dev_successful_state = ObsState.IDLE - # tango_cmd_name: is the TANGO command name with the capital letter - # In the dictionary keys, is generally used the command name in lower letters - target_device._num_dev_completed_task[cmd_name] = 0 - target_device._list_dev_completed_task[cmd_name] = [] - target_device._cmd_progress[cmd_name] = 0 - target_device._cmd_duration_measured[cmd_name] = 0 - # sub-component command execution measured time - sc_cmd_duration_measured = defaultdict(lambda:defaultdict(lambda:0)) - # loop on the devices and issue asynchrnously the Configure command - command_progress = target_device._cmd_progress[cmd_name] - # flag to signal when configuration ends on a sub-array sub-component - device_done = defaultdict(lambda:False) - # inside the end-less lop check the obsState of each sub-component - while True: - for device in device_list: - elapsed_time = time.time() - target_device._sc_subarray_cmd_starting_time[device] - sc_cmd_duration_measured[device][cmd_name] = elapsed_time - self.logger.debug("Command {} obs_state: {}".format(cmd_name, - target_device._sc_subarray_obs_state[device])) - if device_done[device] == True: - continue - # if the sub-component execution flag is no more RUNNING, the command has - # ended with or without success. Go to check next device state. - if target_device._sc_subarray_obs_state[device] == dev_successful_state: - self.logger.info("Command {} ended with success on device {}.".format(cmd_name, - device)) - # update the list and number of device that completed the task - target_device._num_dev_completed_task[cmd_name] += 1 - target_device._list_dev_completed_task[cmd_name].append(device) - # reset the value of the attribute reporting the execution state of - # the command - target_device._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.IDLE - target_device._sc_subarray_cmd_progress[device][cmd_name] = 100 - # calculate the execution time for the command as the max value of all the execution times - if sc_cmd_duration_measured[device][cmd_name] >= target_device._cmd_duration_measured[cmd_name]: - target_device._cmd_duration_measured[cmd_name] = sc_cmd_duration_measured[device][cmd_name] - # command success: step to next device - device_done[device] = True - # check for timeout event. A timeout event can be detected in two ways: - # 1- the sub-element implements the 'onTimeoutExpired' attribute configured - # for change event - # 2- the CspMaster periodically checks the time elapsed from the start - # of the command: if the value is greater than the sub-element expected time - # for command execution, the sub-element command execution state is set - # to TIMEOUT - # Note: the second check, can be useful if the timeout event is not received - # (for example for a temporary connection timeout) - #elapsed_time = time.time() - self._sc_subarray_cmd_starting_time[device] - #sc_cmd_duration_measured[device][cmd_name] = elapsed_time - if (elapsed_time > target_device._sc_subarray_cmd_duration_expected[device][cmd_name] or - target_device._sc_subarray_cmd_exec_state[device][cmd_name] == CmdExecState.TIMEOUT): - msg = ("Timeout executing {} command on device {}".format(cmd_name, device)) - self.logger.warning(msg) - target_device._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.TIMEOUT - device_done[device] = True - self.logger.info("elapsed_time:{} device {}".format(elapsed_time, device)) - # check if sub-element command ended throwing an exception: in this case the - # 'cmd_ended_cb' callback is invoked. - if target_device._sc_subarray_cmd_exec_state[device][cmd_name] == CmdExecState.FAILED: - # execution ended for this sub-element, skip to the next one - device_done[device] = True - # update the progress counter inside the loop taking into account the number of devices - # executing the command - target_device._cmd_progress[cmd_name] = command_progress+ target_device._sc_subarray_cmd_progress[device][cmd_name]/len(device_list) - self.logger.debug("Command {} on device {} obsState {}:".format(cmd_name,device, - target_device._sc_subarray_cmd_exec_state[device][cmd_name])) - if all(value == True for value in device_done.values()): - self.logger.info("All devices have been handled!") - break - self.logger.info("Sleeping...") - time.sleep(0.1) - # end of the while loop - # check for timeout/failure conditions on each sub-component - for device in device_list: - self.logger.info("Device {} running state is : {}".format(device, - target_device._sc_subarray_cmd_exec_state[device][cmd_name])) - if target_device._sc_subarray_cmd_exec_state[device][cmd_name] == CmdExecState.TIMEOUT: - target_device._timeout_expired = True - if target_device._sc_subarray_cmd_exec_state[device][cmd_name] == CmdExecState.FAILED: - target_device._failure_raised = True - # reset sub-component execution flag - # update the progress counter at the end of the loop - target_device._cmd_progress[cmd_name] = command_progress + target_device._sc_subarray_cmd_progress[device][cmd_name]/len(device_list) - - self.logger.info("1") - target_device._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.IDLE - if target_device._failure_raised or target_device._timeout_expired: - return target_device.gotoidle_cmd_obj.failed() - - self.logger.info("2") - if all(target_device._sc_subarray_obs_state[fqdn] == dev_successful_state for fqdn in device_list): - target_device._last_executed_command = cmd_name - # reset the CSP Subarray command execution flag - target_device._cmd_execution_state[cmd_name] = CmdExecState.IDLE - return target_device.gotoidle_cmd_obj.succeeded() - - def check_allowed(self): - """ - Whether this command is allowed to be run in current device - state - - :return: True if this command is allowed to be run in - current device state - :rtype: boolean - :raises: DevFailed if this command is not allowed to be run - in current device state - """ - if self.state_model.dev_state == DevState.ON: - return True - msg = "GoToIdle not allowed in State {}".format(self.state_model.dev_state) - tango.Except.throw_exception("API_CommandFailed", - msg, - "GoToIdle", - tango.ErrSeverity.ERR) - #if not self.state_model.obs_state in [ObsState.READY]: - # msg = "GoToIdle not allowed in obsState {}".format(self.state_model.obs_state) - # tango.Except.throw_exception("API_CommandFailed", - # msg, - # "GoToIdle", - # tango.ErrSeverity.ERR) - ''' class GoToIdleCommand(SKASubarray.EndCommand): def do(self): target_device = self.target @@ -1440,9 +1476,9 @@ class CspSubarray(SKASubarray): self.logger.info(log_msg) # update CSP sub-array SCM #07-2020: with the new base classes, transitions are handled via actions. - #if evt.attr_value.name.lower() in ["state", "healthstate", "adminmode", "obsstate"]: + #if evt.attr_value.name.lower() in ["obsstate"]: # self.update_subarray_state() - if evt.attr_value.name.lower() == "healthstate": + if evt.attr_value.name.lower() in ["healthstate"]: self._update_subarray_health_state() except tango.DevFailed as df: self.logger.error(str(df.args[0].desc)) @@ -1585,33 +1621,21 @@ class CspSubarray(SKASubarray): Class protected method. Retrieve the State attribute values of the CSP sub-elements and aggregate them to build up the CSP global state. + This method should be called only when no command is running. :param: None - :return: None """ + self.logger.info("update_subarray_state") self._update_subarray_health_state() - - if self._command_thread: - a = [self._command_thread[cmd_name].is_alive() for cmd_name in self._command_thread.keys()] - self.logger.info("list of running threds:{}".format(a)) - if any(self._command_thread[cmd_name].is_alive() for cmd_name in self._command_thread.keys()): - self.logger.info("A command is already running...the obsState is not updated") - return False - # CSP state reflects the status of CBF. Only if CBF is present - # CSP can work. The state of PSS and PST sub-elements only contributes - # to determine the CSP health state. - if self._sc_subarray_state[self.CbfSubarray] == DevState.OFF: - if self._sc_subarray_obs_state[self.CbfSubarray] == ObsState.EMPTY: - self.off_cmd_obj.succeeded() - if self._sc_subarray_state[self.CbfSubarray] == DevState.ON: - if self._sc_subarray_obs_state[self.CbfSubarray] == ObsState.EMPTY: - self.on_cmd_obj.succeeded() - if self._sc_subarray_obs_state[self.CbfSubarray] == ObsState.READY: - self.configure_cmd_obj.succeeded() - #self.set_state(self._sc_subarray_state[self.CbfSubarray]) - #self.logger.info("Csp subarray state: {} obsState: {}".format(self.get_state(), self.state_model._obs_state)) - return True + # check if a long-running command is in execution + for key, thread in self._command_thread.items(): + if thread.is_alive(): + self.logger.info("Tread {} is running".format(key)) + return + target_obs_state = self.obs_state_evaluator() + if target_obs_state != self._obs_state: + self.set_csp_obs_state(target_obs_state) def _update_subarray_health_state(self): """ @@ -1838,30 +1862,31 @@ class CspSubarray(SKASubarray): # ---------------- # Class private methods # ---------------- - ''' + def _init_state_model(self): """ Sets up the state model for the device """ self.state_model = CspSubarrayStateModel( - dev_state_callback=self._update_state, + logger=self.logger, + op_state_callback=self._update_state, + admin_mode_callback=self._update_admin_mode, + obs_state_callback=self._update_obs_state, ) - ''' + def init_command_objects(self): """ - Sets up the command objects + Sets up the command objects. + The init_command_method is called after InitCommand in the + SKABaseDevice class. + This means that the command object handler has to be defined into + the InitCommandClass. """ super().init_command_objects() args = (self, self.state_model, self.logger) - self.configure_cmd_obj = self.ConfigureCommand(*args) - self.off_cmd_obj = self.OffCommand(*args) - self.on_cmd_obj = self.OnCommand(*args) - self.scan_cmd_obj = self.ScanCommand(*args) self.gotoidle_cmd_obj = self.GoToIdleCommand(*args) - self.obsreset_cmd_obj = self.ObsResetCommand(*args) self.abort_cmd_obj = self.AbortCommand(*args) - self.restart_cmd_obj = self.RestartCommand(*args) self.register_command_object("GoToIdle", self.GoToIdleCommand(*args)) self.register_command_object("Configure", self.ConfigureCommand(*args)) self.register_command_object("Scan", self.ScanCommand(*args)) @@ -2321,6 +2346,12 @@ class CspSubarray(SKASubarray): """ # PROTECTED REGION ID(CspSubarray.delete_device) ENABLED START # #release the allocated event resources + # check for running threads and stop them + for key, thread in self._command_thread.items(): + is_alive = thread.is_alive() + if is_alive: + self._stop_thread[key] = True + thread.join() event_to_remove = {} for fqdn in self._sc_subarray_fqdn: try: @@ -2844,6 +2875,7 @@ class CspSubarray(SKASubarray): :return:'DevVarLongStringArray' """ + self.logger.info("CALL ABORT at time {}".format(time.time())) with self._mutex_obs_state: handler = self.get_command_object("Abort") (result_code, message) = handler() diff --git a/csp-lmc-common/csp_lmc_common/release.py b/csp-lmc-common/csp_lmc_common/release.py index 45a477e4f9c7b206dddd4769966b30dcdc33b0e9..e47259389b92953d45e9eb68cc3fb68381b17628 100755 --- a/csp-lmc-common/csp_lmc_common/release.py +++ b/csp-lmc-common/csp_lmc_common/release.py @@ -10,7 +10,7 @@ """Release information for Python Package""" name = """csp-lmc-common""" -version = "0.7.1" +version = "0.7.2" version_info = version.split(".") description = """SKA CSP.LMC Common Software""" author = "INAF-OAA" diff --git a/csp-lmc-common/tests/unit/cspsubarray_unit_test.py b/csp-lmc-common/tests/unit/cspsubarray_unit_test.py index 09460846e10f31ffe76383b471c01d0008c04c89..a2c9893d1a7b4ea829f21aae4369045aa9dcb71a 100644 --- a/csp-lmc-common/tests/unit/cspsubarray_unit_test.py +++ b/csp-lmc-common/tests/unit/cspsubarray_unit_test.py @@ -21,25 +21,41 @@ def test_cspsubarray_state_and_obstate_value_after_initialization(): """ device_under_test = CspSubarray cbf_subarray_fqdn = 'mid_csp_cbf/sub_elt/subarray_01' - cbf_subarray_state_attr = 'State' + pss_subarray_fqdn = 'mid_csp_pss/sub_elt/subarray_01' + pst_subarray_fqdn = 'mid_csp_pst/sub_elt/subarray_01' + + state_attr = 'State' dut_properties = { - 'CspMaster':'mid_csp/elt/master', + 'CspMaster': 'mid_csp/elt/master', 'CbfSubarray': cbf_subarray_fqdn, - 'PssSubarray': 'mid_csp_pss/sub_elt/subarray_01', - 'PstSubarray': 'mid_csp_pst/sub_elt/subarray_01', + 'PssSubarray': pss_subarray_fqdn, + 'PstSubarray': pst_subarray_fqdn } - event_subscription_map = {} cbf_subarray_device_proxy_mock = Mock() + pss_subarray_device_proxy_mock = Mock() + pst_subarray_device_proxy_mock = Mock() + + event_subscription_map_cbf= {} cbf_subarray_device_proxy_mock.subscribe_event.side_effect = ( - lambda attr_name, event_type, callback, *args, **kwargs: event_subscription_map.update({attr_name: callback})) + lambda attr_name, event_type, callback, *args, **kwargs: event_subscription_map_cbf.update({attr_name: callback})) + + event_subscription_map_pss = {} + cbf_subarray_device_proxy_mock.subscribe_event.side_effect = ( + lambda attr_name, event_type, callback, *args, **kwargs: event_subscription_map_pss.update( + {attr_name: callback})) + + event_subscription_map_pst = {} + cbf_subarray_device_proxy_mock.subscribe_event.side_effect = ( + lambda attr_name, event_type, callback, *args, **kwargs: event_subscription_map_pst.update( + {attr_name: callback})) proxies_to_mock = { - cbf_subarray_fqdn: cbf_subarray_device_proxy_mock + cbf_subarray_fqdn: cbf_subarray_device_proxy_mock, + pss_subarray_fqdn: pss_subarray_device_proxy_mock, + pst_subarray_fqdn: pst_subarray_device_proxy_mock } - + # CASE A: CBF is OFF with fake_tango_system(device_under_test, initial_dut_properties=dut_properties, proxies_to_mock=proxies_to_mock) as tango_context: - dummy_event = create_dummy_event(cbf_subarray_fqdn, DevState.OFF) - event_subscription_map[cbf_subarray_state_attr](dummy_event) assert tango_context.device.State() == DevState.OFF assert tango_context.device.obsState == ObsState.EMPTY @@ -176,13 +192,13 @@ def test_cspsubarray_transaction_id_in_log(capsys): with fake_tango_system(device_under_test, initial_dut_properties=dut_properties, proxies_to_mock=proxies_to_mock) as tango_context: cbf_subarray_device_proxy_mock.On.side_effect = return_ok pss_subarray_device_proxy_mock.On.side_effect = return_ok + prober_obs_state = Probe(tango_context.device, "State", DevState.OFF, f"State is not OFF") + Poller(3, 0.1).check(prober_obs_state) tango_context.device.On() assert tango_context.device.State() == DevState.ON - tango_context.device.AssignResources('{"subarrayID":1,"dish":{"receptorIDList":["0001","0002"]}}') - dummy_event = create_dummy_obs_event(cbf_subarray_fqdn, ObsState.IDLE) - event_subscription_map[cbf_subarray_state_attr](dummy_event) - prober_obs_state = Probe(tango_context.device, "obsState", ObsState.EMPTY, f"AssignResources command out of time") - Poller(10, 0.1).check(prober_obs_state) + #tango_context.device.AssignResources('{"subarrayID":1,"dish":{"receptorIDList":["0001","0002"]}}') + tango_context.device.AssignResources('{"example": ["BAND1"]}') + tango_context.device.obsState == ObsState.IDLE #TODO: find a way to test Configure (ObsState is needed to be IDLE) #tango_context.device.Configure('{"id":"sbi-400-scienceA"}') # a prober is needed since the duration of the Configure command is variable. diff --git a/csp-lmc-mid/.make/k8s.mk b/csp-lmc-mid/.make/k8s.mk index c3eb95b118daa4e4f96b7b4cf3d836ab53a9ebc3..825aa0d402ffa8bf8464e79095a9a3ceca8ab1f1 100644 --- a/csp-lmc-mid/.make/k8s.mk +++ b/csp-lmc-mid/.make/k8s.mk @@ -238,7 +238,7 @@ k8s_test = tar -c . | \ /bin/bash -c "tar xv --strip-components 1 --warning=all && \ python3 -m pip install -r requirements-tst.txt . && \ cd test-harness &&\ - make TANGO_HOST=$(TANGO_HOST) $1 && \ + make TANGO_HOST=$(TANGO_HOST) MARK='$(MARK)' $1 && \ tar -czvf /tmp/build.tgz build && \ echo '~~~~BOUNDARY~~~~' && \ cat /tmp/build.tgz | base64 && \ diff --git a/csp-lmc-mid/.release b/csp-lmc-mid/.release index 900d2ad8ecdb761a326b02a465dc42cf110ae625..594a509c6b699773ba00b43a5c9b56792130b482 100644 --- a/csp-lmc-mid/.release +++ b/csp-lmc-mid/.release @@ -9,7 +9,7 @@ """Release information for Python Package""" name = """MID CSP.LMC""" -version = "0.7.1" +version = "0.7.2" version_info = version.split(".") description = """SKA MID CSP.LMC Classes""" author = "E.G" @@ -20,5 +20,5 @@ copyright = """""" #!!!! UPDATE THE MID-CSP IMAGE VERSION #!!!! DO BEFORE TAGGING !!!! -release=0.7.1 -tag=mid-csp-lmc-0.7.1 +release=0.7.2 +tag=mid-csp-lmc-0.7.2 diff --git a/csp-lmc-mid/HISTORY b/csp-lmc-mid/HISTORY index f1dc1f5c5049ddde614495bba9c018d766ebfc70..860c01dd7e829bf06f928f3a1fb9939453f24ede 100644 --- a/csp-lmc-mid/HISTORY +++ b/csp-lmc-mid/HISTORY @@ -1,3 +1,8 @@ +0.7.2 +- use csp-lmc-common 0.7.2 +- updated integration tests for init command +- removed tango forwarded-attributes + 0.7.1 - use csp-lmc-common 0.7.1 - updated integration tests diff --git a/csp-lmc-mid/charts/mid-csp/data/midcspconfig.json b/csp-lmc-mid/charts/mid-csp/data/midcspconfig.json index 08bb41f842bce42a89850a1cd634bdf4a3bcfb68..e4a775e7d8754e6a869998c6e71ea75bd8f72c31 100644 --- a/csp-lmc-mid/charts/mid-csp/data/midcspconfig.json +++ b/csp-lmc-mid/charts/mid-csp/data/midcspconfig.json @@ -347,31 +347,6 @@ "-1", "1" ] - }, - "assignedFspHealthState": { - "__root_att": [ - "mid_csp_cbf/sub_elt/subarray_01/fspHealthState" - ] - }, - "assignedFspState": { - "__root_att": [ - "mid_csp_cbf/sub_elt/subarray_01/fspState" - ] - }, - "assignedReceptors": { - "__root_att": [ - "mid_csp_cbf/sub_elt/subarray_01/receptors" - ] - }, - "assignedVccHealthState": { - "__root_att": [ - "mid_csp_cbf/sub_elt/subarray_01/vccHealthState" - ] - }, - "assignedVccState": { - "__root_att": [ - "mid_csp_cbf/sub_elt/subarray_01/vccState" - ] } }, "properties": { @@ -510,31 +485,6 @@ "-1", "1" ] - }, - "assignedFspHealthState": { - "__root_att": [ - "mid_csp_cbf/sub_elt/subarray_02/fspHealthState" - ] - }, - "assignedFspState": { - "__root_att": [ - "mid_csp_cbf/sub_elt/subarray_02/fspState" - ] - }, - "assignedReceptors": { - "__root_att": [ - "mid_csp_cbf/sub_elt/subarray_02/receptors" - ] - }, - "assignedVccHealthState": { - "__root_att": [ - "mid_csp_cbf/sub_elt/subarray_02/vccHealthState" - ] - }, - "assignedVccState": { - "__root_att": [ - "mid_csp_cbf/sub_elt/subarray_02/vccState" - ] } }, "properties": { @@ -673,31 +623,6 @@ "-1", "1" ] - }, - "assignedFspHealthState": { - "__root_att": [ - "mid_csp_cbf/sub_elt/subarray_03/fspHealthState" - ] - }, - "assignedFspState": { - "__root_att": [ - "mid_csp_cbf/sub_elt/subarray_03/fspState" - ] - }, - "assignedReceptors": { - "__root_att": [ - "mid_csp_cbf/sub_elt/subarray_03/receptors" - ] - }, - "assignedVccHealthState": { - "__root_att": [ - "mid_csp_cbf/sub_elt/subarray_03/vccHealthState" - ] - }, - "assignedVccState": { - "__root_att": [ - "mid_csp_cbf/sub_elt/subarray_03/vccState" - ] } }, "properties": { diff --git a/csp-lmc-mid/csp_lmc_mid/MidCspSubarrayBase.py b/csp-lmc-mid/csp_lmc_mid/MidCspSubarrayBase.py index 1bfe5c72a765c96ea85cbf26a03ffb2aa492bf18..30cc168f184daff39bb62fa6d068d9abf97a4301 100644 --- a/csp-lmc-mid/csp_lmc_mid/MidCspSubarrayBase.py +++ b/csp-lmc-mid/csp_lmc_mid/MidCspSubarrayBase.py @@ -24,6 +24,7 @@ import time import json from collections import defaultdict import logging +import numpy # PROTECTED REGION END# //MidCspSubarrayBase.standardlibray_import @@ -88,7 +89,7 @@ class MidCspSubarrayBase(CspSubarray): device._assigned_fsp = [] #device._receptor_to_vcc_map = {} #device._receptor_id_list = [] - device._receptors = Receptors(device.CspMaster) + device._receptors = Receptors(device, self.logger) message = "MidCspSubarray Init command completed OK" self.logger.info(message) return (result_code, message) @@ -450,6 +451,20 @@ class MidCspSubarrayBase(CspSubarray): self.logger.debug("len assigned_receptors:{}".format(assigned_receptors)) return len(assigned_receptors) + def init_command_objects(self): + """ + Sets up the command objects + """ + super().init_command_objects() + + args = (self, self.state_model, self.logger) + + self._assignresources_cmd_obj = self.AssignResourcesCommand(*args) + self._releaseresources_cmd_obj = self.ReleaseResourcesCommand(*args) + self.register_command_object("AssignResources", self.AssignResourcesCommand(*args)) + self.register_command_object("ReleaseResources", self.ReleaseResourcesCommand(*args)) + self.register_command_object("ReleaseAllResources", self.ReleaseAllResourcesCommand(*args)) + def update_subarray_state(self): """ Class protected method. @@ -505,7 +520,6 @@ class MidCspSubarrayBase(CspSubarray): self.logger.info("Going to assign receptors {}".format(receptors_to_be_added)) while True: - self.logger.info("device {} obs_state:{}".format(device, self._sc_subarray_obs_state[device])) if self._sc_subarray_obs_state[device] == ObsState.IDLE: self.logger.info("Reconfiguring is:{}".format(self._reconfiguring)) assigned_receptors = self._receptors.assigned_to_subarray(self.SubID) @@ -645,20 +659,6 @@ class MidCspSubarrayBase(CspSubarray): #def Configure(self, argin): # CspSubarray.Configure(self, argin) - def init_command_objects(self): - """ - Sets up the command objects - """ - super().init_command_objects() - args = (self, self.state_model, self.logger) - - self._assignresources_cmd_obj = self.AssignResourcesCommand(*args) - self._releaseresources_cmd_obj = self.ReleaseResourcesCommand(*args) - self.register_command_object("AssignResources", self.AssignResourcesCommand(*args)) - self.register_command_object("ReleaseResources", self.ReleaseResourcesCommand(*args)) - self.register_command_object("ReleaseAllResources", self.ReleaseAllResourcesCommand(*args)) - - # PROTECTED REGION END # // MidCspSubarrayBase.private_methods # ---------------- # Class Properties @@ -698,43 +698,71 @@ class MidCspSubarrayBase(CspSubarray): doc="The progress percentage for the RemoveReceptors command.", ) - assignedVccState = attribute(name="assignedVccState", - label="State of the assigned VCC", - forwarded=True - ) - assignedVccHealthState = attribute(name="assignedVccHealthState", - label="HealthState of the assigned VCC", - forwarded=True - ) - assignedFspState = attribute(name="assignedFspState", - label="State of the assigned FSPs", - forwarded=True - ) - assignedFspHealthState = attribute(name="assignedFspHealthState", - label="HealthState of the assigned FSPs.", - forwarded=True - ) - assignedReceptors = attribute(name="assignedReceptors", - label="The list of assigned receptor IDs.", - forwarded=True - ) - # TODO: implement the root attributes on CbfSubarray - # assignedVccObsState = attribute(name="assignedVccObsState", - # label="ObsState of the assigned VCCs", - # forwarded=True - # ) - # assignedFspObsState = attribute(name="assignedFspObsState", - # label="ObsState of the assigned FSPs.", - # forwarded=True - # ) - # assignedVccAdminMode = attribute(name="assignedVccAdminMode", - # label="AdminMode of the assigned VCCs.", - # forwarded=True - # ) - # assignedFspAdminMode = attribute(name="assignedFspAdminMode", - # label="AdminMode of the assigned FSPs.", - # forwarded=True - # ) + assignedVccState = attribute( + dtype=('DevState',), + max_dim_x=197, + label="assignedVccState", + doc="The State of the assigned VCCs.", + ) + + assignedVccHealthState = attribute( + dtype=('DevUShort',), + max_dim_x=197, + label="assignedVccHealthState", + doc="The health state of the assigned VCCs.", + ) + + assignedVccObsState = attribute( + dtype=('DevUShort',), + max_dim_x=197, + label="assignedVccObsState", + doc="The observing state of the assigned VCCs.", + ) + + assignedVccAdminMode = attribute( + dtype=('DevUShort',), + access=AttrWriteType.READ_WRITE, + max_dim_x=197, + label="assignedVccAdminMode", + doc="The admin mode of the assigned VCCs.", + ) + + assignedFspState = attribute( + dtype=('DevState',), + max_dim_x=197, + label="assignedFSPState", + doc="The State of the assigned FSPs.", + ) + + assignedFspHealthState = attribute( + dtype=('DevUShort',), + max_dim_x=197, + label="assignedFSPHealthState", + doc="The health state of the assigned FSPs.", + ) + + assignedFspObsState = attribute( + dtype=('DevUShort',), + max_dim_x=197, + label="assignedFspObsState", + doc="The observing state of the assigned FSPs.", + ) + + assignedFspAdminMode = attribute( + dtype=('DevUShort',), + access=AttrWriteType.READ_WRITE, + max_dim_x=197, + label="assignedFspAdminMode", + doc="The admin mode of the assigned FSPs.", + ) + + assignedReceptors = attribute( + dtype=('DevULong',), + max_dim_x=197, + label="assignedReceptors", + doc="The list of receptors assigned to the subarray.", + ) + # --------------- # General methods # --------------- @@ -807,7 +835,6 @@ class MidCspSubarrayBase(CspSubarray): self.logger.warning(tango_err.args[0].desc) ''' try: - #assigned_receptors = self._sc_subarray_proxies[self.CbfSubarray].receptors assigned_receptors = self._receptors.assigned_to_subarray(self.SubID) # NOTE: if receptors attribute is empty, assigned_receptors is an empty numpy array # and it will just be skipped by the for loop @@ -829,6 +856,73 @@ class MidCspSubarrayBase(CspSubarray): return self._assigned_vcc # PROTECTED REGION END # // MidCspSubarrayBase.assignedVcc_read + def read_assignedVccState(self): + # PROTECTED REGION ID(MidCspSubarrayBase.assignedVccState_read) ENABLED START # + """Return the assignedVccState attribute.""" + return (tango.DevState.UNKNOWN,) + def read_assignedVccHealthState(self): + # PROTECTED REGION ID(MidCspSubarrayBase.assignedVccHealthState_read) ENABLED START # + """Return the assignedVccHealthState attribute.""" + return (0,) + # PROTECTED REGION END # // MidCspSubarrayBase.assignedVccHealthState_read + + def read_assignedVccObsState(self): + # PROTECTED REGION ID(MidCspSubarrayBase.assignedVccObsState_read) ENABLED START # + """Return the assignedVccObsState attribute.""" + return (0,) + # PROTECTED REGION END # // MidCspSubarrayBase.assignedVccObsState_read + + def read_assignedVccAdminMode(self): + # PROTECTED REGION ID(MidCspSubarrayBase.assignedVccAdminMode_read) ENABLED START # + """Return the assignedVccAdminMode attribute.""" + return (0,) + # PROTECTED REGION END # // MidCspSubarrayBase.assignedVccAdminMode_read + + def write_assignedVccAdminMode(self, value): + # PROTECTED REGION ID(MidCspSubarrayBase.assignedVccAdminMode_write) ENABLED START # + """Set the assignedVccAdminMode attribute.""" + pass + # PROTECTED REGION END # // MidCspSubarrayBase.assignedVccAdminMode_write + + def read_assignedFspState(self): + # PROTECTED REGION ID(MidCspSubarrayBase.assignedFspState_read) ENABLED START # + """Return the assignedFspState attribute.""" + return (tango.DevState.UNKNOWN,) + # PROTECTED REGION END # // MidCspSubarrayBase.assignedFspState_read + + def read_assignedFspHealthState(self): + # PROTECTED REGION ID(MidCspSubarrayBase.assignedFspHealthState_read) ENABLED START # + """Return the assignedFspHealthState attribute.""" + return (0,) + # PROTECTED REGION END # // MidCspSubarrayBase.assignedFspHealthState_read + + def read_assignedFspObsState(self): + # PROTECTED REGION ID(MidCspSubarrayBase.assignedFspObsState_read) ENABLED START # + """Return the assignedFspObsState attribute.""" + return (0,) + # PROTECTED REGION END # // MidCspSubarrayBase.assignedFspObsState_read + + def read_assignedFspAdminMode(self): + # PROTECTED REGION ID(MidCspSubarrayBase.assignedFspAdminMode_read) ENABLED START # + """Return the assignedFspAdminMode attribute.""" + return (0,) + # PROTECTED REGION END # // MidCspSubarrayBase.assignedFspAdminMode_read + + def write_assignedFspAdminMode(self, value): + # PROTECTED REGION ID(MidCspSubarrayBase.assignedFspAdminMode_write) ENABLED START # + """Set the assignedFspAdminMode attribute.""" + pass + # PROTECTED REGION END # // MidCspSubarrayBase.assignedFspAdminMode_write + + def read_assignedReceptors(self): + # PROTECTED REGION ID(MidCspSubarrayBase.assignedReceptors_read) ENABLED START # + """Return the assignedReceptors attribute.""" + assigned_receptors = self._receptors.assigned_to_subarray(self.SubID) + if len(assigned_receptors) == 0: + return [0] + return assigned_receptors + # PROTECTED REGION END # // MidCspSubarrayBase.assignedReceptors_read + # ---------- # Run server # ---------- diff --git a/csp-lmc-mid/csp_lmc_mid/receptors.py b/csp-lmc-mid/csp_lmc_mid/receptors.py index 0d507c0a73113618541f9ecfc64b13dd69b5fb89..2bc8e6fbfb5c9cc684e765498dfcfae62801694b 100644 --- a/csp-lmc-mid/csp_lmc_mid/receptors.py +++ b/csp-lmc-mid/csp_lmc_mid/receptors.py @@ -3,13 +3,15 @@ import logging import time from tango import DeviceProxy -LOGGER = logging.getLogger(__name__) +module_logger = logging.getLogger(__name__) class Receptors: """ Class to handle information about the Mid receptors. """ - def __init__(self, csp_master_fqdn): - self._csp_master_fqdn = csp_master_fqdn + def __init__(self, device, logger=None): + self.device = device + self._csp_master_fqdn = device.CspMaster + self.logger = logger or module_logger def cbf_master_address(self): """ @@ -34,7 +36,7 @@ class Receptors: proxy.ping() return proxy except tango.DevFailed as tango_ex: - LOGGER.error(tango_ex.args[0].desc) + module_logger.error(tango_ex.args[0].desc) tango.Except.re_throw_exception(tango_ex, "Connection failed", "Receptors class", @@ -53,7 +55,7 @@ class Receptors: for pair in receptor_to_vcc) return receptor_to_vcc_map except tango.DevFailed as tango_ex: - LOGGER.error(tango_ex.args[0].desc) + module_logger.error(tango_ex.args[0].desc) tango.Except.re_throw_exception(tango_ex, "Connection failed", "Receptors class", @@ -84,7 +86,7 @@ class Receptors: value = proxy.unassignedReceptorIDs return value except tango.DevFailed as tango_ex: - LOGGER.error(tango_ex.args[0].desc) + module_logger.error(tango_ex.args[0].desc) tango.Except.re_throw_exception(tango_ex, "Connection failed", "Receptors class", @@ -99,10 +101,10 @@ class Receptors: try: proxy = self.connect(self._csp_master_fqdn) value = proxy.receptorMembership - LOGGER.debug("receptorMembership:{}".format(value)) + module_logger.debug("receptorMembership:{}".format(value)) return value except tango.DevFailed as tango_ex: - LOGGER.error(tango_ex.args[0].desc) + module_logger.error(tango_ex.args[0].desc) tango.Except.re_throw_exception(tango_ex, "Connection failed", "Receptors class", @@ -115,16 +117,15 @@ class Receptors: assigned_receptors = [] sub_id = int(_sub_id) try: - proxy = self.connect(self._csp_master_fqdn) - subarray_addrs = proxy.cspSubarrayAddresses + self.logger.info(f"CbfSubarray: {self.device.CbfSubarray}") + proxy = self.connect(self.device.CbfSubarray) #receptor_membership = self.subarray_affiliation() #assigned_receptors = [receptor_id + 1 for receptor_id, e in enumerate(receptor_membership) if e == int(sub_id)] - proxy = self.connect(subarray_addrs[sub_id - 1]) - assigned_receptors = proxy.assignedReceptors - LOGGER.debug(assigned_receptors) + assigned_receptors = proxy.receptors + module_logger.debug(assigned_receptors) return assigned_receptors except tango.DevFailed as tango_ex: - LOGGER.error(tango_ex.args[0].desc) + module_logger.error(tango_ex.args[0].desc) tango.Except.re_throw_exception(tango_ex, "Connection failed", "Receptors class", diff --git a/csp-lmc-mid/csp_lmc_mid/release.py b/csp-lmc-mid/csp_lmc_mid/release.py index 687296cd021523c1355dd9bda4fea4e0bf1367fe..d5386cb15a44e02c500f7dad64c398e929ed7bc6 100755 --- a/csp-lmc-mid/csp_lmc_mid/release.py +++ b/csp-lmc-mid/csp_lmc_mid/release.py @@ -10,7 +10,7 @@ """Release information for Python Package""" name = """mid-csp-lmc""" -version = "0.7.1" +version = "0.7.2" version_info = version.split(".") description = """SKA MID CSP.LMC""" author = "INAF-OAA" diff --git a/csp-lmc-mid/json_configuration/CSP_AssignResources.json b/csp-lmc-mid/json_configuration/CSP_AssignResources.json new file mode 100644 index 0000000000000000000000000000000000000000..755770d448abc26b5ee2117be95876f927b37491 --- /dev/null +++ b/csp-lmc-mid/json_configuration/CSP_AssignResources.json @@ -0,0 +1,8 @@ +{ + "subarrayID": 1, + "dish": + { "receptorIDList": + ["0001", "0002"] + } +} + diff --git a/csp-lmc-mid/json_configuration/CSP_ConfigureScan_ADR18.json b/csp-lmc-mid/json_configuration/CSP_ConfigureScan_ADR18.json new file mode 100644 index 0000000000000000000000000000000000000000..5641400ca378a2249c4bd8bfb285c80057495f19 --- /dev/null +++ b/csp-lmc-mid/json_configuration/CSP_ConfigureScan_ADR18.json @@ -0,0 +1,32 @@ +{ + "interface": "https://schema.skatelescope.org/ska-csp-configure/1.0", + "common": { + "id": "sbi-mvp01-20200326-00001-science_B", + "frequencyBand": "3" + }, + "cbf": { + "delayModelSubscriptionPoint": "ska_mid/tm_leaf_node/csp_subarray01/delayModel", + "fsp": [ + { + "fspID": 1, + "functionMode": "CORR", + "frequencySliceID": 1, + "integrationTime": 1400, + "corrBandwidth": 0, + "channelAveragingMap": [[0,2], [744,0]], + "fspChannelOffset": 0, + "outputLinkMap": [[0,0], [200,1]], + "outputHost": [[0, "192.168.0.1"], [8184, "192.168.0.2"]], + "outputMac": [[0, "06-00-00-00-00-01"]], + "outputPort": [[0, 9000, 1], [8184, 9000, 1]] + }, + { + "fspID": 2, "functionMode": "CORR", "frequencySliceID": 2, + "integrationTime": 1400, "corrBandwidth": 0, + "channelAveragingMap": [[0,2], [744,0]], + "fspChannelOffset": 744, + "outputLinkMap": [[0,4], [200,5]] + } + ] + } +} diff --git a/csp-lmc-mid/json_configuration/CSP_ConfigureScan_ADR4.json b/csp-lmc-mid/json_configuration/CSP_ConfigureScan_ADR4.json new file mode 100644 index 0000000000000000000000000000000000000000..f3c12a6e4f83bb511f8f05eb97e0ab1691477e01 --- /dev/null +++ b/csp-lmc-mid/json_configuration/CSP_ConfigureScan_ADR4.json @@ -0,0 +1,77 @@ +{ + "id": "sbi-mvp01-20200325-00002-science_A", + "frequencyBand": "1", + "delayModelSubscriptionPoint": "ska_mid/tm_leaf_node/csp_subarray01/delayModel", + + "fsp": [ + { + "fspID": 1, + "functionMode": "CORR", + "frequencySliceID": 1, + "corrBandwidth": 0, + "integrationTime": 140, + "fspChannelOffset": 0, + "channelAveragingMap": [ + [0, 1], + [744, 1], + [1488, 1], + [2232, 1], + [2976, 1], + [3720, 1], + [4464, 1], + [5208, 1], + [5952, 1], + [6696, 1], + [7440, 1], + [8184, 1], + [8928, 1], + [9672, 1], + [10416, 1], + [11160, 1], + [11904, 1], + [12648, 1], + [13392, 1], + [14136, 1] + ], + "outputLinkMap": [ + [0, 4], + [744, 8], + [1480, 12], + [2234, 16], + [2978, 20], + [3722, 24], + [4466, 28], + [5208, 32], + [5952, 36], + [6696, 40], + [7440, 44], + [8184, 48], + [8928, 52], + [9672, 56], + [10416, 60], + [11160, 64], + [11904, 68], + [12648, 72], + [13392, 76], + [14136, 80] + ], + "outputHost": [[0, "192.168.0.1"], [8184, "192.168.0.2"]], + "outputMac": [[0, "06-00-00-00-00-01"]], + "outputPort": [[0, 9000, 1], [8184, 9000, 1]] + }, + { + "fspID":2, + "functionMode":"CORR", + "frequencySliceID":2, + "integrationTime":1400, + "corrBandwidth":1, + "channelAveragingMap":[[0,2],[744,0]], + "fspChannelOffset":744, + "outputLinkMap":[[0,4],[200,5]], + "zoomWindowTuning":650000, + "outputHost": [[0, "192.168.0.1"], [8184, "192.168.0.2"]], + "outputMac": [[0, "06-00-00-00-00-01"]], + "outputPort": [[0, 9000, 1], [8184, 9000, 1]] + } + ] +} diff --git a/csp-lmc-mid/json_configuration/TM_AssignResources.txt b/csp-lmc-mid/json_configuration/TM_AssignResources.txt new file mode 100644 index 0000000000000000000000000000000000000000..91b5b5df22ee6b38177278eb601eeae651e625ef --- /dev/null +++ b/csp-lmc-mid/json_configuration/TM_AssignResources.txt @@ -0,0 +1 @@ +{"subarrayID":1,"dish":{"receptorIDList":["0001","0002"]},"sdp":{"id":"sbi-mvp01-20200325-00001","max_length":100.0,"scan_types":[{"id":"science_A","coordinate_system":"ICRS","ra":"02:42:40.771","dec":"-00:00:47.84","channels":[{"count":744,"start":0,"stride":2,"freq_min":0.35e9,"freq_max":0.368e9,"link_map":[[0,0],[200,1],[744,2],[944,3]]},{"count":744,"start":2000,"stride":1,"freq_min":0.36e9,"freq_max":0.368e9,"link_map":[[2000,4],[2200,5]]}]},{"id":"calibration_B","coordinate_system":"ICRS","ra":"12:29:06.699","dec":"02:03:08.598","channels":[{"count":744,"start":0,"stride":2,"freq_min":0.35e9,"freq_max":0.368e9,"link_map":[[0,0],[200,1],[744,2],[944,3]]},{"count":744,"start":2000,"stride":1,"freq_min":0.36e9,"freq_max":0.368e9,"link_map":[[2000,4],[2200,5]]}]}],"processing_blocks":[{"id":"pb-mvp01-20200325-00001","workflow":{"type":"realtime","id":"vis_receive","version":"0.1.0"},"parameters":{}},{"id":"pb-mvp01-20200325-00002","workflow":{"type":"realtime","id":"test_receive_addresses","version":"0.3.2"},"parameters":{}},{"id":"pb-mvp01-20200325-00003","workflow":{"type":"batch","id":"ical","version":"0.1.0"},"parameters":{},"dependencies":[{"pb_id":"pb-mvp01-20200325-00001","type":["visibilities"]}]},{"id":"pb-mvp01-20200325-00004","workflow":{"type":"batch","id":"dpreb","version":"0.1.0"},"parameters":{},"dependencies":[{"pb_id":"pb-mvp01-20200325-00003","type":["calibration"]}]}]}} diff --git a/csp-lmc-mid/json_configuration/TM_ConfigureScan.json b/csp-lmc-mid/json_configuration/TM_ConfigureScan.json new file mode 100644 index 0000000000000000000000000000000000000000..ff5b1cc79939d49dd3a47ab6182046c8fdc02098 --- /dev/null +++ b/csp-lmc-mid/json_configuration/TM_ConfigureScan.json @@ -0,0 +1,52 @@ +{ + "pointing": + {"target": + { + "system":"ICRS", + "name":"Polaris Australis","RA":"21:08:47.92","dec":"-88:57:22.9" + } + }, + "dish": + {"receiverBand":"1"}, + "csp":{ + "interface":"https://schema.skatelescope.org/ska-csp-configure/1.0", + "subarray":{"subarrayName":"science period 23"}, + "common":{ + "id":"sbi-mvp01-20200325-00001-science_A", + "frequencyBand":"1", + "subarrayID":1 + }, + "cbf":{ + "fsp":[{ + "fspID":1, + "functionMode":"CORR", + "frequencySliceID":1, + "integrationTime":1400, + "corrBandwidth":0, + "channelAveragingMap":[[0,2],[744,0]], + "fspChannelOffset":0, + "outputLinkMap":[[0,0],[200,1]], + "outputHost":[[0,"192.168.1.1"]], + "outputPort":[[0,9000,1]] + }, + { + "fspID":2, + "functionMode":"CORR", + "frequencySliceID":2, + "integrationTime":1400, + "corrBandwidth":0, + "channelAveragingMap":[[0,2],[744,0]], + "fspChannelOffset":744, + "outputLinkMap":[[0,4],[200,5]], + "outputHost":[[0,"192.168.1.1"]], + "outputPort":[[0,9744,1]] + } + ], + "vlbi":{} + }, + "pss":{}, + "pst":{} + }, + "sdp":{"scan_type":"science_A"}, + "tmc":{"scanDuration":6.0} +} diff --git a/csp-lmc-mid/pogo/MidCspSubarrayBase.xmi b/csp-lmc-mid/pogo/MidCspSubarrayBase.xmi index d1b084a5f060572d72430b5a942313fc93fc3e92..e154f9affcbbfebfb4ad0c2fe76672c6a83c0050 100644 --- a/csp-lmc-mid/pogo/MidCspSubarrayBase.xmi +++ b/csp-lmc-mid/pogo/MidCspSubarrayBase.xmi @@ -1,11 +1,11 @@ - + - - - + + + @@ -75,7 +75,7 @@ - + @@ -138,7 +138,7 @@ - + @@ -147,7 +147,7 @@ - + @@ -174,7 +174,7 @@ - + @@ -183,7 +183,7 @@ - + @@ -192,7 +192,7 @@ - + @@ -210,7 +210,7 @@ - + @@ -300,7 +300,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -882,33 +909,78 @@ - + + + + + - - + + + + + + + - - + + + + + + + - - + + + + + + + - - + + + + + + + - - + + + + + + + - - + + + + + + + - - + + + + + + + - - + + + + + + + - + + @@ -934,14 +1006,14 @@ - - - - - - - - - + + + + + + + + + diff --git a/csp-lmc-mid/requirements.txt b/csp-lmc-mid/requirements.txt index 047ea76d4479cb85c76d785e3d1eb759c5e0db5c..3202269aea82d2df653ee2e73cf95c7d5e3ea11f 100644 --- a/csp-lmc-mid/requirements.txt +++ b/csp-lmc-mid/requirements.txt @@ -2,7 +2,7 @@ numpy == 1.17.2 pytango >= 9.3.2 jsonschema >= 3.2.0 lmcbaseclasses >= 0.8.0 -csp-lmc-common >= 0.7.1 +csp-lmc-common >= 0.7.2 ska-log-transactions ska-telescope-model==0.2.0 diff --git a/csp-lmc-mid/taranta_dashboards/CBF.wj b/csp-lmc-mid/taranta_dashboards/CBF.wj new file mode 100644 index 0000000000000000000000000000000000000000..5ec7153bf278a6a26895f555a58593f859c42bb4 --- /dev/null +++ b/csp-lmc-mid/taranta_dashboards/CBF.wj @@ -0,0 +1,410 @@ +{ + "id": "602cdf4d1c66ab001d6db9d1", + "name": "CBF", + "version": "1.0.7", + "user": "CREAM", + "insertTime": "2021-02-17T09:18:05.979Z", + "updateTime": "2021-02-17T09:36:35.307Z", + "group": null, + "groupWriteAccess": false, + "lastUpdatedBy": "CREAM", + "widget": [ + { + "id": "100", + "x": 28, + "y": 26, + "canvas": "0", + "width": 8, + "height": 6, + "type": "LABEL", + "inputs": { + "text": "001", + "textColor": "#004f70", + "backgroundColor": "#ffffff", + "size": 2, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "http://integration.engageska-portugal.pt/testdb/devices/mid_csp_cbf/sub_elt/subarray_01/attributes", + "customCss": "text-align:center;\nfont-size:15px\npadding-top: 10px;\nfont-weight:bold;\ntext-decoration:underline;\n" + }, + "order": 2 + }, + { + "id": "207", + "x": 47, + "y": 27, + "canvas": "0", + "width": 5, + "height": 4, + "type": "DEVICE_STATUS", + "inputs": { + "device": "mid_csp_cbf/sub_elt/subarray_01", + "state": { + "device": null, + "attribute": null + }, + "showDeviceName": false, + "showStateString": false, + "showStateLED": true, + "LEDSize": 1, + "textSize": 1 + }, + "order": 3 + }, + { + "id": "208", + "x": 36, + "y": 32, + "canvas": "0", + "width": 17, + "height": 4, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp_cbf/sub_elt/subarray_01", + "attribute": "obsstate", + "label": "obsState" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#fdfcfc", + "backgroundColor": "#1187d7", + "size": 1, + "font": "Helvetica" + }, + "order": 4 + }, + { + "id": "209", + "x": 36, + "y": 27, + "canvas": "0", + "width": 11, + "height": 4, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp_cbf/sub_elt/subarray_01", + "attribute": "state", + "label": "State" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": false, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 5 + }, + { + "id": "210", + "x": 27, + "y": 25, + "canvas": "0", + "width": 31, + "height": 13, + "type": "LABEL", + "inputs": { + "text": " ", + "textColor": "#f0f0f0", + "backgroundColor": "#ffffff", + "size": 1, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "border: 1px solid gray;" + }, + "order": 1 + }, + { + "id": "211", + "x": 26, + "y": 18, + "canvas": "0", + "width": 67, + "height": 81, + "type": "LABEL", + "inputs": { + "text": "CBF SubArray", + "textColor": "#3d68a3", + "backgroundColor": "#f0f0f0", + "size": 1.5, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "border:1px solid #b3b3b3;\npadding-top:10px;\npadding-left:20px;\n" + }, + "order": 0 + }, + { + "id": "224", + "x": 30, + "y": 42, + "canvas": "0", + "width": 27, + "height": 5, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp_cbf/fsp/01", + "attribute": "functionmode", + "label": "Function mode" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 6 + }, + { + "id": "225", + "x": 30, + "y": 47, + "canvas": "0", + "width": 27, + "height": 5, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp_cbf/fspcorrsubarray/01_01", + "attribute": "frequencysliceid", + "label": "Frequency slice ID" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 7 + }, + { + "id": "226", + "x": 30, + "y": 52, + "canvas": "0", + "width": 27, + "height": 5, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp_cbf/fspcorrsubarray/01_01", + "attribute": "integrationtime", + "label": "Integration time (ms)" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 8 + }, + { + "id": "227", + "x": 30, + "y": 57, + "canvas": "0", + "width": 27, + "height": 5, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp_cbf/fspcorrsubarray/01_01", + "attribute": "fspchanneloffset", + "label": "fspChannelOffset" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 9 + }, + { + "id": "228", + "x": 30, + "y": 62, + "canvas": "0", + "width": 27, + "height": 32, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp_cbf/fspcorrsubarray/01_01", + "attribute": "visdestinationaddress", + "label": "Destination addresses" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 10 + }, + { + "id": "229", + "x": 62, + "y": 62, + "canvas": "0", + "width": 27, + "height": 32, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp_cbf/fspcorrsubarray/02_01", + "attribute": "visdestinationaddress", + "label": "Destination addresses" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 11 + }, + { + "id": "230", + "x": 62, + "y": 57, + "canvas": "0", + "width": 27, + "height": 5, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp_cbf/fspcorrsubarray/02_01", + "attribute": "fspchanneloffset", + "label": "fspChannelOffset" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 12 + }, + { + "id": "231", + "x": 62, + "y": 52, + "canvas": "0", + "width": 27, + "height": 5, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp_cbf/fspcorrsubarray/02_01", + "attribute": "integrationtime", + "label": "Integration time (ms)" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 13 + }, + { + "id": "232", + "x": 62, + "y": 47, + "canvas": "0", + "width": 27, + "height": 5, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp_cbf/fspcorrsubarray/02_01", + "attribute": "frequencysliceid", + "label": "Frequency slice ID" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 14 + }, + { + "id": "233", + "x": 62, + "y": 42, + "canvas": "0", + "width": 27, + "height": 5, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp_cbf/fsp/02", + "attribute": "functionmode", + "label": "Function mode" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 15 + } + ] +} \ No newline at end of file diff --git a/csp-lmc-mid/taranta_dashboards/CSP.wj b/csp-lmc-mid/taranta_dashboards/CSP.wj new file mode 100644 index 0000000000000000000000000000000000000000..d9d9907030d65efd84e65f387c3072fbadd61ad7 --- /dev/null +++ b/csp-lmc-mid/taranta_dashboards/CSP.wj @@ -0,0 +1,1041 @@ +{ + "id": "602b96701c66ab001d6d8b9f", + "name": "CSP", + "version": "1.0.7", + "user": "CREAM", + "insertTime": "2021-02-16T09:54:57.176Z", + "updateTime": "2021-02-17T09:32:00.283Z", + "group": null, + "groupWriteAccess": false, + "lastUpdatedBy": "CREAM", + "widget": [ + { + "id": "2", + "x": 6, + "y": 13, + "canvas": "0", + "width": 15, + "height": 5, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp/elt/master", + "attribute": "versionid", + "label": "versionId" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": false, + "textColor": "#000000", + "backgroundColor": "#f0f0f0", + "size": 1, + "font": "Helvetica" + }, + "order": 14 + }, + { + "id": "3", + "x": 50, + "y": 8, + "canvas": "0", + "width": 31, + "height": 8, + "type": "SPECTRUM_TABLE", + "inputs": { + "attribute": { + "device": "mid_csp/elt/master", + "attribute": "unassignedreceptorids", + "label": "Unassigned receptors IDs" + }, + "layout": "horizontal", + "showDevice": false, + "showAttribute": "Label", + "showIndex": false, + "showLabel": false, + "fontSize": 16 + }, + "order": 15 + }, + { + "id": "5", + "x": 25, + "y": 9, + "canvas": "0", + "width": 19, + "height": 5, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp/elt/master", + "attribute": "state", + "label": "State" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": false, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1.2, + "font": "Helvetica" + }, + "order": 17 + }, + { + "id": "6", + "x": 39, + "y": 9, + "canvas": "0", + "width": 6, + "height": 5, + "type": "DEVICE_STATUS", + "inputs": { + "device": "mid_csp/elt/master", + "state": { + "device": null, + "attribute": null + }, + "showDeviceName": false, + "showStateString": false, + "showStateLED": true, + "LEDSize": 1.5, + "textSize": 1 + }, + "order": 18 + }, + { + "id": "7", + "x": 26, + "y": 20, + "canvas": "0", + "width": 54, + "height": 8, + "type": "LABEL", + "inputs": { + "text": " ", + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "border:1px solid gray;" + }, + "order": 2 + }, + { + "id": "8", + "x": 95, + "y": 14, + "canvas": "0", + "width": 5, + "height": 4, + "type": "DEVICE_STATUS", + "inputs": { + "device": "mid_csp_cbf/vcc/001", + "state": { + "device": null, + "attribute": null + }, + "showDeviceName": false, + "showStateString": false, + "showStateLED": true, + "LEDSize": 1, + "textSize": 1 + }, + "order": 19 + }, + { + "id": "9", + "x": 89, + "y": 14, + "canvas": "0", + "width": 6, + "height": 4, + "type": "LABEL", + "inputs": { + "text": " 001", + "textColor": "#000000", + "backgroundColor": "#e6e6e6", + "size": 1.3, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "http://integration.engageska-portugal.pt/testdb/devices/mid_csp_cbf/vcc/001/attributes", + "customCss": "border:1px solid grey;" + }, + "order": 6 + }, + { + "id": "18", + "x": 95, + "y": 19, + "canvas": "0", + "width": 5, + "height": 4, + "type": "DEVICE_STATUS", + "inputs": { + "device": "mid_csp_cbf/vcc/002", + "state": { + "device": null, + "attribute": null + }, + "showDeviceName": false, + "showStateString": false, + "showStateLED": true, + "LEDSize": 1, + "textSize": 1 + }, + "order": 20 + }, + { + "id": "19", + "x": 89, + "y": 19, + "canvas": "0", + "width": 6, + "height": 4, + "type": "LABEL", + "inputs": { + "text": " 002", + "textColor": "#000000", + "backgroundColor": "#e6e6e6", + "size": 1.3, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "http://integration.engageska-portugal.pt/testdb/devices/mid_csp_cbf/vcc/002/attributes", + "customCss": "border:1px solid grey;" + }, + "order": 8 + }, + { + "id": "20", + "x": 109, + "y": 14, + "canvas": "0", + "width": 5, + "height": 4, + "type": "DEVICE_STATUS", + "inputs": { + "device": "mid_csp_cbf/vcc/003", + "state": { + "device": null, + "attribute": null + }, + "showDeviceName": false, + "showStateString": false, + "showStateLED": true, + "LEDSize": 1, + "textSize": 1 + }, + "order": 21 + }, + { + "id": "21", + "x": 103, + "y": 14, + "canvas": "0", + "width": 6, + "height": 4, + "type": "LABEL", + "inputs": { + "text": " 003", + "textColor": "#000000", + "backgroundColor": "#e6e6e6", + "size": 1.3, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "http://integration.engageska-portugal.pt/testdb/devices/mid_csp_cbf/vcc/003/attributes", + "customCss": "border:1px solid grey;" + }, + "order": 9 + }, + { + "id": "22", + "x": 109, + "y": 19, + "canvas": "0", + "width": 5, + "height": 4, + "type": "DEVICE_STATUS", + "inputs": { + "device": "mid_csp_cbf/vcc/004", + "state": { + "device": null, + "attribute": null + }, + "showDeviceName": false, + "showStateString": false, + "showStateLED": true, + "LEDSize": 1, + "textSize": 1 + }, + "order": 30 + }, + { + "id": "23", + "x": 103, + "y": 19, + "canvas": "0", + "width": 6, + "height": 4, + "type": "LABEL", + "inputs": { + "text": " 004", + "textColor": "#000000", + "backgroundColor": "#e6e6e6", + "size": 1.3, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "http://integration.engageska-portugal.pt/testdb/devices/mid_csp_cbf/vcc/004/attributes", + "customCss": "border:1px solid grey;" + }, + "order": 10 + }, + { + "id": "64", + "x": 8, + "y": 20, + "canvas": "0", + "width": 11, + "height": 8, + "type": "LABEL", + "inputs": { + "text": " ", + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "background-image:url(https://www.skatelescope.org/wp-content/uploads/2014/06/09545_NEW_LOGO_20144.jpg);\nbackground-size:90%;\nbackground-position:center;\nbackground-repeat:none;" + }, + "order": 3 + }, + { + "id": "98", + "x": 86, + "y": 10, + "canvas": "0", + "width": 31, + "height": 15, + "type": "LABEL", + "inputs": { + "text": "VCC States", + "textColor": "#3d68a3", + "backgroundColor": "#ffffff", + "size": 1.2, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "border:1px solid gray;" + }, + "order": 5 + }, + { + "id": "99", + "x": 2, + "y": 3, + "canvas": "0", + "width": 117, + "height": 29, + "type": "LABEL", + "inputs": { + "text": "CSP Master", + "textColor": "#3d68a3", + "backgroundColor": "#f0f0f0", + "size": 2, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "http://fattyeg/testdb/devices/mid_csp/elt/master/attributes", + "customCss": "border:1px solid #b3b3b3;\npadding-top:35px;\npadding-left:20px;\n" + }, + "order": 0 + }, + { + "id": "100", + "x": 143, + "y": 55, + "canvas": "0", + "width": 8, + "height": 6, + "type": "LABEL", + "inputs": { + "text": "001", + "textColor": "#004f70", + "backgroundColor": "#ffffff", + "size": 2, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "http://integration.engageska-portugal.pt/testdb/devices/mid_csp_cbf/sub_elt/subarray_01/attributes", + "customCss": "text-align:center;\nfont-size:15px\npadding-top: 10px;\nfont-weight:bold;\ntext-decoration:underline;\n" + }, + "order": 16 + }, + { + "id": "101", + "x": 19, + "y": 49, + "canvas": "0", + "width": 11, + "height": 4, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp/elt/subarray_01", + "attribute": "state", + "label": "State" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": false, + "textColor": "#000000", + "backgroundColor": "#dcdcdc", + "size": 1, + "font": "Helvetica" + }, + "order": 22 + }, + { + "id": "102", + "x": 35, + "y": 49, + "canvas": "0", + "width": 18, + "height": 4, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp/elt/subarray_01", + "attribute": "obsstate", + "label": "obsState" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#fdfcfc", + "backgroundColor": "#1187d7", + "size": 1, + "font": "Helvetica" + }, + "order": 23 + }, + { + "id": "103", + "x": 16, + "y": 93, + "canvas": "0", + "width": 36, + "height": 8, + "type": "SPECTRUM_TABLE", + "inputs": { + "attribute": { + "device": "mid_csp_cbf/sub_elt/subarray_01", + "attribute": "receptors", + "label": "Receptors" + }, + "layout": "horizontal", + "showDevice": false, + "showAttribute": "Label", + "showIndex": false, + "showLabel": false, + "fontSize": 16 + }, + "order": 24 + }, + { + "id": "105", + "x": 30, + "y": 49, + "canvas": "0", + "width": 5, + "height": 4, + "type": "DEVICE_STATUS", + "inputs": { + "device": "mid_csp/elt/subarray_01", + "state": { + "device": null, + "attribute": null + }, + "showDeviceName": false, + "showStateString": false, + "showStateLED": true, + "LEDSize": 1, + "textSize": 1 + }, + "order": 25 + }, + { + "id": "107", + "x": 18, + "y": 48, + "canvas": "0", + "width": 36, + "height": 6, + "type": "LABEL", + "inputs": { + "text": " ", + "textColor": "#f0f0f0", + "backgroundColor": "#dcdcdc", + "size": 1, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "border: 1px solid gray;" + }, + "order": 13 + }, + { + "id": "108", + "x": 17, + "y": 72, + "canvas": "0", + "width": 10, + "height": 4, + "type": "COMMAND_EXECUTOR", + "inputs": { + "command": { + "device": "mid_csp/elt/subarray_01", + "command": "GoToIdle", + "acceptedType": "DevVoid" + }, + "title": "", + "requireConfirmation": false, + "displayOutput": false, + "cooldown": 0, + "textColor": "#004c8c", + "backgroundColor": "#fcfcfc", + "size": 1, + "font": "Helvetica" + }, + "order": 26 + }, + { + "id": "110", + "x": 27, + "y": 87, + "canvas": "0", + "width": 20, + "height": 5, + "type": "COMMAND_EXECUTOR", + "inputs": { + "command": { + "device": "mid_csp/elt/subarray_01", + "command": "ReleaseAllResources", + "acceptedType": "DevVoid" + }, + "title": "", + "requireConfirmation": false, + "displayOutput": false, + "cooldown": 0, + "textColor": "#004c8c", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 27 + }, + { + "id": "111", + "x": 49, + "y": 39, + "canvas": "0", + "width": 7, + "height": 4, + "type": "COMMAND_EXECUTOR", + "inputs": { + "command": { + "device": "mid_csp/elt/subarray_01", + "command": "Off", + "acceptedType": "DevVoid" + }, + "title": "", + "requireConfirmation": false, + "displayOutput": false, + "cooldown": 0, + "textColor": "#004c8c", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 28 + }, + { + "id": "112", + "x": 42, + "y": 39, + "canvas": "0", + "width": 7, + "height": 4, + "type": "COMMAND_EXECUTOR", + "inputs": { + "command": { + "device": "mid_csp/elt/subarray_01", + "command": "On", + "acceptedType": "DevVoid" + }, + "title": "", + "requireConfirmation": false, + "displayOutput": false, + "cooldown": 0, + "textColor": "#004c8c", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 29 + }, + { + "id": "154", + "x": 12, + "y": 33, + "canvas": "0", + "width": 96, + "height": 72, + "type": "LABEL", + "inputs": { + "text": "CSP SubArray", + "textColor": "#3d68a3", + "backgroundColor": "#f0f0f0", + "size": 1.5, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "border:1px solid #b3b3b3;\npadding-top:10px;\npadding-left:20px;\n" + }, + "order": 11 + }, + { + "id": "157", + "x": 27, + "y": 72, + "canvas": "0", + "width": 11, + "height": 4, + "type": "COMMAND_EXECUTOR", + "inputs": { + "command": { + "device": "mid_csp/elt/subarray_01", + "command": "ObsReset", + "acceptedType": "DevVoid" + }, + "title": "", + "requireConfirmation": false, + "displayOutput": false, + "cooldown": 0, + "textColor": "#004c8c", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 31 + }, + { + "id": "158", + "x": 15, + "y": 38, + "canvas": "0", + "width": 45, + "height": 64, + "type": "LABEL", + "inputs": { + "text": " ", + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "border:1px solid gray;" + }, + "order": 12 + }, + { + "id": "161", + "x": 48, + "y": 72, + "canvas": "0", + "width": 10, + "height": 4, + "type": "COMMAND_EXECUTOR", + "inputs": { + "command": { + "device": "mid_csp/elt/subarray_01", + "command": "Restart", + "acceptedType": "DevVoid" + }, + "title": "", + "requireConfirmation": false, + "displayOutput": false, + "cooldown": 0, + "textColor": "#004c8c", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 32 + }, + { + "id": "162", + "x": 39, + "y": 72, + "canvas": "0", + "width": 9, + "height": 4, + "type": "COMMAND_EXECUTOR", + "inputs": { + "command": { + "device": "mid_csp/elt/subarray_01", + "command": "Abort", + "acceptedType": "DevVoid" + }, + "title": "", + "requireConfirmation": false, + "displayOutput": false, + "cooldown": 0, + "textColor": "#004c8c", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 33 + }, + { + "id": "166", + "x": 16, + "y": 65, + "canvas": "0", + "width": 36, + "height": 7, + "type": "command_file", + "inputs": { + "uploadBtnLabel": "Upload File", + "buttonLabel": "", + "command": { + "device": "mid_csp/elt/subarray_01", + "command": "Configure", + "acceptedType": "DevString" + }, + "showDevice": false, + "showCommand": false, + "requireConfirmation": true, + "displayOutput": false, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 14, + "font": "Helvetica" + }, + "order": 34 + }, + { + "id": "167", + "x": 19, + "y": 56, + "canvas": "0", + "width": 36, + "height": 8, + "type": "command_file", + "inputs": { + "uploadBtnLabel": "Upload File", + "buttonLabel": "", + "command": { + "device": "mid_csp/elt/subarray_01", + "command": "AssignResources", + "acceptedType": "DevString" + }, + "showDevice": false, + "showCommand": false, + "requireConfirmation": true, + "displayOutput": false, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 35 + }, + { + "id": "168", + "x": 16, + "y": 79, + "canvas": "0", + "width": 42, + "height": 9, + "type": "command_file", + "inputs": { + "uploadBtnLabel": "Upload File", + "buttonLabel": "", + "command": { + "device": "mid_csp/elt/subarray_01", + "command": "ReleaseResources", + "acceptedType": "DevString" + }, + "showDevice": false, + "showCommand": false, + "requireConfirmation": true, + "displayOutput": false, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 14, + "font": "Helvetica" + }, + "order": 36 + }, + { + "id": "170", + "x": 28, + "y": 21, + "canvas": "0", + "width": 21, + "height": 6, + "type": "COMMAND_ARRAY", + "inputs": { + "command": { + "device": "mid_csp/elt/master", + "command": "On", + "acceptedType": "DevVarStringArray" + }, + "showDevice": false, + "showCommand": true, + "requireConfirmation": true, + "displayOutput": true, + "OutputMaxSize": 20, + "timeDisplayOutput": 3000, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 37 + }, + { + "id": "171", + "x": 51, + "y": 21, + "canvas": "0", + "width": 25, + "height": 6, + "type": "COMMAND_ARRAY", + "inputs": { + "command": { + "device": "mid_csp/elt/master", + "command": "Standby", + "acceptedType": "DevVarStringArray" + }, + "showDevice": false, + "showCommand": true, + "requireConfirmation": true, + "displayOutput": true, + "OutputMaxSize": 20, + "timeDisplayOutput": 3000, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 38 + }, + { + "id": "172", + "x": 24, + "y": 8, + "canvas": "0", + "width": 23, + "height": 7, + "type": "LABEL", + "inputs": { + "text": " ", + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "border:1px solid gray;" + }, + "order": 1 + }, + { + "id": "207", + "x": 162, + "y": 56, + "canvas": "0", + "width": 5, + "height": 4, + "type": "DEVICE_STATUS", + "inputs": { + "device": "mid_csp_cbf/sub_elt/subarray_01", + "state": { + "device": null, + "attribute": null + }, + "showDeviceName": false, + "showStateString": false, + "showStateLED": true, + "LEDSize": 1, + "textSize": 1 + }, + "order": 41 + }, + { + "id": "208", + "x": 151, + "y": 61, + "canvas": "0", + "width": 17, + "height": 4, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp_cbf/sub_elt/subarray_01", + "attribute": "obsstate", + "label": "obsState" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#fdfcfc", + "backgroundColor": "#1187d7", + "size": 1, + "font": "Helvetica" + }, + "order": 42 + }, + { + "id": "209", + "x": 151, + "y": 56, + "canvas": "0", + "width": 11, + "height": 4, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp_cbf/sub_elt/subarray_01", + "attribute": "state", + "label": "State" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": false, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 43 + }, + { + "id": "210", + "x": 142, + "y": 54, + "canvas": "0", + "width": 31, + "height": 13, + "type": "LABEL", + "inputs": { + "text": " ", + "textColor": "#f0f0f0", + "backgroundColor": "#ffffff", + "size": 1, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "border: 1px solid gray;" + }, + "order": 7 + }, + { + "id": "211", + "x": 141, + "y": 47, + "canvas": "0", + "width": 35, + "height": 22, + "type": "LABEL", + "inputs": { + "text": "CBF SubArray", + "textColor": "#3d68a3", + "backgroundColor": "#f0f0f0", + "size": 1.5, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "border:1px solid #b3b3b3;\npadding-top:10px;\npadding-left:20px;\n" + }, + "order": 4 + }, + { + "id": "222", + "x": 16, + "y": 40, + "canvas": "0", + "width": 10, + "height": 6, + "type": "LABEL", + "inputs": { + "text": "001", + "textColor": "#004f70", + "backgroundColor": "#ffffff", + "size": 1.5, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "http://integration.engageska-portugal.pt/testdb/devices/mid_csp_cbf/sub_elt/subarray_01/attributes", + "customCss": "text-align:center;\nfont-size:15px\npadding-top: 10px;\nfont-weight:bold;\ntext-decoration:underline;\n" + }, + "order": 39 + }, + { + "id": "223", + "x": 61, + "y": 35, + "canvas": "0", + "width": 45, + "height": 69, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp/elt/subarray_01", + "attribute": "validscanconfiguration", + "label": "Valid Scan Configuration" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": false, + "textColor": "#000000", + "backgroundColor": "#f0f0f0", + "size": 1, + "font": "Helvetica" + }, + "order": 40 + } + ] +} \ No newline at end of file diff --git a/csp-lmc-mid/taranta_dashboards/TM.wj b/csp-lmc-mid/taranta_dashboards/TM.wj new file mode 100644 index 0000000000000000000000000000000000000000..a9d984150dbd225aaf9fd63c969e07e451cddef7 --- /dev/null +++ b/csp-lmc-mid/taranta_dashboards/TM.wj @@ -0,0 +1,1278 @@ +{ + "id": "602a55c41c66ab001d6d098e", + "name": "TM", + "version": "1.0.7", + "user": "CREAM", + "insertTime": "2021-02-15T11:06:44.775Z", + "updateTime": "2021-02-16T15:57:33.280Z", + "group": null, + "groupWriteAccess": false, + "lastUpdatedBy": "CREAM", + "widget": [ + { + "id": "1", + "x": 12, + "y": 51, + "canvas": "0", + "width": 19, + "height": 5, + "type": "LABEL", + "inputs": { + "text": "TMC Subarray 1", + "backgroundColor": "#b6e3f5", + "textColor": "#000", + "size": 1, + "borderWidth": 0.001, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 47 + }, + { + "id": "3", + "x": 78, + "y": 71, + "canvas": "0", + "width": 19, + "height": 5, + "type": "LABEL", + "inputs": { + "text": "Dish Master 3", + "backgroundColor": "#f2b3b7", + "textColor": "#000", + "size": 1, + "borderWidth": 0.001, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 46 + }, + { + "id": "4", + "x": 100, + "y": 71, + "canvas": "0", + "width": 19, + "height": 5, + "type": "LABEL", + "inputs": { + "text": "Dish Master 4", + "backgroundColor": "#f2b3b7", + "textColor": "#000", + "size": 1, + "borderWidth": 0.001, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 45 + }, + { + "id": "7", + "x": 34, + "y": 51, + "canvas": "0", + "width": 19, + "height": 5, + "type": "LABEL", + "inputs": { + "text": "CSP Subarray 1", + "backgroundColor": "#b5d7ae", + "textColor": "#000", + "size": 1, + "borderWidth": 0.001, + "borderColor": "#010101", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 44 + }, + { + "id": "9", + "x": 56, + "y": 51, + "canvas": "0", + "width": 19, + "height": 5, + "type": "LABEL", + "inputs": { + "text": "SDP Subarray 1", + "backgroundColor": "#f5ce74", + "textColor": "#000", + "size": 1, + "borderWidth": 0.001, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 43 + }, + { + "id": "10", + "x": 12, + "y": 60, + "canvas": "0", + "width": 19, + "height": 8, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "ska_mid/tm_subarray_node/1", + "attribute": "obsstate", + "label": "obsState" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Name", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 42 + }, + { + "id": "11", + "x": 34, + "y": 60, + "canvas": "0", + "width": 19, + "height": 8, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_csp/elt/subarray_01", + "attribute": "obsstate", + "label": "obsState" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Name", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 41 + }, + { + "id": "12", + "x": 56, + "y": 60, + "canvas": "0", + "width": 19, + "height": 8, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_sdp/elt/subarray_1", + "attribute": "obsstate", + "label": "Obs State" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Name", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 40 + }, + { + "id": "13", + "x": 78, + "y": 80, + "canvas": "0", + "width": 19, + "height": 4, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_d0003/elt/master", + "attribute": "pointingstate", + "label": "pointingState" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Name", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 39 + }, + { + "id": "14", + "x": 100, + "y": 80, + "canvas": "0", + "width": 19, + "height": 4, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_d0004/elt/master", + "attribute": "pointingstate", + "label": "pointingState" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Name", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 38 + }, + { + "id": "15", + "x": 33, + "y": 15, + "canvas": "0", + "width": 17, + "height": 4, + "type": "COMMAND_EXECUTOR", + "inputs": { + "command": { + "device": "ska_mid/tm_central/central_node", + "command": "StartUpTelescope" + }, + "title": "", + "requireConfirmation": false, + "displayOutput": false, + "cooldown": 0, + "textColor": "#090a0a", + "backgroundColor": "#fffefe", + "size": 1, + "font": "Helvetica" + }, + "order": 37 + }, + { + "id": "16", + "x": 33, + "y": 19, + "canvas": "0", + "width": 17, + "height": 4, + "type": "COMMAND_EXECUTOR", + "inputs": { + "command": { + "device": "ska_mid/tm_central/central_node", + "command": "StandByTelescope" + }, + "title": "", + "requireConfirmation": false, + "displayOutput": false, + "cooldown": 0, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 36 + }, + { + "id": "20", + "x": 55, + "y": 36, + "canvas": "0", + "width": 19, + "height": 5, + "type": "COMMAND_WRITER", + "inputs": { + "title": "", + "command": { + "device": "ska_mid/tm_subarray_node/1", + "command": "Scan" + }, + "showDevice": false, + "showCommand": true, + "requireConfirmation": false, + "displayOutput": false, + "cooldown": 0, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 35 + }, + { + "id": "21", + "x": 92, + "y": 36, + "canvas": "0", + "width": 7, + "height": 5, + "type": "COMMAND_EXECUTOR", + "inputs": { + "command": { + "device": "ska_mid/tm_subarray_node/1", + "command": "Abort", + "acceptedType": "DevVoid" + }, + "title": "", + "requireConfirmation": false, + "displayOutput": false, + "cooldown": 0, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 34 + }, + { + "id": "22", + "x": 12, + "y": 15, + "canvas": "0", + "width": 19, + "height": 4, + "type": "LABEL", + "inputs": { + "text": "Central Node", + "textColor": "#000", + "backgroundColor": "#b6e3f5", + "size": 1, + "borderWidth": 0.001, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 33 + }, + { + "id": "23", + "x": 12, + "y": 30, + "canvas": "0", + "width": 107, + "height": 4, + "type": "LABEL", + "inputs": { + "text": "TMC Subarray 1", + "textColor": "#000", + "backgroundColor": "#b6e3f5", + "size": 1, + "borderWidth": 0.001, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 32 + }, + { + "id": "24", + "x": 12, + "y": 8, + "canvas": "0", + "width": 107, + "height": 6, + "type": "LABEL", + "inputs": { + "text": "Observation Control", + "textColor": "#000", + "backgroundColor": "#f7f2ba", + "size": 1, + "borderWidth": 0.001, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 31 + }, + { + "id": "25", + "x": 12, + "y": 44, + "canvas": "0", + "width": 107, + "height": 4, + "type": "LABEL", + "inputs": { + "text": "Observation Monitoring", + "textColor": "#11110f", + "backgroundColor": "#f7f2ba", + "size": 1, + "borderWidth": 0.001, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 30 + }, + { + "id": "27", + "x": 12, + "y": 68, + "canvas": "0", + "width": 23, + "height": 7, + "type": "SPECTRUM_TABLE", + "inputs": { + "attribute": { + "device": "ska_mid/tm_subarray_node/1", + "attribute": "receptoridlist", + "label": "receptorIDList" + }, + "layout": "horizontal", + "showDevice": false, + "showAttribute": "Name", + "showIndex": false, + "showLabel": false, + "fontSize": 16 + }, + "order": 29 + }, + { + "id": "28", + "x": 51, + "y": 69, + "canvas": "0", + "width": 26, + "height": 20, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_sdp/elt/subarray_1", + "attribute": "receiveaddresses", + "label": "Receive Addresses" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": false, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 28 + }, + { + "id": "29", + "x": 19, + "y": 56, + "canvas": "0", + "width": 12, + "height": 4, + "type": "DEVICE_STATUS", + "inputs": { + "device": "ska_mid/tm_subarray_node/1", + "state": { + "device": null, + "attribute": null + }, + "showDeviceName": false, + "showStateString": true, + "showStateLED": true, + "LEDSize": 1, + "textSize": 1 + }, + "order": 27 + }, + { + "id": "30", + "x": 20, + "y": 59, + "canvas": "0", + "width": 7, + "height": 4, + "type": "LABEL", + "inputs": { + "text": "state:", + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 26 + }, + { + "id": "35", + "x": 56, + "y": 56, + "canvas": "0", + "width": 7, + "height": 4, + "type": "LABEL", + "inputs": { + "text": "state:", + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 25 + }, + { + "id": "36", + "x": 78, + "y": 76, + "canvas": "0", + "width": 7, + "height": 4, + "type": "LABEL", + "inputs": { + "text": "state:", + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 24 + }, + { + "id": "37", + "x": 100, + "y": 76, + "canvas": "0", + "width": 7, + "height": 4, + "type": "LABEL", + "inputs": { + "text": "state:", + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 23 + }, + { + "id": "38", + "x": 34, + "y": 56, + "canvas": "0", + "width": 7, + "height": 4, + "type": "LABEL", + "inputs": { + "text": "state:", + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 22 + }, + { + "id": "39", + "x": 41, + "y": 56, + "canvas": "0", + "width": 12, + "height": 4, + "type": "DEVICE_STATUS", + "inputs": { + "device": "mid_csp/elt/subarray_01", + "state": { + "device": null, + "attribute": null + }, + "showDeviceName": false, + "showStateString": true, + "showStateLED": true, + "LEDSize": 1, + "textSize": 1 + }, + "order": 21 + }, + { + "id": "40", + "x": 63, + "y": 56, + "canvas": "0", + "width": 12, + "height": 4, + "type": "DEVICE_STATUS", + "inputs": { + "device": "mid_sdp/elt/subarray_1", + "state": { + "device": null, + "attribute": null + }, + "showDeviceName": false, + "showStateString": true, + "showStateLED": true, + "LEDSize": 1, + "textSize": 1 + }, + "order": 20 + }, + { + "id": "42", + "x": 85, + "y": 76, + "canvas": "0", + "width": 12, + "height": 4, + "type": "DEVICE_STATUS", + "inputs": { + "device": "mid_d0003/elt/master", + "state": { + "device": null, + "attribute": null + }, + "showDeviceName": false, + "showStateString": true, + "showStateLED": true, + "LEDSize": 1, + "textSize": 1 + }, + "order": 19 + }, + { + "id": "43", + "x": 107, + "y": 76, + "canvas": "0", + "width": 12, + "height": 4, + "type": "DEVICE_STATUS", + "inputs": { + "device": "mid_d0004/elt/master", + "state": { + "device": null, + "attribute": null + }, + "showDeviceName": false, + "showStateString": true, + "showStateLED": true, + "LEDSize": 1, + "textSize": 1 + }, + "order": 18 + }, + { + "id": "54", + "x": 78, + "y": 51, + "canvas": "0", + "width": 19, + "height": 5, + "type": "LABEL", + "inputs": { + "text": "Dish Master 1", + "backgroundColor": "#f2b3b7", + "textColor": "#000", + "size": 1, + "borderWidth": 0.001, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 17 + }, + { + "id": "55", + "x": 100, + "y": 51, + "canvas": "0", + "width": 19, + "height": 5, + "type": "LABEL", + "inputs": { + "text": "Dish Master 2", + "backgroundColor": "#f2b3b7", + "textColor": "#000", + "size": 1, + "borderWidth": 0.001, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 16 + }, + { + "id": "56", + "x": 78, + "y": 60, + "canvas": "0", + "width": 19, + "height": 4, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_d0001/elt/master", + "attribute": "pointingstate", + "label": "pointingState" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Name", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 15 + }, + { + "id": "57", + "x": 100, + "y": 60, + "canvas": "0", + "width": 19, + "height": 4, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_d0002/elt/master", + "attribute": "pointingstate", + "label": "pointingState" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Name", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 14 + }, + { + "id": "58", + "x": 78, + "y": 56, + "canvas": "0", + "width": 7, + "height": 4, + "type": "LABEL", + "inputs": { + "text": "state:", + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 13 + }, + { + "id": "59", + "x": 100, + "y": 56, + "canvas": "0", + "width": 7, + "height": 4, + "type": "LABEL", + "inputs": { + "text": "state:", + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 12 + }, + { + "id": "60", + "x": 85, + "y": 56, + "canvas": "0", + "width": 12, + "height": 4, + "type": "DEVICE_STATUS", + "inputs": { + "device": "mid_d0001/elt/master", + "state": { + "device": null, + "attribute": null + }, + "showDeviceName": false, + "showStateString": true, + "showStateLED": true, + "LEDSize": 1, + "textSize": 1 + }, + "order": 11 + }, + { + "id": "61", + "x": 107, + "y": 56, + "canvas": "0", + "width": 12, + "height": 4, + "type": "DEVICE_STATUS", + "inputs": { + "device": "mid_d0002/elt/master", + "state": { + "device": null, + "attribute": null + }, + "showDeviceName": false, + "showStateString": true, + "showStateLED": true, + "LEDSize": 1, + "textSize": 1 + }, + "order": 10 + }, + { + "id": "62", + "x": 12, + "y": 22, + "canvas": "0", + "width": 8, + "height": 4, + "type": "LABEL", + "inputs": { + "text": "state:", + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "borderWidth": 0, + "borderColor": "#000000", + "font": "Helvetica", + "linkTo": "", + "customCss": "" + }, + "order": 9 + }, + { + "id": "63", + "x": 20, + "y": 22, + "canvas": "0", + "width": 11, + "height": 4, + "type": "DEVICE_STATUS", + "inputs": { + "device": "ska_mid/tm_central/central_node", + "state": { + "device": null, + "attribute": null + }, + "showDeviceName": false, + "showStateString": true, + "showStateLED": true, + "LEDSize": 1, + "textSize": 1 + }, + "order": 8 + }, + { + "id": "64", + "x": 85, + "y": 36, + "canvas": "0", + "width": 6, + "height": 5, + "type": "COMMAND_EXECUTOR", + "inputs": { + "command": { + "device": "ska_mid/tm_subarray_node/1", + "command": "End" + }, + "title": "", + "requireConfirmation": false, + "displayOutput": false, + "cooldown": 0, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 7 + }, + { + "id": "65", + "x": 100, + "y": 36, + "canvas": "0", + "width": 8, + "height": 5, + "type": "COMMAND_EXECUTOR", + "inputs": { + "command": { + "device": "ska_mid/tm_subarray_node/1", + "command": "Restart", + "acceptedType": "DevVoid" + }, + "title": "", + "requireConfirmation": false, + "displayOutput": false, + "cooldown": 0, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 6 + }, + { + "id": "66", + "x": 78, + "y": 64, + "canvas": "0", + "width": 19, + "height": 7, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_d0001/elt/master", + "attribute": "dishmode", + "label": "dishMode" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Name", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 5 + }, + { + "id": "67", + "x": 100, + "y": 64, + "canvas": "0", + "width": 19, + "height": 7, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_d0002/elt/master", + "attribute": "dishmode", + "label": "dishMode" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Name", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 4 + }, + { + "id": "68", + "x": 78, + "y": 84, + "canvas": "0", + "width": 19, + "height": 7, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_d0003/elt/master", + "attribute": "dishmode", + "label": "dishMode" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Name", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 3 + }, + { + "id": "69", + "x": 100, + "y": 84, + "canvas": "0", + "width": 19, + "height": 7, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_d0004/elt/master", + "attribute": "dishmode", + "label": "dishMode" + }, + "precision": 2, + "showDevice": false, + "showAttribute": "Name", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 2 + }, + { + "id": "70", + "x": 109, + "y": 36, + "canvas": "0", + "width": 10, + "height": 5, + "type": "COMMAND_EXECUTOR", + "inputs": { + "command": { + "device": "ska_mid/tm_subarray_node/1", + "command": "ObsReset", + "acceptedType": "DevVoid" + }, + "title": "", + "requireConfirmation": false, + "displayOutput": false, + "cooldown": 0, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 1 + }, + { + "id": "71", + "x": 12, + "y": 81, + "canvas": "0", + "width": 34, + "height": 5, + "type": "ATTRIBUTE_DISPLAY", + "inputs": { + "attribute": { + "device": "mid_d0001/elt/master", + "attribute": "rxcapturingdata", + "label": "capturingData" + }, + "precision": 2, + "showDevice": true, + "showAttribute": "Label", + "scientificNotation": false, + "showEnumLabels": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 0 + }, + { + "id": "72", + "x": 33, + "y": 23, + "canvas": "0", + "width": 17, + "height": 4, + "type": "COMMAND_EXECUTOR", + "inputs": { + "command": { + "device": "ska_mid/tm_central/central_node", + "command": "Reset", + "acceptedType": "DevVoid" + }, + "title": "", + "requireConfirmation": false, + "displayOutput": false, + "cooldown": 0, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 48 + }, + { + "id": "73", + "x": 52, + "y": 15, + "canvas": "0", + "width": 67, + "height": 5, + "type": "command_file", + "inputs": { + "uploadBtnLabel": "Upload File", + "buttonLabel": "", + "command": { + "device": "ska_mid/tm_central/central_node", + "command": "AssignResources", + "acceptedType": "DevString" + }, + "showDevice": false, + "showCommand": false, + "requireConfirmation": true, + "displayOutput": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 14, + "font": "Helvetica" + }, + "order": 49 + }, + { + "id": "74", + "x": 52, + "y": 22, + "canvas": "0", + "width": 67, + "height": 5, + "type": "command_file", + "inputs": { + "uploadBtnLabel": "Upload File", + "buttonLabel": "", + "command": { + "device": "ska_mid/tm_central/central_node", + "command": "ReleaseResources", + "acceptedType": "DevString" + }, + "showDevice": false, + "showCommand": false, + "requireConfirmation": true, + "displayOutput": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 14, + "font": "Helvetica" + }, + "order": 50 + }, + { + "id": "75", + "x": 12, + "y": 36, + "canvas": "0", + "width": 43, + "height": 5, + "type": "command_file", + "inputs": { + "uploadBtnLabel": "Upload File", + "buttonLabel": "", + "command": { + "device": "ska_mid/tm_subarray_node/1", + "command": "Configure", + "acceptedType": "DevString" + }, + "showDevice": false, + "showCommand": false, + "requireConfirmation": true, + "displayOutput": true, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 14, + "font": "Helvetica" + }, + "order": 51 + }, + { + "id": "76", + "x": 76, + "y": 36, + "canvas": "0", + "width": 6, + "height": 4, + "type": "COMMAND_EXECUTOR", + "inputs": { + "command": { + "device": "ska_mid/tm_subarray_node/1", + "command": "Off", + "acceptedType": "DevVoid" + }, + "title": "", + "requireConfirmation": true, + "displayOutput": true, + "cooldown": 0, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 52 + }, + { + "id": "77", + "x": 12, + "y": 76, + "canvas": "0", + "width": 18, + "height": 4, + "type": "COMMAND_EXECUTOR", + "inputs": { + "command": { + "device": "ska_mid/tm_subarray_node/1", + "command": "ReleaseAllResources", + "acceptedType": "DevVoid" + }, + "title": "", + "requireConfirmation": true, + "displayOutput": true, + "cooldown": 0, + "textColor": "#000000", + "backgroundColor": "#ffffff", + "size": 1, + "font": "Helvetica" + }, + "order": 53 + } + ] +} \ No newline at end of file diff --git a/csp-lmc-mid/test-harness/Makefile b/csp-lmc-mid/test-harness/Makefile index bb172a34963f4e093e8c1064c426278997cfef64..f73b9fc5b607bf5bc26a9c787e8f301537fe971c 100644 --- a/csp-lmc-mid/test-harness/Makefile +++ b/csp-lmc-mid/test-harness/Makefile @@ -17,7 +17,7 @@ test: retry --max=15 -- tango_admin --ping-device mid_csp/elt/master retry --max=15 -- tango_admin --ping-device mid_csp/elt/subarray_01 retry --max=15 -- tango_admin --ping-device mid_csp/elt/subarray_02 - cd /app && pytest tests| tee integration-test.stdout + cd /app && pytest $(if $(findstring all,$(MARK)),, -m '$(MARK)')| tee integration-test.stdout mkdir -p build/reports && \ if [ -d build ]; then \ mv /app/integration-test.stdout ./build/csp-lmc-mid-setup-test.stdout; \ diff --git a/csp-lmc-mid/tests/integration/MidCspSubarray_test.py b/csp-lmc-mid/tests/integration/MidCspSubarray_test.py index 5e1a2286919665242cfa582034ada8e03698433c..678009b0982acb8505c776c2a56b7a414a305c13 100755 --- a/csp-lmc-mid/tests/integration/MidCspSubarray_test.py +++ b/csp-lmc-mid/tests/integration/MidCspSubarray_test.py @@ -16,7 +16,6 @@ import time import random import numpy as np import logging -import unittest import pytest import json @@ -45,7 +44,7 @@ def prepare_configuration_string(filename="test_ConfigureScan_ADR4.json"): # Device test case @pytest.mark.usefixtures("midcsp_master", "midcsp_subarray01", "cbf_subarray01") -class TestBase(unittest.TestCase): +class TestBase(object): fixture_names = () @pytest.fixture(autouse=True) @@ -93,7 +92,8 @@ class TestCspSubarray(TestBase): obs_state = self.midcsp_subarray01.obsState if obs_state == ObsState.IDLE: self._release_all_receptors() - + prober_obs_state = Probe(self.midcsp_subarray01, "obsState", ObsState.EMPTY, f"CSP Subarray not EMPTY") + Poller(4, 0.2).check(prober_obs_state) def _setup_subarray_off(self): """ Set the subarray state to OFF-EMPTY @@ -176,6 +176,7 @@ class TestCspSubarray(TestBase): 'dish': { 'receptorIDList': list(map(str, argin))}} return json.dumps(param) + @pytest.mark.init_EMPTY def test_AFTER_initialization(self): """ Test for State after CSP startup. @@ -188,9 +189,116 @@ class TestCspSubarray(TestBase): Poller(4, 0.2).check(prober_subarray_state) prober_subarray_obsstate = Probe(self.midcsp_subarray01, "obsState", ObsState.EMPTY, f"CSP Subarray not EMPTY") Poller(4, 0.2).check(prober_subarray_obsstate) + + @pytest.mark.init_IDLE + def test_re_initialization_when_IDLE(self): + """ + Test for re-initialization of mid-csp device after a restart of + the Tango device. + The CspSubarray aligns to the state/obsstate of CBFSubarray: ON/IDLE + """ + self._setup_subarray() + json_config= self._build_resources([1,2]) + self.midcsp_subarray01.AssignResources(json_config) + prober_subarray_obsstate = Probe(self.midcsp_subarray01, "obsState", ObsState.IDLE, f"CSP Subarray not IDLE") + Poller(4, 0.2).check(prober_subarray_obsstate) + # open a proxy to the adminstrative server + dserver_proxy = tango.DeviceProxy(self.midcsp_subarray01.adm_name()) + dserver_proxy. devrestart('mid_csp/elt/subarray_01') + prober_subarray_state = Probe(self.midcsp_subarray01, "State", DevState.ON, f"CSP Subarray not ON after re-initialization") + Poller(10, 0.2).check(prober_subarray_state) + prober_subarray_obsstate = Probe(self.midcsp_subarray01, "obsState", ObsState.IDLE, f"CSP Subarray not IDLE after re-initialization") + Poller(4, 0.2).check(prober_subarray_obsstate) + @pytest.mark.init_READY + def test_re_initialization_when_READY(self): + """ + Test for re-initialization of mid-csp device after the restart of + the Tango device. + The CspSubarray aligns to the state/obsstate of CBFSubarray: ON/READY + """ + self._setup_subarray() + self._configure_scan() + # open a proxy to the adminstrative server + dserver_proxy = tango.DeviceProxy(self.midcsp_subarray01.adm_name()) + dserver_proxy. devrestart('mid_csp/elt/subarray_01') + prober_subarray_state = Probe(self.midcsp_subarray01, "State", DevState.ON, f"CSP Subarray not ON after re-initialization") + Poller(10, 0.2).check(prober_subarray_state) + prober_subarray_obsstate = Probe(self.midcsp_subarray01, "obsState", ObsState.READY, f"CSP Subarray not READY after re-initialization") + Poller(4, 0.2).check(prober_subarray_obsstate) + + @pytest.mark.init_SCANNING + @pytest.mark.parametrize("elapsed_time", [0.1, 0.2, 0.3, 0.4, 0.5,1,2]) + def test_re_initialization_when_SCANNING(self, elapsed_time): + """ + Test for re-initialization of mid-csp device after the of the + Tango device. + The CspSubarray aligns to the state/obsstate of CBFSubarray: ON/SCANNING. + The tests ends with the CSP Subarray in READY. + Test is executed several times with different wait time (dealys) before + sending the EndScan. + """ + self._setup_subarray() + self._configure_scan() + self.midcsp_subarray01.Scan('2') + prober_subarray_obsstate = Probe(self.midcsp_subarray01, "obsState", ObsState.SCANNING, f'CSP Subarray not SCANNING') + Poller(10, 0.2).check(prober_subarray_obsstate) + # wait for a variable time + time.sleep(elapsed_time) + # open a proxy to the adminstrative server + dserver_proxy = tango.DeviceProxy(self.midcsp_subarray01.adm_name()) + # restart the device to force a reinitialization + dserver_proxy. devrestart('mid_csp/elt/subarray_01') + prober_subarray_state = Probe(self.midcsp_subarray01, "State", DevState.ON, f"CSP Subarray not ON after re-initialization") + Poller(10, 0.2).check(prober_subarray_state) + prober_subarray_obsstate = Probe(self.midcsp_subarray01, "obsState", ObsState.SCANNING, f"CSP Subarray not SCANNING after re-initialization") + Poller(4, 0.2).check(prober_subarray_obsstate) + # wait a variable time before sending the endscan + time.sleep(elapsed_time) + self.midcsp_subarray01.EndScan() + prober_subarray_obsstate = Probe(self.midcsp_subarray01, "obsState", ObsState.READY, f'CSP Subarray not SCANNING') + Poller(5, 0.2).check(prober_subarray_obsstate) + + @pytest.mark.init_ABORTED + def test_re_initialization_when_ABORTED(self): + """ + Test for re-initialization of mid-csp device after the restart of the + Tango device. + The CspSubarray align to the state/obsstate of CBFSubarray: ON/ABORTED + """ + self._setup_subarray() + self._assign_receptors() + self.midcsp_subarray01.Abort() + prober_subarray_obsstate = Probe(self.midcsp_subarray01, "obsState", ObsState.ABORTED, f'CSP Subarray not ABORTED') + # open a proxy to the adminstrative server + dserver_proxy = tango.DeviceProxy(self.midcsp_subarray01.adm_name()) + dserver_proxy. devrestart('mid_csp/elt/subarray_01') + prober_subarray_state = Probe(self.midcsp_subarray01, "State", DevState.ON, f"CSP Subarray not ON after re-initialization") + Poller(10, 0.2).check(prober_subarray_state) + prober_subarray_obsstate = Probe(self.midcsp_subarray01, "obsState", ObsState.ABORTED, f"CSP Subarray not ABORTED after re-initialization") + Poller(4, 0.2).check(prober_subarray_obsstate) + + @pytest.mark.init_FAULT + def test_re_initialization_when_FAULT(self): + """ + Test for re-initialization of mid-csp device after killing the Tango device. + The CspSubarray align to the state/obsstate of CBFSubarray: ON/IDLE + """ + self._setup_subarray() + self._assign_receptors() + configuration_string = prepare_configuration_string("test_ConfigureScan_invalid_cbf_json.json") + self.midcsp_subarray01.Configure(configuration_string) + prober_subarray_obsstate = Probe(self.midcsp_subarray01, "obsState", ObsState.FAULT, f'CSP Subarray not FAULT') + Poller(10, 0.2).check(prober_subarray_obsstate) + # open a proxy to the adminstrative server + dserver_proxy = tango.DeviceProxy(self.midcsp_subarray01.adm_name()) + dserver_proxy. devrestart('mid_csp/elt/subarray_01') + prober_subarray_state = Probe(self.midcsp_subarray01, "State", DevState.ON, f"CSP Subarray not ON after re-initialization") + Poller(10, 0.2).check(prober_subarray_state) + prober_subarray_obsstate = Probe(self.midcsp_subarray01, "obsState", ObsState.FAULT, f"CSP Subarray not FAULT after re-initialization") + Poller(4, 0.2).check(prober_subarray_obsstate) + def test_subarray_state_AFTER_on_command_execution(self): - """ Test for State after CSP startup. The CspSubarray State at start is OFF. @@ -204,20 +312,29 @@ class TestCspSubarray(TestBase): prober_subarray_state = Probe(self.midcsp_subarray01, "State", DevState.ON, f"CSP Subarray not OFF") Poller(4, 0.2).check(prober_subarray_state) + @pytest.mark.off_resourcing def test_OffCommand_after_RESOURCING(self): """ Test that the Off command send the device in OFF-EMPTY if it is ON-RESOURCING """ - self._setup_subarray + self._setup_subarray() + subarray_state = self.midcsp_subarray01.State() + obs_state = self.midcsp_subarray01.obsState + LOGGER.info("CSPSubarray state before test:{}-{}".format(subarray_state, obs_state)) json_config= self._build_resources([1,2]) self.midcsp_subarray01.AssignResources(json_config) + subarray_state = self.midcsp_subarray01.State() + obs_state = self.midcsp_subarray01.obsState + LOGGER.info("CSPSubarray state before test:{}-{}".format(subarray_state, obs_state)) self.midcsp_subarray01.Off() prober_subarray_state = Probe(self.midcsp_subarray01, "State", DevState.OFF, f"CSP Subarray not OFF") Poller(4, 0.2).check(prober_subarray_state) prober_subarray_obsstate = Probe(self.midcsp_subarray01, "obsState", ObsState.EMPTY, f"CSP Subarray not EMPTY") Poller(4, 0.2).check(prober_subarray_obsstate) receptors = self.midcsp_subarray01.assignedReceptors + LOGGER.info(f'type of {type(receptors)}') + LOGGER.info(f'list of receptors{receptors}') assert not receptors.any(), f"CSP Subarray is not empty" def test_OffCommand_after_IDLE(self): @@ -266,7 +383,8 @@ class TestCspSubarray(TestBase): Poller(10, 0.2).check(prober_subarray_obsstate) receptors = self.midcsp_subarray01.assignedReceptors assert not receptors.any(), f"CSP Subarray is not empty" - + + @pytest.mark.off def test_OffCommand_after_SCANNING(self): """ Test that the Off command send the device in OFF-EMPTY @@ -656,11 +774,15 @@ class TestCspSubarray(TestBase): prober_obs_state = Probe(self.midcsp_subarray01, "obsState", ObsState.IDLE, f"CSP Subarray not IDLE") Poller(4, 0.2).check(prober_obs_state) - @pytest.mark.csp_k8s - def test_send_abort_WHILE_in_configuring(self): + @pytest.mark.abort + #@pytest.mark.parametrize("elapsed_time", [0.4, 0.41, 0.42, 0.43, 0.44]) + @pytest.mark.parametrize("elapsed_time", [0.42, 0.43, 0.44]) + @pytest.mark.parametrize('execution_number', range(2)) + def test_send_abort_WHILE_in_configuring(self, elapsed_time, execution_number): """ - Configure the CSP Subarray with a JSon string including - the new ADR22 fields. + Test that the subarray is able to handle the Abort command when issued + at any time. + The test is repeated several times with different delay times. """ self._setup_subarray() self._assign_receptors() @@ -671,7 +793,7 @@ class TestCspSubarray(TestBase): LOGGER.info(f"Configuring CSP subarray01") configuration_string = prepare_configuration_string() (result_code, msg) = self.midcsp_subarray01.Configure(configuration_string) - #time.sleep(0.1) + time.sleep(elapsed_time) self.midcsp_subarray01.Abort() # check prober_subarray_obstate = Probe(self.midcsp_subarray01, 'obsState', ObsState.ABORTED, @@ -721,26 +843,20 @@ class TestCspSubarray(TestBase): prober_obs_state = Probe(self.midcsp_subarray01, "obsState", ObsState.EMPTY, f"CSP Subarray not EMPTY") Poller(4, 0.2).check(prober_obs_state) - ''' - def test_configureScan_with_subarray_ready(self, midcsp_subarray01, midcsp_master): + def test_configureScan_WHEN_subarray_ready(self, midcsp_subarray01, midcsp_master): """ Test that the Configure() command is issued when the Subarray state already READY """ + self._configure_scan() obs_state = midcsp_subarray01.obsState assert obs_state == ObsState.READY - f = open(file_path +"/test_ConfigureScan_basic.json") - obs_state = midcsp_subarray01.obsState - try: - midcsp_subarray01.Configure(f.read().replace("\n", "")) - except tango.DevFailed as tango_err: - print("configure error:", tango_err.args[0].desc) - obs_state = midcsp_subarray01.obsState - f.close() - time.sleep(5) - obs_state = midcsp_subarray01.obsState - assert obs_state == ObsState.READY + configuration_string = prepare_configuration_string("test_ConfigureScan_basic.json") + self.midcsp_subarray01.Configure(configuration_string) + prober_obs_state = Probe(self.midcsp_subarray01, "obsState", ObsState.READY, f"CSP Subarray not READY") + Poller(4, 0.2).check(prober_obs_state) +''' def test_remove_receptors_when_ready(self, midcsp_subarray01): """ Test that the complete deallocation of receptors fails diff --git a/csp-lmc-mid/tests/unit/midcspsubarray_unit_test.py b/csp-lmc-mid/tests/unit/midcspsubarray_unit_test.py index 2478b499d5be30cea589d17873865955df247384..89a63ab140607f0663acc0306977261bedddaaff 100644 --- a/csp-lmc-mid/tests/unit/midcspsubarray_unit_test.py +++ b/csp-lmc-mid/tests/unit/midcspsubarray_unit_test.py @@ -75,6 +75,9 @@ def test_midcspsubarray_state_AFTER_on_command_WITH_exception_raised_by_subeleme proxies_to_mock=proxies_to_mock) as tango_context: cbf_subarray_device_proxy_mock.On.side_effect = raise_devfailed_exception pss_subarray_device_proxy_mock.On.side_effect = return_ok + state = tango_context.device.State() + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() # Note: the state is in ALARM because the device uses forwarded attributes. #assert tango_context.device.State() == DevState.FAULT @@ -105,6 +108,8 @@ def test_midcspsubarray_state_AFTER_on_command_WITH_failed_code_returned_by_sube proxies_to_mock=proxies_to_mock) as tango_context: cbf_subarray_device_proxy_mock.On.side_effect = return_failed pss_subarray_device_proxy_mock.On.side_effect = return_ok + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() #assert tango_context.device.State() == DevState.FAULT assert tango_context.device.obsState == ObsState.EMPTY @@ -133,6 +138,8 @@ def test_midcspsubarray_state_AFTER_on_command_WITH_failed_code_returned_by_pss_ proxies_to_mock=proxies_to_mock) as tango_context: cbf_subarray_device_proxy_mock.On.side_effect = return_ok pss_subarray_device_proxy_mock.On.side_effect = return_failed + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() #assert tango_context.device.State() == DevState.ON assert tango_context.device.obsState == ObsState.EMPTY @@ -162,6 +169,8 @@ def test_midcspsubarray_state_after_on_forwarded_to_subelement_subarray(): proxies_to_mock=proxies_to_mock) as tango_context: cbf_subarray_device_proxy_mock.On.side_effect = return_ok pss_subarray_device_proxy_mock.On.side_effect = return_ok + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() #assert tango_context.device.State() == DevState.ON assert tango_context.device.obsState == ObsState.EMPTY @@ -232,6 +241,8 @@ def test_removereceptors_command_WHEN_subarray_is_in_wrong_state(): mock_do.return_value = (ResultCode.OK, "AssignResources OK") mock_on_do.return_value = (ResultCode.OK, "On command OK") mock_configure_do.return_value = (ResultCode.OK, "On command OK") + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() param = { 'subarrayID': 1, @@ -281,6 +292,8 @@ def test_midcspsubarray_obsstate_WHEN_cbfsubarray_raises_an_exception(): mock.patch('csp_lmc_mid.receptors.Receptors.unassigned_ids') as mock_unassigned_ids: cbf_subarray_device_proxy_mock.On.side_effect = return_ok pss_subarray_device_proxy_mock.On.side_effect = return_ok + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() dummy_event = create_dummy_event(cbf_subarray_fqdn, 'obsstate', ObsState.EMPTY) event_subscription_map[cbf_subarray_state_attr](dummy_event) @@ -325,6 +338,8 @@ def test_midcspsubarray_obsstate_AFTER_add_receptors_to_cbf_subarray(): proxies_to_mock=proxies_to_mock) as tango_context: cbf_subarray_device_proxy_mock.On.side_effect = return_ok pss_subarray_device_proxy_mock.On.side_effect = return_ok + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() dummy_event = create_dummy_event(cbf_subarray_fqdn, 'obstate',ObsState.IDLE) event_subscription_map[cbf_subarray_state_attr](dummy_event) @@ -385,6 +400,8 @@ def test_midcspsubarray_obsstate_AFTER_configure(): mock_do.return_value = (ResultCode.OK, "AssignResources OK") mock_on_do.return_value = (ResultCode.OK, "On command OK") mock_delay_expected.return_value = 2 + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() param = { 'subarrayID': 1, @@ -440,6 +457,8 @@ def test_midcspsubarray_invoke_configure_WHILE_gotoidle_is_running(): mock_len.return_value = len(receptor_list) mock_do.return_value = (ResultCode.OK, "AssignResources OK") mock_on_do.return_value = (ResultCode.OK, "On command OK") + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() param = { 'subarrayID': 1, @@ -490,6 +509,8 @@ def test_midcspsubarray_obsstate_AFTER_configure_WITH_wrong_json(): mock_len.return_value = len(receptor_list) mock_do.return_value = (ResultCode.OK, "AssignResources OK") mock_on_do.return_value = (ResultCode.OK, "On command OK") + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() param = { 'subarrayID': 1, @@ -537,13 +558,14 @@ def test_midcspsubarray_obsstate_AFTER_timeout_during_configuration(): mock_do.return_value = (ResultCode.OK, "AssignResources OK") mock_on_do.return_value = (ResultCode.OK, "On command OK") mock_delay_expected.return_value = 2 + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() param = { 'subarrayID': 1, 'dish': {'receptorIDList': receptor_list}} json_config = json.dumps(param) tango_context.device.AssignResources(json_config) - #assert tango_context.device.obsState == ObsState.IDLE configuration_string = load_json_file("test_ConfigureScan_ADR4.json") tango_context.device.Configure(configuration_string) @@ -589,6 +611,8 @@ def test_midcspsubarray_obsstate_AFTER_cbfsubarray_fault_during_configuration(): mock_do.return_value = (ResultCode.OK, "AssignResources OK") mock_on_do.return_value = (ResultCode.OK, "On command OK") mock_delay_expected.return_value = 2 + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() param = { 'subarrayID': 1, @@ -641,6 +665,8 @@ def test_midcspsubarray_obsstate_AFTER_abort_request_during_configuration(): mock_do.return_value = (ResultCode.OK, "AssignResources OK") mock_on_do.return_value = (ResultCode.OK, "On command OK") mock_delay_expected.return_value = 2 + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() param = { 'subarrayID': 1, @@ -693,6 +719,8 @@ def test_midcspsubarray_obsstate_WHEN_cbfsubarray_is_in_fault_during_abort_reque mock_do.return_value = (ResultCode.OK, "AssignResources OK") mock_on_do.return_value = (ResultCode.OK, "On command OK") mock_delay_expected.return_value = 2 + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() param = { 'subarrayID': 1, @@ -752,6 +780,8 @@ def test_midcspsubarray_obsstate_WHEN_abort_invoked_in_resetting(): mock_do.return_value = (ResultCode.OK, "AssignResources OK") mock_on_do.return_value = (ResultCode.OK, "On command OK") mock_delay_expected.return_value = 2 + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() param = { 'subarrayID': 1, @@ -807,6 +837,8 @@ def test_midcspsubarray_obsstate_WHEN_restart_invoked_after_cspsubarray_aborted( mock_do.return_value = (ResultCode.OK, "AssignResources OK") mock_on_do.return_value = (ResultCode.OK, "On command OK") mock_delay_expected.return_value = 2 + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() param = { 'subarrayID': 1, @@ -847,6 +879,8 @@ def test_midcspsubarray_state_AFTER_on_command_WITH_failed_code_returned_by_pss_ proxies_to_mock=proxies_to_mock) as tango_context: cbf_subarray_device_proxy_mock.On.side_effect = return_ok pss_subarray_device_proxy_mock.On.side_effect = return_failed + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() #assert tango_context.device.State() == DevState.ON assert tango_context.device.obsState == ObsState.EMPTY @@ -934,6 +968,8 @@ def test_midcspsubarray_obsstate_WHEN_timeout_in_abort_request_during_configurin mock_do.return_value = (ResultCode.OK, "AddReceptors OK") mock_on_do.return_value = (ResultCode.OK, "On command OK") mock_delay_expected.return_value = 2 + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() tango_context.device.AddReceptors(receptor_list) configuration_string = load_json_file("test_ConfigureScan_ADR4.json") @@ -981,6 +1017,8 @@ def test_midcspsubarray_obsstate_AFTER_configure_WITH_cbf_returning_FAULT(): mock_len.return_value = len(receptor_list) mock_do.return_value = (ResultCode.OK, "AddReceptors OK") mock_on_do.return_value = (ResultCode.OK, "On command OK") + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() tango_context.device.AddReceptors(receptor_list) configuration_string = load_json_file("test_ConfigureScan_ADR4.json") @@ -1027,6 +1065,8 @@ def test_midcspsubarray_obsstate_AFTER_end_scan(): mock_do.return_value = (ResultCode.OK, "AddReceptors OK") mock_on_do.return_value = (ResultCode.OK, "On command OK") #mock_configure_do.return_value = (ResultCode.OK, "Configure command OK") + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() tango_context.device.AddReceptors(receptor_list) configuration_string = load_json_file("test_ConfigureScan_ADR4.json") @@ -1076,6 +1116,8 @@ def test_midcspsubarray_obsreset(): mock_len.return_value = len(receptor_list) mock_do.return_value = (ResultCode.OK, "AddReceptors OK") mock_on_do.return_value = (ResultCode.OK, "On command OK") + prober_state = Probe(tango_context.device, 'State', DevState.OFF, f"Wrong CspSubarray state") + Poller(3, 0.1).check(prober_state) tango_context.device.On() tango_context.device.AddReceptors(receptor_list) configuration_string = load_json_file("test_ConfigureScan_ADR4.json")