=========================== How to use the control mode =========================== .. important:: The original :py:class:`ska_control_model.ControlMode` enum has been deprecated since ska-control-model 1.3.0 used in ska-tango-base 1.7.0. This guide explains how the new :py:class:`ska_control_model.future.ControlMode` should be used according to ADR-114. The optional :attr:`~.ControlModeMixin.controlMode` Tango attribute can be added to a device by inheriting from :py:class:`~.ControlModeMixin`. This will allow clients to instruct your Tango device when to monitor its component and when to allow commands that affect its component. Subclasses must override the :meth:`.start_monitoring_component` and :meth:`.stop_monitoring_component` methods, which will be called whenever the :attr:`~.ControlModeMixin.controlMode` transitions to/from a monitoring state. The :meth:`.start_monitoring_component` method should call :meth:`~._base_interface.BaseInterface.report_health` before returning. If the connection to the component happens asynchronously, then use `healthState.FAILED` to report that the connection has not yet been established. Subclasses can also call the :meth:`.check_component_controlled` method from their is-allowed methods to raise an informative exception if we are not in :class:`ControlMode.MONITOR_AND_CONTROL ` when a command is invoked. Typically, when using long running commands, this will want to be done at enqueue time. For example, the following :class:`.PoweredInterface` device starts and stops communicating with its component when it is requested to start/stop monitoring and checks if it is controlling before adjusting the power level via its long running commands. .. code:: python import ska_control_model as scm import ska_tango_base.future as stb class MyDevice(stb.ControlModeMixin, stb.LRCMixin, stb.PoweredInterface): ... def start_monitoring_component(self) -> None: self.report_health(scm.HealthState.FAILED, ["Initial communication not yet established."]) self.component.connect() def stop_monitoring_component(self) -> None: self.component.disconnect() ... def is_On_allowed( self, request_type: stb.LRCReqType = stb.LRCReqType.ENQUEUE_REQ, # type: ignore[override] ) -> bool: """Return True if On is allowed.""" if request_type == stb.LRCReqType.ENQUEUE_REQ: self.check_component_controlled() return super().is_On_allowed(request_type) @stb.submit_lrc_task def execute_On(self) -> stb.type_hints.TaskFunctionType: ... def is_Off_allowed( self, request_type: stb.LRCReqType = stb.LRCReqType.ENQUEUE_REQ, # type: ignore[override] ) -> bool: """Return True if On is allowed.""" if request_type == stb.LRCReqType.ENQUEUE_REQ: self.check_component_controlled() return super().is_Off_allowed(request_type) @stb.submit_lrc_task def execute_Off(self) -> stb.type_hints.TaskFunctionType: ... ...