Skip to content
Snippets Groups Projects
Commit 8c5a7b59 authored by Jan David Mol's avatar Jan David Mol
Browse files

L2SS-624: Updated boot procedure in jupyter notebook test script

parent 263caa9f
No related branches found
No related tags found
1 merge request!244L2SS-624: Add summarizing attributes for state, improve/fix boot procedure of various devices
Showing with 149 additions and 24 deletions
%% Cell type:markdown id:6bdc7054 tags: %% Cell type:markdown id:6bdc7054 tags:
# Test LRx.y: Test Name # Test LRx.y: Test Name
This notebook documents test output. This notebook documents test output.
Instructions: Instructions:
1. *PRESS File -> Make a Copy*, 1. *PRESS File -> Make a Copy*,
1. Rename the notebook to the name of the test, 1. Rename the notebook to the name of the test,
1. Update the title at the top of this section, 1. Update the title at the top of this section,
1. Fill in the sections with empty blocks with code and text, 1. Fill in the sections with empty blocks with code and text,
1. Execute the provided initialisation code, 1. Execute the provided initialisation code,
1. Run the tests, 1. Run the tests,
1. *Rerun everything top to bottom to make sure the notebook is correct*, 1. *Rerun everything top to bottom to make sure the notebook is correct*,
1. Fill in the results & verdict. 1. Fill in the results & verdict.
1. Export the Jupyter Notebook to PDF and upload the file to the Polarion test results page. 1. Export the Jupyter Notebook to PDF and upload the file to the Polarion test results page.
1. ...and you're done! 1. ...and you're done!
%% Cell type:markdown id:63785004 tags: %% Cell type:markdown id:63785004 tags:
## Author ## Author
Descibe who ran this test, and who helped (if applicable): Descibe who ran this test, and who helped (if applicable):
%% Cell type:markdown id:3c720d4b tags: %% Cell type:markdown id:3c720d4b tags:
(your name) (your name)
%% Cell type:markdown id:ff837bcb tags: %% Cell type:markdown id:ff837bcb tags:
## Timestamp ## Timestamp
This test was executed at: This test was executed at:
%% Cell type:code id:00418ee4 tags: %% Cell type:code id:00418ee4 tags:
``` python ``` python
# Run this code # Run this code
import datetime import datetime
print(f"Test was executed at {datetime.datetime.isoformat(datetime.datetime.now(), ' ')}") print(f"Test was executed at {datetime.datetime.isoformat(datetime.datetime.now(), ' ')}")
``` ```
%% Cell type:markdown id:0b4a59a5 tags: %% Cell type:markdown id:0b4a59a5 tags:
## Purpose ## Purpose
Describe the purpose and context of this notebook, possibly including any links to external references, e.g. the Polarion reference number: Describe the purpose and context of this notebook, possibly including any links to external references, e.g. the Polarion reference number:
%% Cell type:markdown id:09d4d0a1 tags: %% Cell type:markdown id:09d4d0a1 tags:
(purpose) (purpose)
%% Cell type:markdown id:4c6489f3 tags: %% Cell type:markdown id:4c6489f3 tags:
## Methodology ## Methodology
Provide a summary of how we are going to prove compliance: Provide a summary of how we are going to prove compliance:
%% Cell type:markdown id:ceae21d4 tags: %% Cell type:markdown id:ceae21d4 tags:
(methodology) (methodology)
%% Cell type:markdown id:9033f262 tags: %% Cell type:markdown id:9033f262 tags:
## Initialisation ## Initialisation
The following sections contain boilerplate code to get the station to a well-defined state. If this is not applicable or broken, just note that here: The following sections contain boilerplate code to get the station to a well-defined state. If this is not applicable or broken, just note that here:
%% Cell type:markdown id:00d4e336 tags: %% Cell type:markdown id:00d4e336 tags:
%% Cell type:markdown id:7532d05e tags: %% Cell type:markdown id:7532d05e tags:
### Hot reboot ### Reboot
Makes sure the software and hardware are all in a known state. Makes sure the software and hardware are all in a known state.
%% Cell type:code id:c7a3effa tags:
``` python
# Restart boot device
boot.off()
boot.initialise()
boot.on()
```
%% Cell type:code id:b4dd21b1 tags: %% Cell type:code id:b4dd21b1 tags:
``` python ``` python
# Reboot the station # Reboot the station
boot.boot() boot.reboot()
``` ```
%% Cell type:code id:78a4db84 tags: %% Cell type:code id:78a4db84 tags:
``` python ``` python
# Wait for reboot to complete # Wait for reboot to complete
import time import time
while boot.booting_R: while boot.booting_R:
time.sleep(2) time.sleep(2)
print(f"Initialisation at {boot.progress_R}%: {boot.status_R}") print(f"Initialisation at {boot.progress_R}%: {boot.status_R}")
assert boot.progress_R == 100, f"Failed to fully initialise station: {boot.status_R}" assert boot.progress_R == 100, f"Failed to fully initialise station: {boot.status_R}"
if boot.uninitialised_devices_R: if boot.uninitialised_devices_R:
print(f"Warning! Did not initialise {boot.uninitialised_devices_R}. This might be inconsequential for this test.") print(f"Warning! Did not initialise {boot.uninitialised_devices_R}. This might be inconsequential for this test.")
``` ```
%% Cell type:markdown id:9bc072af tags: %% Cell type:markdown id:9bc072af tags:
### Active versions ### Active versions
List the versions currently running on the station. List the versions currently running on the station.
%% Cell type:code id:35b815d4 tags: %% Cell type:code id:35b815d4 tags:
``` python ``` python
def summarise(l: list) -> list: def summarise(l: list) -> list:
return [f"{idx}: {version}" for idx,version in enumerate(l) if version] or ["no versions reported"] return [f"{idx}: {version}" for idx,version in enumerate(l) if version] or ["no versions reported"]
versions = { versions = {
"SC": {dev.name():dev.version_R for dev in devices}, "SC": {dev.name():dev.version_R for dev in devices},
"SDP": { "SDP": {
"FPGA firmware": summarise(sdp.FPGA_firmware_version_R), "FPGA firmware": summarise(sdp.FPGA_firmware_version_R),
"FPGA hardware": summarise(sdp.FPGA_hardware_version_R), "FPGA hardware": summarise(sdp.FPGA_hardware_version_R),
"SDPTR": sdp.TR_software_version_R, "SDPTR": sdp.TR_software_version_R,
}, },
"RECV": { "RECV": {
"PCB": summarise(recv.RCU_PCB_version_R), "PCB": summarise(recv.RCU_PCB_version_R),
}, },
"APSCT": { "APSCT": {
"PCB": apsct.APSCT_PCB_version_R, "PCB": apsct.APSCT_PCB_version_R,
}, },
"APSPU": { "APSPU": {
"PCB": apspu.APSPU_PCB_version_R, "PCB": apspu.APSPU_PCB_version_R,
}, },
"UNB2": { "UNB2": {
"PCB": summarise(unb2.UNB2_PCB_version_R), "PCB": summarise(unb2.UNB2_PCB_version_R),
} }
} }
from pprint import pprint from pprint import pprint
pprint(versions, width=120) pprint(versions, width=120)
``` ```
%% Cell type:markdown id:e51a06b7 tags: %% Cell type:markdown id:e51a06b7 tags:
## Test setup ## Test setup
Setup the hardware for the test: Setup the hardware for the test:
%% Cell type:code id:e72dc2df tags: %% Cell type:code id:e72dc2df tags:
``` python ``` python
# Your code to configure the station for this test # Your code to configure the station for this test
``` ```
%% Cell type:markdown id:772dff7c tags: %% Cell type:markdown id:772dff7c tags:
## Run test ## Run test
%% Cell type:code id:26570aea tags: %% Cell type:code id:26570aea tags:
``` python ``` python
# Your code that triggers the actual test (if this is an explicit step) # Your code that triggers the actual test (if this is an explicit step)
``` ```
%% Cell type:markdown id:6c604116 tags: %% Cell type:markdown id:6c604116 tags:
## Test results ## Test results
%% Cell type:code id:d290d8dd tags: %% Cell type:code id:d290d8dd tags:
``` python ``` python
# plot sst in after # plot sst in after
``` ```
%% Cell type:markdown id:d3cdb620 tags: %% Cell type:markdown id:d3cdb620 tags:
## Discuss results ## Discuss results
How should the results be interpreted? Are there remaining worries and todo's based on this result? How should the results be interpreted? Are there remaining worries and todo's based on this result?
%% Cell type:markdown id:6e082c7c tags: %% Cell type:markdown id:6e082c7c tags:
(Explain results, and caveats) (Explain results, and caveats)
%% Cell type:markdown id:a95fbf48 tags: %% Cell type:markdown id:a95fbf48 tags:
## Verdict ## Verdict
The test passed/did not pass: The test passed/did not pass:
%% Cell type:markdown id:9a2a7a97 tags: %% Cell type:markdown id:9a2a7a97 tags:
(Explain whether the result is good enough, or what needs to be done to improve) (Explain whether the result is good enough, or what needs to be done to improve)
......
...@@ -79,7 +79,30 @@ class APSCT(opcua_device): ...@@ -79,7 +79,30 @@ class APSCT(opcua_device):
def read_APSCT_error_R(self): def read_APSCT_error_R(self):
return ((self.proxy.APSCTTR_I2C_error_R > 0) return ((self.proxy.APSCTTR_I2C_error_R > 0)
| self.alarm_val("APSCT_PCB_ID_R")) | self.alarm_val("APSCT_PCB_ID_R")
| ~self.proxy.APSCT_INPUT_10MHz_good_R
| (~self.proxy.APSCT_INPUT_PPS_good_R & ~self.proxy.ASPCT_PPS_ignore_R)
| (~self.proxy.APSCT_PLL_160MHz_locked_R & ~self.proxy.APSCT_PLL_200MHz_locked_R)
| (self.proxy.APSCT_PLL_200MHz_locked_R & self.proxy.APSCT_PLL_200MHz_error_R)
| (self.proxy.APSCT_PLL_160MHz_locked_R & self.proxy.APSCT_PLL_160MHz_error_R)
)
APSCT_TEMP_error_R = attribute(dtype=bool)
APSCT_VOUT_error_R = attribute(dtype=bool)
def read_APSCT_TEMP_error_R(self):
return (self.alarm_val("APSCT_TEMP_R"))
def read_APSCT_VOUT_error_R(self):
return ( self.alarm_val("APSCT_PWR_PPSDIST_3V3_R")
| self.alarm_val("APSCT_PWR_CLKDIST1_3V3_R")
| self.alarm_val("APSCT_PWR_CLKDIST2_3V3_R")
| self.alarm_val("APSCT_PWR_CTRL_3V3_R")
| self.alarm_val("APSCT_PWR_INPUT_3V3_R")
| (self.proxy.APSCT_PWR_PLL_160MHz_on_R & self.alarm_val("APSCT_PWR_PLL_160MHz_3V3_R"))
| (self.proxy.APSCT_PWR_PLL_200MHz_on_R & self.alarm_val("APSCT_PWR_PLL_200MHz_3V3_R"))
| ~self.proxy.APSCT_PWR_on_R
)
# -------- # --------
# overloaded functions # overloaded functions
......
...@@ -72,6 +72,28 @@ class APSPU(opcua_device): ...@@ -72,6 +72,28 @@ class APSPU(opcua_device):
| self.alarm_val("APSPU_FAN2_RPM_R") | self.alarm_val("APSPU_FAN2_RPM_R")
| self.alarm_val("APSPU_FAN3_RPM_R")) | self.alarm_val("APSPU_FAN3_RPM_R"))
APSPU_IOUT_error_R = attribute(dtype=bool)
APSPU_TEMP_error_R = attribute(dtype=bool)
APSPU_VOUT_error_R = attribute(dtype=bool)
def read_APSPU_IOUT_error_R(self):
return ( self.alarm_val("APSPU_LBA_IOUT_R")
| self.alarm_val("APSPU_RCU2A_IOUT_R")
| self.alarm_val("APSPU_RCU2D_IOUT_R")
)
def read_APSPU_TEMP_error_R(self):
return ( self.alarm_val("APSPU_LBA_TEMP_R")
| self.alarm_val("APSPU_RCU2A_TEMP_R")
| self.alarm_val("APSPU_RCU2D_TEMP_R")
)
def read_APSPU_VOUT_error_R(self):
return ( self.alarm_val("APSPU_LBA_VOUT_R")
| self.alarm_val("APSPU_RCU2A_VOUT_R")
| self.alarm_val("APSPU_RCU2D_VOUT_R")
)
# -------- # --------
# overloaded functions # overloaded functions
# -------- # --------
......
...@@ -266,7 +266,7 @@ class lofar_device(Device, metaclass=DeviceMeta): ...@@ -266,7 +266,7 @@ class lofar_device(Device, metaclass=DeviceMeta):
# This is just the command version of _initialise_hardware(). # This is just the command version of _initialise_hardware().
self._initialise_hardware() self._initialise_hardware()
def _boot_device(self, initialise_hardware=True): def _boot(self, initialise_hardware=True):
# setup connections # setup connections
self.Initialise() self.Initialise()
......
...@@ -186,6 +186,32 @@ class RECV(opcua_device): ...@@ -186,6 +186,32 @@ class RECV(opcua_device):
~self.proxy.RCU_ADC_locked_R ~self.proxy.RCU_ADC_locked_R
) )
RECV_IOUT_error_R = attribute(dtype=(bool,), max_dim_x=32)
RECV_TEMP_error_R = attribute(dtype=(bool,), max_dim_x=32)
RECV_VOUT_error_R = attribute(dtype=(bool,), max_dim_x=32)
def read_RECV_IOUT_error_R(self):
return self.proxy.ANT_mask_RW & (
self.alarm_val("RCU_PWR_ANT_IOUT_R")
).any(axis=1)
def read_RECV_TEMP_error_R(self):
return self.proxy.RCU_mask_RW & (
self.alarm_val("RCU_TEMP_R")
)
def read_RECV_VOUT_error_R(self):
return (self.proxy.ANT_mask_RW & (
self.alarm_val("RCU_PWR_ANT_VIN_R")
| self.alarm_val("RCU_PWR_ANT_VOUT_R")
).any(axis=1) | (self.proxy.RCU_mask_RW & (
self.alarm_val("RCU_PWR_1V8_R")
| self.alarm_val("RCU_PWR_2V5_R")
| self.alarm_val("RCU_PWR_3V3_R")
| ~self.proxy.RCU_PWR_DIGITAL_on_R
| ~self.proxy.RCU_PWR_good_R
)))
# -------- # --------
# overloaded functions # overloaded functions
# -------- # --------
......
...@@ -214,6 +214,7 @@ class SDP(opcua_device): ...@@ -214,6 +214,7 @@ class SDP(opcua_device):
def read_FPGA_error_R(self): def read_FPGA_error_R(self):
return self.proxy.TR_fpga_mask_RW & ( return self.proxy.TR_fpga_mask_RW & (
self.proxy.TR_fpga_communication_error_R self.proxy.TR_fpga_communication_error_R
| self.alarm_val(self.proxy.FPGA_jesd204b_csr_dev_syncn_R).any(axis=1)
) )
def read_FPGA_processing_error_R(self): def read_FPGA_processing_error_R(self):
......
...@@ -104,6 +104,16 @@ class SST(Statistics): ...@@ -104,6 +104,16 @@ class SST(Statistics):
# whether the subband data was calibrated by the SDP (that is, were subband weights applied) # whether the subband data was calibrated by the SDP (that is, were subband weights applied)
subbands_calibrated_R = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "subbands_calibrated"}, dims=(SSTCollector.MAX_INPUTS,), datatype=numpy.bool_) subbands_calibrated_R = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "subbands_calibrated"}, dims=(SSTCollector.MAX_INPUTS,), datatype=numpy.bool_)
# ----------
# Summarising Attributes
# ----------
FPGA_processing_error_R = attribute(dtype=(bool,), max_dim_x=16)
def read_FPGA_processing_error_R(self):
return self.sdp_proxy.TR_fpga_mask_RW & (
~self.proxy.FPGA_sst_offload_enable_R
)
# -------- # --------
# Overloaded functions # Overloaded functions
# -------- # --------
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
# PyTango imports # PyTango imports
from tango.server import device_property from tango.server import device_property
from tango import DeviceProxy
# Additional import # Additional import
import asyncio import asyncio
...@@ -123,6 +124,9 @@ class Statistics(opcua_device): ...@@ -123,6 +124,9 @@ class Statistics(opcua_device):
future = asyncio.run_coroutine_threadsafe(self._connect_statistics(), self.statistics_client.event_loop) future = asyncio.run_coroutine_threadsafe(self._connect_statistics(), self.statistics_client.event_loop)
_ = future.result() _ = future.result()
# proxy the SDP device in case we need the FPGA mask
self.sdp_proxy = DeviceProxy("STAT/SDP/1")
async def _connect_statistics(self): async def _connect_statistics(self):
# map an access helper class # map an access helper class
for i in self.attr_list(): for i in self.attr_list():
......
...@@ -144,6 +144,16 @@ class XST(Statistics): ...@@ -144,6 +144,16 @@ class XST(Statistics):
def read_xst_phase_R(self): def read_xst_phase_R(self):
return numpy.angle(self.statistics_client.collector.xst_values()) return numpy.angle(self.statistics_client.collector.xst_values())
# ----------
# Summarising Attributes
# ----------
FPGA_processing_error_R = attribute(dtype=(bool,), max_dim_x=16)
def read_FPGA_processing_error_R(self):
return self.sdp_proxy.TR_fpga_mask_RW & (
~self.proxy.FPGA_xst_offload_enable_R
)
# -------- # --------
# Overloaded functions # Overloaded functions
# -------- # --------
......
...@@ -123,24 +123,66 @@ class UNB2(opcua_device): ...@@ -123,24 +123,66 @@ class UNB2(opcua_device):
# Summarising Attributes # Summarising Attributes
# ---------- # ----------
UNB2_error_R = attribute(dtype=(bool,), max_dim_x=2) UNB2_error_R = attribute(dtype=(bool,), max_dim_x=2)
UNB2_FPGA_error_R = attribute(dtype=((bool,),), max_dim_x=4, max_dim_y=2)
UNB2_QSFP_error_R = attribute(dtype=((bool,),), max_dim_x=24, max_dim_y=2)
def read_UNB2_error_R(self): def read_UNB2_error_R(self):
return self.proxy.UNB2_mask_RW & ( return self.proxy.UNB2_mask_RW & (
(self.proxy.UNB2TR_I2C_bus_error_R > 0) (self.proxy.UNB2TR_I2C_bus_error_R > 0)
| self.alarm_val("UNB2_PCB_ID_R") | self.alarm_val("UNB2_PCB_ID_R")
| (self.proxy.UNB2TR_I2C_bus_DDR4_error_R > 0).any(axis=1)
| (self.proxy.UNB2TR_I2C_bus_FPGA_PS_error_R > 0).any(axis=1)
| (self.proxy.UNB2TR_I2C_bus_QSFP_error_R > 0).any(axis=1)
) )
def read_UNB2_FPGA_error_R(self): UNB2_IOUT_error_R = attribute(dtype=(bool,), max_dim_x=2)
UNB2_TEMP_error_R = attribute(dtype=(bool,), max_dim_x=2)
UNB2_VOUT_error_R = attribute(dtype=(bool,), max_dim_x=2)
def read_UNB2_IOUT_error_R(self):
return self.proxy.UNB2_mask_RW & (
self.alarm_val("UNB2_DC_DC_48V_12V_IOUT_R")
| self.alarm_val("UNB2_FPGA_POL_CORE_IOUT_R").any(axis=1)
| self.alarm_val("UNB2_FPGA_POL_ERAM_IOUT_R").any(axis=1)
| self.alarm_val("UNB2_FPGA_POL_HGXB_IOUT_R").any(axis=1)
| self.alarm_val("UNB2_FPGA_POL_PGM_IOUT_R").any(axis=1)
| self.alarm_val("UNB2_FPGA_POL_RXGXB_IOUT_R").any(axis=1)
| self.alarm_val("UNB2_FPGA_POL_TXGXB_IOUT_R").any(axis=1)
| self.alarm_val("UNB2_POL_CLOCK_IOUT_R")
| self.alarm_val("UNB2_POL_QSFP_N01_IOUT_R")
| self.alarm_val("UNB2_POL_QSFP_N23_IOUT_R")
| self.alarm_val("UNB2_POL_SWITCH_1V2_IOUT_R")
| self.alarm_val("UNB2_POL_SWITCH_PHY_IOUT_R")
)
def read_UNB2_TEMP_error_R(self):
return self.proxy.UNB2_mask_RW & ( return self.proxy.UNB2_mask_RW & (
(self.proxy.UNB2TR_I2C_bus_DDR4_error_R > 0) self.alarm_val("UNB2_DC_DC_48V_12V_TEMP_R")
| (self.proxy.UNB2TR_I2C_bus_FPGA_PS_error_R > 0) | self.alarm_val("UNB2_FPGA_POL_CORE_TEMP_R").any(axis=1)
| self.alarm_val("UNB2_FPGA_POL_ERAM_TEMP_R").any(axis=1)
| self.alarm_val("UNB2_FPGA_POL_HGXB_TEMP_R").any(axis=1)
| self.alarm_val("UNB2_FPGA_POL_PGM_TEMP_R").any(axis=1)
| self.alarm_val("UNB2_FPGA_POL_RXGXB_TEMP_R").any(axis=1)
| self.alarm_val("UNB2_FPGA_POL_TXGXB_TEMP_R").any(axis=1)
| self.alarm_val("UNB2_POL_CLOCK_TEMP_R")
| self.alarm_val("UNB2_POL_QSFP_N01_TEMP_R")
| self.alarm_val("UNB2_POL_QSFP_N23_TEMP_R")
| self.alarm_val("UNB2_POL_SWITCH_1V2_TEMP_R")
| self.alarm_val("UNB2_POL_SWITCH_PHY_TEMP_R")
) )
def read_UNB2_QSFP_error_R(self): def read_UNB2_VOUT_error_R(self):
return self.proxy.UNB2_mask_RW & ( return self.proxy.UNB2_mask_RW & (
(self.proxy.UNB2TR_I2C_bus_QSFP_error_R > 0) self.alarm_val("UNB2_DC_DC_48V_12V_VOUT_R")
| self.alarm_val("UNB2_FPGA_POL_CORE_VOUT_R").any(axis=1)
| self.alarm_val("UNB2_FPGA_POL_ERAM_VOUT_R").any(axis=1)
| self.alarm_val("UNB2_FPGA_POL_HGXB_VOUT_R").any(axis=1)
| self.alarm_val("UNB2_FPGA_POL_PGM_VOUT_R").any(axis=1)
| self.alarm_val("UNB2_FPGA_POL_RXGXB_VOUT_R").any(axis=1)
| self.alarm_val("UNB2_FPGA_POL_TXGXB_VOUT_R").any(axis=1)
| self.alarm_val("UNB2_POL_CLOCK_VOUT_R")
| self.alarm_val("UNB2_POL_QSFP_N01_VOUT_R")
| self.alarm_val("UNB2_POL_QSFP_N23_VOUT_R")
| self.alarm_val("UNB2_POL_SWITCH_1V2_VOUT_R")
| self.alarm_val("UNB2_POL_SWITCH_PHY_VOUT_R")
) )
# -------- # --------
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment