Migrating to 1.5
This migration guide lists all the deprecations introduced by ska-tango-base release 1.5.0.
Assigning NoValue to signal deprecated
The ska-tango-base 1.4.0 release introduced the signal bus mechanism and attribute_from_signal attribute decorator, with a special NoValue type that can be assigned to Signal objects.
Rationale
The original intent was to have NoValue serve two distinct purposes when assigned to a signal:
To automatically set the quality of an attribute linked to the signal to
ATTR_INVALID.To delete the signal’s value stored on the bus when it’s initialised with
stored=True.
However, the mistake with the original implementation was to not rather have None assigned to an attribute’s signal set the attribute’s quality to ATTR_INVALID (and consequently also its value to None). With the ska-tango-base 1.5.0 release assigning None to an attribute’s signal does this as well.
Another oversight was not originally implementing a __delete__ method in the Signal descriptor. With the ska-tango-base 1.5.0 release using the del keyword on a signal will delete the value stored on the bus without emitting anything.
This means the two functions above are now decoupled from one another and as a result assigning NoValue to a Signal object has been deprecated. NoValue is only used as the default for a signal’s initial_value to distinguish from None, which is a valid initial value to emit.
Preparing for removal
Assign
Noneinstead ofNoValueto a signal to automatically set a linked attribute’s quality toATTR_INVALID.Use the
delkeyword on a signal instantiated withstored=Trueinstead of assigningNoValueif you have to delete its last value stored on the bus.
Warning
Assigning NoValue to a signal will raise an exception in the next major release.
obsMode attribute becoming optional and a spectrum
The obsMode attribute with a scalar type is deprecated. A deprecation warning will be emitted at initialisation time if the obsMode attribute is a scalar. In the next major release this attribute will be optional with a spectrum data type.
Rationale
Some devices that support observing modes support multiple concurrent modes so their observer mode attribute needs to be a spectrum. For devices that only support a single concurrent observing mode it is
preferable to still have a specturm attribute for consistency. Some devices with an observing state may not support any observing mode at all, therefore this attribute should be an optional part of the ObsInterface.
Preparing for type change
Device’s inheriting from ObsInterface should use standard_obs_mode() to override the attribute to have a spectrum type or assign obsMode = None at class scope to disable the attribute. When using the spectrum observing mode, assigning to the self._obs_mode signal will push new Tango events and update obsMode attribute.
For example,
import ska_control_model as scm
import ska_tango_base as stb
class WithSpectrumObsMode(stb.obs.ObsInterface):
_obs_mode, obsMode = stb.obs.standard_obs_mode()
def _update_obs_mode(self, new_obs_mode: list[scm.ObsMode]) -> None:
"""Example method for updating the spectrum observing mode."""
self._obs_mode = new_obs_mode
...
class NoObsMode(stb.obs.ObsInterface):
obsMode = None
Writing to _health_state deprecated
Updating the healthState attribute by directly assigning to the _health_state signal has been deprecated and will emit a deprecation warning. Instead the report_health() method should be used to update the healthState and healthInfo attributes in tandem. In the next major release, emitting from _health_state directly will raise an exception.
The last emitted health state value can still be read via the _health_state and this will not be removed.
Rationale
ADR-128 places requirements on the healthInfo attribute based on the current value of the healthState, as such these attributes are coupled and it makes sense to update these attributes together. The new report_health() method ensures that the rules specified by ADR-128 are being followed. Also, the report_health() method will ensure that the attributes have the same time stamp if they change at the same time, allowing users to correlate the values in the archiver.
Preparing for removal
Replace assignments of the _health_state attribute with calls to report_health(). This requires providing a non-empty health info list for HealthState.DEGRADED and HealthState.FAILED. For example, the following device has a monitoring loop that collects health issues and then reports HealthState.FAILED if any are encountered.
import ska_control_model as scm
import ska_tango_base as stb
class MyDevice(stb.base.BaseInterface):
def monitoring(self) -> None:
while True:
health_infos = []
# ... added entries to health_infos as we detect issues
if health_infos:
self.report_health(scm.HealthState.FAILED, health_infos)
else:
self.report_health(scm.HealthState.OK, health_infos)
# ...
The report_health() method does not support HealthState.UNKNOWN and you should use HealthState.FAILED with an appropriate message instead.