Mid.CBF AA* Design Work In Progress

Startup Sequence (TBD)

@startuml startup
!include mid-cbf-puml-definitions.txt

title  MCS Startup Sequence\nAll Units have hardware\nAll FHS connected and on Network
participant "CSP_Mid\n.LMC" as lmc #Thistle
box "\nMCS\n"
  participant "Mid.CBF\nController" as controller
  collections "Subarray" as subarray
  collections "VCC\nUnit" as vcc_unit
  collections "FSP\nUnit" as fsp_unit
  collections "FSP" as mcs_fsp
  participant "FHS\nHardware\nStatus" as hw_status
  collections "Network\nSwitch" as network
end box
box "\nHardware\n"
  participant "Open\nStack" as open_stack #LightGreen
  participant "Network\nAPI" as network_api #LightGreen
end box
box "\nFHS\n"
  collections "FHS\nController" as fhs_ctrl
  collections "VCC\nAll Bands\nController" as vcc_ctrl
  collections "FSP\nControl" as fsp_ctrl
end box

hw_status -> hw_status        : init
activate hw_status
loop #LightCyan Continuous
  hw_status -> open_stack     : get HW status
  alt HW Status returned
    hw_status <- open_stack     : HW Status
    / rnote over hw_status      : HealthState: OK
  else Unable to contact OpenStack
    hw_status <- open_stack     : Error
    / rnote over hw_status      : HealthState: FAILED
  end
end
deactivate hw_status

network  -> network           : init
activate network
loop #LightCyan Continuous, further details TBD
  network   -> network_api    : get Network status
  network   <- network_api    : Network Status
end
deactivate network

rnote over controller         : AdminMode: N/A\nOpState: INIT
/ rnote over subarray         : AdminMode: ONLINE\nOpState: ON\nObservingEnabled: False\nControl Mode:\nMonitor and Control
/ rnote over vcc_unit         : AdminMode: ONLINE\nOpState: INIT
/ rnote over fsp_unit         : AdminMode: ONLINE\nOpState: INIT
/ rnote over hw_status        : AdminMode: N/A\nOpState: ON (or N/A)

group #LightCyan Connect to VCC Units and FSP Units
  loop poll each VCC Unit until communicating
    controller -> vcc_unit        : start communicating
    controller <- vcc_unit        : communicating success
    controller -> vcc_unit        : Subscribe Health State
  end
  loop poll each FSP Unit until communicating
    controller -> fsp_unit        : start communicating
    controller <- fsp_unit        : communicating success
    controller -> fsp_unit        : Subscribe Health State
  end  

end

  alt VCC Unit has hardware
    loop poll until communicating
      vcc_unit -> network          : start communicating
      activate network
      vcc_unit <- network          : communicating success

      vcc_unit -> fhs_ctrl         : start communicating
      activate fhs_ctrl           
      vcc_unit <- fhs_ctrl         : communicating success
 
      vcc_unit -> vcc_ctrl         : start communicating
      activate vcc_ctrl 
      vcc_unit <- vcc_ctrl         : communicating success   
      
    end
    vcc_unit  ->> network        : Subscribe Health State
    vcc_unit  ->> fhs_ctrl       : Subscribe Health State
    vcc_unit  ->> vcc_ctrl       : Subscribe Health State
    vcc_unit  <<-- network        : Health State
    deactivate network
    vcc_unit  <<-- fhs_ctrl       : Health State
    deactivate fhs_ctrl
    vcc_unit  <<-- vcc_ctrl       : Health State
    deactivate vcc_ctrl
    vcc_unit -->> controller     : Health State
    rnote over vcc_unit          : AdminMode: ONLINE\nOpState: ON\nHealthState: OK, \nDEGRADED or FAILED\nControlMode:\nMonitor and Control    
  else VCC Unit has no hardware, do nothing
    rnote over vcc_unit          : AdminMode: ENGINEERING\nOpState: ON\nHealthState: UNKNOWN\nControlMode:\nNoMonitor NoControl
  end

  alt FSP Unit has hardware
    loop poll until communicating
      fsp_unit  ->> network      : start communicating
      activate network
      fsp_unit <- network        : communicating success

      fsp_unit  ->> fhs_ctrl      : start communicating
      activate fhs_ctrl      
      fsp_unit <- fhs_ctrl        : communicating success

      fsp_unit  ->> mcs_fsp      : start communicating
      activate mcs_fsp 
      mcs_fsp  ->> fsp_ctrl      : start communicating
      activate fsp_ctrl
      mcs_fsp <- fsp_ctrl        : communicating success
      fsp_unit <- mcs_fsp        : communicating success
   
    end
    fsp_unit  ->> network        : Subscribe Health State
    fsp_unit  ->> fhs_ctrl       : Subscribe Health State
    fsp_unit  ->> fsp_ctrl       : Subscribe Health State

    fsp_unit  <<-- network        : Health State
    deactivate network
    fsp_unit  <<-- fhs_ctrl       : Health State
    deactivate fhs_ctrl
    mcs_fsp  <<-- fsp_ctrl       : Health State
    deactivate fsp_ctrl
    fsp_unit  <<-- mcs_fsp       : Health State
    deactivate mcs_fsp
    fsp_unit -->> controller      : Health State
    rnote over fsp_unit         : AdminMode: ONLINE\nOpState: ON\nHealthState: OK, \nDEGRADED or FAILED\nControlMode:\nMonitor and Control   
  else FSP Unit has no hardware, do nothing
    rnote over fsp_unit         : AdminMode: ENGINEERING\nOpState: ON\nHealthState: UNKNOWN\nControlMode:\nNoMonitor NoControl  
  end

note right of vcc_unit           : VCC Units and FSP Units without\nhardware\ndo not participate in remaining sequence
rnote over controller         : AdminMode: N/A\nOpState: ON\nHealthState: OK, \nDEGRADED or FAILED\nControl Mode:\nMonitor and Control
group #LightCyan Initialize System Parameters
  lmc        -> controller      : InitSysParam(json_str)
  loop #LightCyan For each Subarray
    controller -> subarray        : Write sysParam
    controller <-- subarray       : Success
  end
  lmc       <-- controller      : Success
end

rnote over controller         : AdminMode: N/A\nOpState: ON\nHealthState: OK or\nDEGRADED or FAILED\nControl Mode:\n Monitor and Control

lmc <- controller             : Get Health State before issuing\nEnableObserving() command
lmc -> controller             : EnableObserving(True)

loop #LightCyan each Subarray
  controller   ->  subarray   : EnableObserving(True)
  controller   <-- subarray   : Success
end loop
lmc         <--  controller   : Success
rnote over subarray         : AdminMode: ONLINE\nOpState: ON\nObservingEnabled: True\nControl Mode:\nMonitor and Control

@enduml

Shutdown Sequence (TBD)

@startuml shutdown
!include mid-cbf-puml-definitions.txt

title Shutdown Sequence\n
participant "CSP_Mid\n.LMC" as lmc #Thistle
box "\nMCS\n"
  participant "Mid.CBF\nController" as controller
  collections "Subarray" as subarray
  collections "VCC\nUnit" as vcc_unit
  collections "FSP\nUnit" as fsp_unit
  participant "FHS\nHardware\nStatus" as hw_status
  collections "Network\nSwitch" as network
end box
box "\nHardware\n"
  participant "Open\nStack" as open_stack #LightGreen
  participant "Network\nAPI" as network_api #LightGreen
end box
box "\nFHS\n"
  collections "FHS\nController" as fhs_ctrl
  collections "All Bands\nController" as ab_ctrl
end box

rnote over controller         : AdminMode: N/A\nOpState: ON\nHealthState: OK, \nDEGRADED or FAILED\nControl Mode:\nMonitor and Control
/ rnote over subarray         : AdminMode: ONLINE\nOpState: ON\nObservingEnabled: True\nControl Mode:\nMonitor and Control

lmc -> controller           : EnableObserving(False)
alt All Subarrays are 

alt all Subarrays are EMPTY
  loop each subarray
    controller -> subarray   : EnableObserving(False)
    / rnote over subarray         : AdminMode: ONLINE\nOpState: ON\nObservingEnabled: False\nControl Mode:\nMonitor and Control
    lmc       <-- controller : Success
  end
else at least one Subarray is not EMPTY (is in use)
  controller <-- subarray   : Failed, with message
  / rnote over subarray         : AdminMode: ONLINE\nOpState: ON\nObservingEnabled: True\nControl Mode:\nMonitor and Control
  lmc        <-- controller : Failed, with message
end

rnote over controller         : AdminMode: N/A\nOpState: ON\nHealthState: OK, \nDEGRADED or FAILED\nControl Mode:\nMonitor and Control

@enduml

Setting System Parameters

@startuml init_sys_param
!include mid-cbf-puml-definitions.txt

title InitSysParam Command Sequence\n

participant "CSP_Mid\n.LMC" as lmc #Thistle
box "\nMCS\n"
  participant "Mid.CBF\nController" as controller
  collections "Mid.CBF\nSubarray" as subarray
end box
participant "CAR\n" as car #YellowGreen

lmc          -> controller          : InitSysParam(json_str)
controller   -> controller          : Validate JSON against schema

group #SeaShell If JSON is valid:
  group #SeaShell If URI provided:
    controller    -> car            : Retrieve init sys param JSON file
    controller    -> controller     : Validate JSON  against schema
  end group
  controller      -> controller     : Update sysParam
  controller      -> subarray       : Set sysParam
  subarray        -> subarray       : Update sysParam
  lmc         <-- controller        : //Success//
end group

@enduml

Resource Status Reporting

@startuml resource-status
!include mid-cbf-puml-definitions.txt

title On Demand Resource Status Reporting\n

' ======================================
participant "CSP_Mid\n.LMC" as lmc #Thistle
box "\nMCS\n"
    participant "Mid.CBF\nController" as controller
    participant "VCC Unit\n" as vcc_unit
    participant "FSP Unit\n" as fsp_unit
    participant "FSP\n" as fsp
end box

box "\nFHS VCC"
    collections "VCC All Bands\nController" as fhs_vcc
end box

' ======================================


' Request resource status report
lmc  ->  controller ++  : resourceStatus

' Controller loops through all VCC Units
loop #LightCyan each VCC Unit in the Mid.CBF
controller ->  vcc_unit ++ : resourceStatus
    loop #LightCyan each VCC in the VCC Unit
    vcc_unit -> fhs_vcc : read adminMode
    fhs_vcc --> vcc_unit : adminMode
    vcc_unit -> fhs_vcc : read subarrayMembership
    vcc_unit <-- fhs_vcc : subarrayMembership
    vcc_unit -> vcc_unit : read vcc healthState
    vcc_unit -> vcc_unit : read vcc unit ID
    vcc_unit -> vcc_unit : add to JSON dict with VCC ID key
    end loop
controller <--  vcc_unit : resourceStatus
end loop

loop #LightCyan each FSP Unit in the Mid.CBF
controller ->  fsp_unit ++ : resourceStatus
fsp_unit -> fsp : read adminMode
fsp_unit <-- fsp : adminMode
fsp_unit -> fsp_unit : read fsp unit healthState
fsp_unit -> fsp : read subarrayMembership
fsp_unit <-- fsp : subarrayMembership
fsp_unit -> fsp : read fspMode
fsp_unit <-- fsp : fspMode
fsp_unit -> fsp_unit : read fsp unit healthState
fsp_unit -> fsp_unit : read fsp unit ID
fsp_unit -> fsp_unit : add to JSON dict with FSP ID key
controller <--  fsp_unit : resourceStatus
end loop

controller -> controller : validate JSON
lmc  <-- controller --  : //result//

@enduml

Assign Resources

@startuml assign-resources
!include mid-cbf-puml-definitions.txt

title MCS Assign Resources\n

participant "TMC\n" as tmc #Gold
participant "CSP_Mid\n.LMC" as lmc #Thistle
box "\nMCS\n"
    participant "Mid.CBF\nSubarray" as subarray
end box

box "\nFHS"
    collections "VCC All Bands\nController" as fhs_vcc
end box

rnote over subarray          : ObsState: EMPTY
lmc         ->  subarray     : AssignResources(list[str])
rnote over subarray          : ObsState: RESOURCING

note over subarray           : "SysParam" may\nbe part of another\nTango device
subarray    ->  subarray     : ValidateReceptors(list[str])
note over subarray #yellow   : SysParam could return\nlist of associated VCCs
note over subarray #yellow   : Is any other\nvalidation\nrequired?


loop #LightCyan each valid receptor/VCC
    subarray    ->  fhs_vcc      : UpdateSubarrayMembership(subarrayId)
    alt receptor successfully added
        subarray    <-- fhs_vcc      : //success//
        subarray    ->  subarray     : Update subarray with subarrayId
    else #LightSalmon assign resource unsuccessful
        subarray    <-- fhs_vcc      : Command rejected (e.g., receptor already assigned)
        subarray    ->  subarray     : Assign resource to "failed" list
    end alt
    rnote over subarray           : ObsState: IDLE
end loop

lmc        <--  subarray         : //result//
note over subarray #yellow : Return list of receptors\nthat failed to add?

@enduml

Release Resources

@startuml release-resources
!include mid-cbf-puml-definitions.txt

title MCS Release Resources\n

participant "TMC\n" as tmc #Gold
participant "CSP_Mid\n.LMC" as lmc #Thistle
box "\nMCS\n"
    participant "Mid.CBF\nSubarray" as subarray
end box

box "\nFHS"
    collections "VCC All Bands\nController" as fhs_vcc
end box

lmc             ->  subarray    : ReleaseResources(list[str])
note over subarray              : ObsState: RESOURCING

note over subarray           : "SysParam" may\nbe part of another\nTango device
subarray    ->  subarray     : ValidateReceptors(list[str])
note over subarray #yellow   : SysParam could return\nlist of associated VCCs
note over subarray #yellow   : Is any other\nvalidation\nrequired?

loop #LightCyan each valid receptor/VCC
    subarray    -> fhs_vcc          : UpdateSubarrayMembership(subarrayId=0)
    alt receptor successfully removed
        subarray <-- fhs_vcc        : //success//
        subarray    ->  subarray    : Update subarray
    else #LightSalmon release resources unsuccessful
        subarray    <-- fhs_vcc     : //failed//
        subarray    ->  subarray    : Assign resource to "failed" list
    end alt
    note over fhs_vcc               : OpState: DISABLE
end loop

group #SeaShell If len(receptors) == 0:
    note over subarray          : ObsState: EMPTY
else
    note over subarray          : ObsState: IDLE
end group


lmc  <--  subarray     : //result//
note over subarray #yellow : Return list of receptors\nthat failed to be removed?

@enduml

Configure Scan

@startuml configure scan
!include mid-cbf-puml-definitions.txt

title Configure Scan (Correlation)\n

' participant "TMC\n" as tmc #Gold
participant "CSP_Mid\n.LMC" as lmc #Thistle
box "\nMCS\n"
    participant "Mid.CBF\nController" as controller
    participant "Mid.CBF\nSubarray" as subarray
    collections "VCC\nUnit" as vcc
    collections "FSP\nUnit" as fsp_unit
    collections "FSP Corr\nSubarray" as fspcorr
    participant "Visibility\nTransport" as vis_trans
end box
box "\nFHS VCC\n" 
    participant "VCC All Bands\nController" as vcc_cont
end box
box "\nFHS FSP\n"
    participant "FSP\nController" as fsp_cont
    participant "FSP Corr\nController" as fsp_corr_ctrl
    participant "FSP PST\nController" as fsp_pst_ctrl
    participant "FSP PSS\nController" as fsp_pss_ctrl
    participant "FPGA Monitor\nand Control" as fpga
end box

lmc         -> subarray     : ConfigureScan(json_str)
subarray    -> subarray     : Validate JSON against schema,\nLoad new configuration

' group #LightCyan For each FSP:
'     subarray    -> fsp          : RemoveSubarrayMembership
'     group #SeaShell If len(subarrayMembership) == 0:
'         fsp         -> fspcorr      : AdminMode.OFFLINE
'         note over fspcorr           : OpState: DISABLE
'         fsp         -> fsp_cont     : Set function mode to IDLE
'         note over fsp_cont          : functionMode: IDLE
'         note over fsp               : functionMode: IDLE
'         subarray    -> fsp          : AdminMode.OFFLINE
'         note over fsp             : OpState: DISABLE
'     end group
' end group

' group #LemonChiffon Delay model subscription point
'     subarray    -> tmc          : Unsubscribe all events
' end group

' subarray    -> subarray     : Clear old configuration

' group #LemonChiffon Delay model subscription point
'     subarray    -> tmc          : Subscribe delay model
' end group

group #LightCyan For each assigned receptor:
    ' subarray    -> vcc          : ConfigureBand(json_str)
    ' vcc         -> vcc_cont     : ConfigureBand(int)
    subarray ->  vcc ++       : ConfigureScan(json_str)
    vcc ->  vcc_cont          : ConfigureScan(json_str)
    vcc <-- vcc_cont          : //result//
    subarray <-- vcc --       : //result// 
    note over vcc             : ObsState: READY
end group

group #LightCyan For each FSP in use:
    subarray  -> subarray     : Build FSP\nconfiguration

    subarray -> fsp_unit      : FunctionMode?

    alt If FunctionMode == IDLE (not part of a subarray)
        subarray <-- fsp_unit : IDLE
        subarray -> fsp_unit  : AdminMode.ONLINE
        note over fsp_unit    : OpState: ON
        subarray -> fsp_unit ++    : SetFunctionMode(str)
        fsp_unit      -> fsp_unit      : Validate FunctionMode
        loop #LightCyan each FSP Controller in the FSP Unit
            fsp_unit ->  fsp_cont  ++  : SetFunctionMode(int)            
            fsp_cont -> fsp_pst_ctrl   : AdminMode.OFFLINE
            fsp_cont -> fsp_pss_ctrl   : AdminMode.OFFLINE
            fsp_cont ->  fpga          : Re-program Corr bitstream
            fsp_cont <-- fpga          : //result//
            fsp_cont -> fsp_corr_ctrl  : AdminMode.ONLINE
            note over fsp_corr_ctrl: Sets communication\nstatus to established.
            fsp_unit <-- fsp_cont --   : //result//
        end loop
        subarray <-- fsp_unit --  : //result//
        note over fsp_cont        : functionMode: CORR
        note over fsp_unit        : functionMode: CORR 
    else #LightGreen FunctionMode == CORR
        subarray <-- fsp_unit     : CORR
        note over fsp_unit: NOP
    else #LightSalmon FunctionMode == PST or FunctionMode == PSS
        subarray <-- fsp_unit      : PST or PSS
        note over fsp_unit: Not allowed
    end alt

    subarray  -> fsp_unit ++  : AddSubarrayMembership(int)
    fsp_unit  -> fsp_unit     : Validate subarrayID
    fsp_unit   -> fspcorr     : AdminMode.ONLINE
    note over fspcorr         : OpState: ON
    subarray <-- fsp_unit --  : //result//

    subarray -> fspcorr ++    : ConfigureScan(json_str)
    ' fspcorr     -> fspcorr      : Reset old configuration,\nRelease all VCCs,\nLoad FSP configuration,\nAssign new VCCs,\nBuild HPS FSP CORR configuration
    fspcorr ->  fsp_corr_ctrl : ConfigureScan(json_str)
    fspcorr <-- fsp_corr_ctrl : //result//
    note over fspcorr         : ObsState: READY
    subarray <-- fspcorr --   : //result//
end group

subarray    -> vis_trans    : Configure(json_str, yaml_str)

note over subarray          : ObsState: READY
lmc        <-- subarray     : Success

@enduml

Abort

DRAFT only. Temporary text will move to MCS DDD when design confirmed. On an Abort command to FHS FSP, the FHS FSP would both stop any processing and deconfigure the FHS FSP.

On an ObsReset, MCS removes the subarray membership to the FSPs.

@startuml sync-fsp-output
!include mid-cbf-puml-definitions.txt

title Abort-ObsReset\n

' ======================================
participant "CSP_Mid\n.LMC" as lmc #Thistle
box "\nMCS\n"
    participant "Mid.CBF\nSubarray1" as subarray
    collections "Mid.CBF\nFspCorrSubarray" as corr_subarray
    collections "Mid.CBF\nFsp" as fsp

end box

box "\nFHS VCC"
    collections "FHS VCC" as fhs_vcc
end box

box "\nFHS FSP"
    collections "FHS FSP Corr" as fhs_fsp
end box

' ======================================

lmc            ->  subarray       : Abort()
note over subarray                : Sequence shown for\nObsState ==\nABORTED or FAULT

loop #LightCyan for each VCC
    subarray       ->  fhs_vcc        : Abort()
    fhs_vcc        ->  fhs_vcc        : interrupt observation\nprocessing
    fhs_vcc        ->  fhs_vcc        : scan deconfigure
end

loop #LightCyan for each FSP
    subarray       ->  corr_subarray  : Abort()
    corr_subarray  ->  fhs_fsp        : Abort()
    fhs_fsp        ->  fhs_fsp        : interrupt observation\nprocessing
    fhs_fsp        ->  fhs_fsp        : scan deconfigure
end

lmc            ->  subarray       : ObsReset()
subarray       ->  subarray       : scan deconfigure

loop #LightCyan for each FSP
    subarray       ->  fsp            : remove subarray membership\n(part of Subarray deconfigure)
    subarray       ->  corr_subarray  : ObsReset()
    corr_subarray  ->  corr_subarray  : scan deconfigure
    corr_subarray  ->  fhs_fsp        : UpdateSubarrayMembership([])
end 
note over subarray                : ObsState: IDLE
@enduml

Start Scan

Engineering Mode

Engineering Mode Example

@startuml engineering-mode
!include mid-cbf-puml-definitions.txt

title Engineering Mode Example:\nExternal Control Scan with Engineering SW/FW Versions

' ======================================
actor "Nic\n" as nic #Blue
participant "Mid.CBF\nDeployment" as deploy #Orange
participant "CSP_Mid\n.LMC" as lmc #Thistle
box "\nMCS\n"
    participant "Mid.CBF\nSubarray" as subarray
    participant "Mid.CBF\nController" as controller
    participant "FSP Corr\n" as fsp_corr
    participant "VCC Unit\n" as vcc_unit
    participant "FSP Unit\n" as fsp_unit
end box

box "\nFHS VCC"
    collections "VCC All Bands\nController" as fhs_vcc
end box

box "\nFHS FSP"
    collections "FSP\nController" as fhs_fsp
    collections "FSP\nCorr" as fhs_corr
end box
' ======================================

note over nic: Confirm list of\n VCC, FSP units to be set\nto adminMode ENGINEERING\n(units not in use) 
note over deploy: Deployment configuration contains\n"science-approved" version numbers
nic  ->  deploy ++ : Deploy Engineering versions of\nSW & FW to VCC and FSP Units
nic  <-- deploy -- : //Deployed//
note over vcc_unit : adminMode for VCC Units and FSP Units\nis OFFLINE upon deployment\nCheck for "science-approved" versions\nprevents setting to ONLINE (science)


nic  ->  lmc ++       : **//"Engineering" Scan//**

rnote over subarray   : ObsState: EMPTY
lmc  ->  subarray ++  : Set Subarray\nadminMode ENGINEERING
note over subarray : can only set ENGINEERING\non empty subarray
lmc  <-- subarray --  : //result//

' Set VCC Unit to Engineering Mode
lmc         --> controller ++ : SetResourceAdminMode()
controller  -->  vcc_unit ++  :  Set VCC Unit \nadminMode ENGINEERING

note over vcc_unit: can only set ENGINEERING if VCC Unit\nis not in use (no associated\nreceptors allocated to\nsubarrays)
vcc_unit    -->  vcc_unit       : Publish adminMode change event
loop #LightCyan each VCC in the VCC Unit
vcc_unit    -->  fhs_vcc        : Receive VCC Unit adminMode\nchange event
fhs_vcc     --> fhs_vcc         : Set VCC \nadminMode ENGINEERING
end loop
controller  <-- vcc_unit --     : //result//


'Set FSP Unit to Engineering Mode

controller  -->  fsp_unit ++    : Set FSP Unit \nadminMode ENGINEERING
note over fsp_unit              : can only set ENGINEERING if\nFSP unit is not in\nuse (idle)
fsp_unit    -->  fsp_unit       : Publish adminMode change event
loop #LightCyan each FSP in the FSP Unit
fsp_unit    -->  fhs_fsp        : Receive FSP Unit adminMode\nchange event
fhs_fsp     --> fhs_fsp         : Set FSP Ctrl \nadminMode ENGINEERING
end
controller  <-- fsp_unit --     :  //result//

lmc         <-- controller --   : //result//

'Assign Resources
lmc  ->  subarray ++  : Assign Resources(list[str])
rnote over subarray   : ObsState: RESOURCING
subarray ->  subarray : ValidateReceptors(list[str])
note over fhs_vcc: ONLINE (Science) VCC allowed in ENGINEERING subarray;\nENGINEERING VCC not allowed in ONLINE (Science) subarray
subarray ->  fhs_vcc  : UpdateSubarrayMembership(subarrayId)
subarray <-- fhs_vcc  : //result//
subarray ->  subarray : Update subarray with vccId
rnote over subarray   : ObsState: IDLE
lmc <-- subarray --   : //result//

'Configure Scan
lmc      ->  subarray ++ : ConfigureScan()
subarray ->  fsp_unit    : Available? ("corr" or "idle")
subarray <-- fsp_unit    : yes
subarray ->  fsp_unit    : ENGINEERING?
note over fsp_unit: Science (ONLINE) FSP allowed in ENGINEERING subarray;\nENGINEERING FSP not allowed in Science(ONLINE) subarray
subarray <-- fsp_unit    : yes
subarray -> fsp_unit     : SetFunctionMode CORR
fsp_unit -> fhs_fsp      : SetFunctionMode CORR
fhs_fsp -> fhs_corr      : ON
fhs_fsp <-- fhs_corr     ://result//
fsp_unit <-- fhs_fsp     ://result//
subarray <-- fsp_unit     ://result//
subarray ->  fsp_corr ++ : Scan Config
fsp_corr ->  fhs_corr     : Scan config
fsp_corr <-- fhs_corr     : //result//
subarray <-- fsp_corr -- : //result//
lmc  <-- subarray --  : //result//

'Start Scan
lmc  ->  subarray ++  : StartScan()
subarray  ->  fsp_corr ++ : Start scan
fsp_corr  ->  fhs_corr: Start Scan
fsp_corr  <-- fhs_corr: //result//
subarray  <--  fsp_corr -- : //result//
lmc  <-- subarray --  : //result//

'End Scan
lmc      ->  subarray ++ : EndScan()
subarray ->  fsp_corr ++ : End scan
fsp_corr ->  fhs_corr     : End Scan
fsp_corr <-- fhs_corr     : //result//
subarray <-- fsp_corr -- : //result//
lmc      <-- subarray -- : //result//

nic  <- lmc --        : **//Done "Engineering" Scan//**

@enduml

Engineering Mode Cleanup

@startuml engineering-mode
!include mid-cbf-puml-definitions.txt

title Engineering Mode Cleanup\n

' ======================================
actor "Nic\n" as nic #Blue
participant "Mid.CBF\nDeployment" as deploy #Orange
participant "CSP_Mid\n.LMC" as lmc #Thistle
box "\nMCS\n"
    participant "Mid.CBF\nSubarray" as subarray
    participant "Mid.CBF\nController" as controller
    participant "FSP Corr\n" as fsp_corr
    participant "VCC Unit\n" as vcc_unit
    participant "FSP Unit\n" as fsp_unit
end box

box "\nFHS VCC"
    collections "VCC All Bands\nController" as fhs_vcc
end box

box "\nFHS FSP"
    collections "FSP\nController" as fhs_fsp
    collections "FSP\nCorr" as fhs_corr
end box
' ======================================

nic  ->  lmc ++       : **//"Engineering" Scan cleanup//**

'Release Resources
lmc  ->  subarray ++  : ReleaseResources()
lmc  <-- subarray --  : //result//

' Set Subarray to Science Mode
lmc  ->  subarray ++  : Set Subarray \nadminMode ONLINE (Science)
note over subarray : can only set ONLINE\non empty subarray
lmc  <-- subarray --  : //result//

nic  <-- lmc --       : **//Done "Engineering" Scan cleanup//**

' Re-deploy Science version of SW & FW
nic  ->  deploy ++    : Re-Deploy Science versions of\nSW & FW to VCC and FSP Units
nic  <-- deploy --    : //Deployed//


nic  ->  lmc ++       : **//"Engineering" Mode cleanup//**

' Set VCC Unit to Science Mode
lmc  -> controller ++ : SetResourceAdminMode()

controller  ->  vcc_unit ++    : Set VCC Unit \nadminMode ONLINE
note over vcc_unit: can only set ONLINE if VCC unit\nis not in use (no associated\nreceptors allocated to\nsubarrays)
vcc_unit ->  vcc_unit : SW & FW are science versions?
alt SW & FW are science versions
    vcc_unit ->  vcc_unit  : Publish adminMode change event
    loop #LightCyan each VCC in the VCC Unit
    vcc_unit ->  fhs_vcc  : Receive adminMode change event
    fhs_vcc --> fhs_vcc  : Set VCC \nadminMode ONLINE
    end loop
    controller  <-- vcc_unit     :  //result//
else #LightSalmon SW & FW are //not// science versions
    controller  <-- vcc_unit --  :  //fail//
    lmc <-- controller : //fail//
end alt

'Set FSP Unit to Science Mode
controller  ->  fsp_unit ++  :   Set FSP Unit \nadminMode ONLINE
note over fsp_unit: can only set ONLINE if\nFSP unit is not in\nuse (idle)
fsp_unit ->  fsp_unit :   SW & FW are science versions?
alt SW & FW are science versions
    fsp_unit --> fsp_unit : Publish adminMode change event
    loop #LightCyan each FSP in the FSP Unit
    fsp_unit -->  fhs_fsp  : Receive adminMode change event
    fhs_fsp  -->  fhs_fsp  : Set FSP \nadminMode ONLINE
    end loop
    controller  <-- fsp_unit     :  //result//
else #LightSalmon SW & FW are //not// science versions
    controller  <-- fsp_unit --  :  //fail//
    lmc <-- controller : //fail//
end alt

lmc <-- controller -- : //result//

nic  <- lmc --        : **//Done "Engineering" Mode cleanup//**

@enduml

Autoset Gain

@startuml autoset_gains
!include mid-cbf-puml-definitions.txt

title Autoset Gains Sequence\n
participant "CSP_Mid\n.LMC" as lmc #Thistle
box "\nMCS\n"
  participant "Mid.CBF\nSubarray" as subarray
end box

box "\nFHS-VCC\n"
  participant "All Bands Controller" as allbands
end box

lmc      ->  subarray ++  : Set RFI Headroom attribute\non Subarray (Default: 3dB)
subarray ->  allbands     : Set Requested RFI Headroom Attribute
subarray <-- allbands     : //Success//
lmc      <-- subarray --  : //Success//

lmc      ->  subarray ++  : AutoSetFilterGain(optional: Headroom)
subarray ->  allbands     : AutoSetFilterGain(optional: Headroom)
allbands ->  allbands     : Read average power over t for\nwideband power relative to the band
allbands ->  allbands     : Algorithm to requantize power accounting\nfor new Headroom required
allbands ->  allbands     : Apply new gains values to\nOSPFFB Channelizer
allbands ->  allbands     : Update Gains attribute and digital bandpass \n corrections map for the current band
allbands ->  allbands     : Publish change event on gains attribute\nand resolve LRC
subarray <-- allbands     : //Success//
subarray ->  allbands     : Read FS lane power levels after\ngains application
allbands ->  allbands     : Read all power levels across each FS lane
note over subarray : Does this power level\nreading need to be\ndone here? 
subarray <-- allbands     : Return array of powers\n(size = number of channels * pol)
lmc      <-- subarray     : //Success//

@enduml

Noise Diode

Mid.CBF Base Classes

@startuml

/'--- CbfDevice ---'/

abstract SKABaseDevice

class "CbfDevice" {
  DeviceID : device_property
  deviceID() -> int
  Off() -> DevVarLongStringArrayType
  On() -> DevVarLongStringArrayType
  Reset() -> DevVarLongStringArrayType
  Standby() -> DevVarLongStringArrayType
  adminMode() -> AdminMode
  simulationMode() -> SimulationMode.FALSE
}

SKABaseDevice <|-- CbfDevice

/'--- CbfComponentManager ---'/

abstract TaskExecutorComponentManager

class "CbfComponentManager"{
  admin_mode_callback : Callable
  attr_archive_callback : Callable
  attr_change_callback : Callable
  health_state_callback : Callable
  start_communicating() -> None
  stop_communicating() -> None
}

TaskExecutorComponentManager <|-- CbfComponentManager

@enduml

Mid.CBF Controller Classes

@startuml

/'--- MidCbfController ---'/

abstract CbfDevice

class MidCbfController {
  FSPs : device_property
  LRCTimeout : device_property
  MaxCapabilities : device_property
  Subarrays : device_property
  InitSysParam(sys_params: str) -> DevVarLongStringArrayType
  Off() -> DevVarLongStringArrayType
  On() -> DevVarLongStringArrayType
  create_component_manager() -> ControllerComponentManager
  dishToVcc() -> List[str]
  init_command_objects() -> None
  is_InitSysParam_allowed() -> bool
  is_Off_allowed() -> bool
  is_On_allowed() -> bool
  maxCapabilities() -> List[str]
  sourceSysParam() -> str
  sysParam() -> str
  validateSupportedConfiguration() -> bool
  vccToDish() -> List[str]
}
CbfDevice <|-- MidCbfController

/'--- MidCbfControllerComponentManager ---'/

abstract MidCbfComponentManager

class "MidCbfControllerComponentManager"{
  blocking_command_ids : set
  dish_utils : NoneType, DISHUtils
  last_init_sys_param : str
  source_init_sys_param : str
  validate_supported_configuration : bool
  init_sys_param(sys_params: str, task_callback: Optional[Callable]) -> tuple[ResultCode, str]
  is_init_sys_param_allowed() -> bool
  is_off_allowed() -> bool
  is_on_allowed() -> bool
  off(task_callback: Optional[Callable]) -> tuple[ResultCode, str]
  on(task_callback: Optional[Callable]) -> tuple[ResultCode, str]
}

MidCbfComponentManager <|-- MidCbfControllerComponentManager
MidCbfController *-- MidCbfControllerComponentManager

@enduml

Mid.CBF Subarray Classes

@startuml

/'--- MidCBFSubarray ---'/

abstract MidCbfObsDevice
abstract MidCbfObsComponentManager
class "MidCbfSubarray"{
  Controller : device_property
  FSPs : device_property
  FspCorrSubarray : device_property
  VCCAllBands : device_property
  obs_state_model : ObsStateModel
  AssignResources(dish_ids: List[str]) -> DevVarLongStringArrayType
  ReleaseAllResources() -> DevVarLongStringArrayType
  ReleaseResources(dish_ids: List[str]) -> DevVarLongStringArrayType
  Restart() -> DevVarLongStringArrayType
  Scan(scan_id: str) -> DevVarLongStringArrayType
  assignedFSPs() -> List[int]
  assignedVCCs() -> List[int]
  create_component_manager() -> CbfSubarrayComponentManager
  delayModel() -> str
  frequencyBand() -> int
  frequencyOffsetK() -> List[int]
  init_command_objects() -> None
  receptors() -> List[str]
  sysParam() -> str
}

class "MidCbfSubarrayComponentManager"{
  blocking_command_ids : set
  config_id : str
  delay_model : str
  dish_ids : set
  frequency_band : int
  frequency_offset_k : List[int]
  fsp_ids
  obs_state : EMPTY
  scan_id : str, int
  vcc_ids
  assign_vcc(dish_ids: List[str], task_callback: Optional[Callable]) -> tuple[TaskStatus, str]
  is_assign_vcc_allowed() -> bool
  is_release_all_vcc_allowed() -> bool
  is_release_vcc_allowed() -> bool
  is_restart_allowed() -> bool
  release_all_vcc(task_callback: Optional[Callable]) -> tuple[TaskStatus, str]
  release_vcc(dish_ids: List[str], task_callback: Optional[Callable]) -> tuple[TaskStatus, str]
  restart(task_callback: Optional[Callable]) -> tuple[TaskStatus, str]
  update_sys_param(sys_param_str: str) -> None
}
MidCbfObsDevice <|-- MidCbfSubarray

MidCbfObsComponentManager <|-- MidCbfSubarrayComponentManager
MidCbfSubarray *-- MidCbfSubarrayComponentManager

@enduml

VCC Classes

@startuml

abstract MidCBFDevice
abstract MidCBFComponentManager
class VCCUnit
class VCCUnitComponentManager

VCCUnit : MidCbfControllerFQDN : device_property
VCCUnit : TBDNetworkSwitchFQDN: device_property
VCCUnit : VCCAllBandsFQDNs : device_property
VCCUnit : FhsHostControllerFQDN : device_property
VCCUnit : healthStateHardware() -> HealthState
VCCUnit : healthStatesVcc() -> str

VCCUnit : create_component_manager() -> VCCUnitComponentManager

VCCUnitComponentManager : +health_state_hw: HealthState
VCCUnitComponentManager : +health_state_vcc: dict[int, HealthState]

VCCUnitComponentManager : -_mid_cbf_controller: DeviceProxy
VCCUnitComponentManager : -_fhs_host_controller: DeviceProxy
VCCUnitComponentManager : -_network_switch_controller: DeviceProxy
VCCUnitComponentManager : -_vcc_all_bands_controller: list[DeviceProxy]

VCCUnitComponentManager : -__init__(*args: any, mid_cbf_controller_fqdn: str, network_switch_fqdn: str, fhs_host_controller_fqdn: str, vcc_all_bands_controller_fqdns: list[str], **kwargs: any)
VCCUnitComponentManager : -_start_communicating(*args, **kwargs)
VCCUnitComponentManager : -_stop_communicating(*args, **kwargs)

VCCUnitComponentManager : -_handle_vcc_all_bands_health_state_callback(vcc_all_bands_id: int, health_state: HealthState)
VCCUnitComponentManager : -_handle_network_switch_health_state_callback(health_state: HealthState)
VCCUnitComponentManager : -_handle_fhs_host_health_state_callback(health_state: HealthState)
VCCUnitComponentManager : -_handle_admin_mode_callback(admin_mode: AdminMode)
MidCBFDevice <|-- VCCUnit
MidCBFComponentManager <|-- VCCUnitComponentManager
VCCUnit *-- VCCUnitComponentManager


@enduml

FSP Classes

@startuml

abstract MidCBFDevice
abstract MidCBFComponentManager
class FSPUnit
class FSPUnitComponentManager
class Fsp
class FHS <<interface>>
class tbd_Switch400Gb

FSPUnit : tbd_Switch400Gb: str

FSPUnit : #create_component_manager() -> FSPUnitComponentManager

FSPUnitComponentManager : -tbd_switch_400_gb: DeviceProxy

MidCBFDevice <|-- FSPUnit
MidCBFComponentManager <|-- FSPUnitComponentManager
FSPUnit *-- FSPUnitComponentManager : owns
FSPUnitComponentManager "1" -- "1" Fsp
FSPUnitComponentManager "1" -- tbd_Switch400Gb : uses
FSPUnitComponentManager "1" -- "4" FHS


@enduml

@startuml

abstract MidCBFObsDevice
abstract MidCBFObsComponentManager

class "FspModeSubarray"{
  LRCTimeout : device_property
  UpdateDelayModel(delay_model_data: str) -> DevVarLongStringArrayType
  delayModel() -> str
  init_command_objects() -> None
  lastHpsScanConfiguration() -> str
  vccIDs() -> List[int]
}

class "FspModeSubarrayComponentManager"{
  config_id : str
  delay_model : str
  last_hps_scan_configuration : str
  scan_id : int
  vcc_ids : list
  update_delay_model(model: str) -> tuple[ResultCode, str]
  update_health_state_from_hps() -> HealthState
}

MidCBFObsDevice <|-- FspModeSubarray
MidCBFObsComponentManager <|-- FspModeSubarrayComponentManager

@enduml

@startuml

class FspModeSubarray
class FspModeSubarrayComponentManager
class FspCorrSubarrayComponentManager
class FHS_FSPCorr <<interface>>

class "FspCorrSubarray"{
  FhsFspCorrControllerAddress : device_property
  create_component_manager() -> FspCorrSubarrayComponentManager
  frequencyBand() -> tango.DevEnum
  frequencySliceID() -> int
}

class "FspCorrSubarrayComponentManager"{
  channel_averaging_map
  config_id
  frequency_band : int
  frequency_slice_id : int
  fsp_channel_offset : int
  last_scan_configuration
  output_link_map
  vis_destination_address : dict
}

FspModeSubarrayComponentManager <|-- FspCorrSubarrayComponentManager
FspCorrSubarray *-- FspCorrSubarrayComponentManager
FspCorrSubarrayComponentManager "1" -- "8" FHS_FSPCorr
FspModeSubarray <|-- FspCorrSubarray

@enduml

@startuml classes
set namespaceSeparator none
class FpgaBoardUtil

FpgaBoardUtil : -_fpga_board_lane_mapping : dict[dict[int, int]]

FpgaBoardUtil : +get_fpga_lane_vccid_fs_map(fpga_board: int, freq_slice_id: int) -> dict[dict[int, int, int]]

FpgaBoardUtil : -_generate_default(fpga_board: int, freq_slice_id: int) -> dict[dict[int, int]]

@enduml

@startuml sync-fsp-output
!include mid-cbf-puml-definitions.txt

title Synchronizing FSP Output\n

' ======================================
participant "CSP_Mid\n.LMC" as lmc #Thistle
box "\nMCS\n"
    participant "Mid.CBF\nSubarray1" as subarray
    collections "Mid.CBF\nFspCorrSubarray" as corr_subarray

end box

box "\nFHS FSP"
    collections "FHS FSP Corr" as fhs_fsp
end box

' ======================================


' Request resource status report
lmc  ->>  subarray ++  : Scan()

' Controller loops through all FSPs in use by Subarray

loop #LightCyan each FspCorrSubarray in use
subarray ->>  corr_subarray ++ : subscribe scanStartTimeRounded
subarray -> subarray : set _scan_started = False
subarray ->>  corr_subarray : Scan()
end loop

loop #LightCyan each FHS FSP in use
corr_subarray ->> fhs_fsp ++ : subscribe subarray1ScanStartTimeRounded
corr_subarray -> corr_subarray : clear scanStartTimeRounded
corr_subarray ->> fhs_fsp : Scan()
corr_subarray <<-- fhs_fsp : subarray1ScanStartTimeRounded
alt#Gold #LightCyan scanStartTimeRounded is None and\nsubarray1ScanStartTimeRounded is not None
    corr_subarray -> corr_subarray : write scanStartTimeRounded
else #LightGreen scanStartTimeRounded is not None
    corr_subarray -> corr_subarray : do nothing
end
end loop

loop #LightCyan each FspCorrSubarray in use
subarray <<-- corr_subarray : scanStartTimeRounded
end loop

alt#Gold  #LightCyan _scanStarted = False
    subarray -> subarray : set _scan_started = True
    loop #LightCyan each FspCorrSubarray in use
    subarray ->> corr_subarray : SetFirstOutputTime()
    end loop
    loop #LightCyan each FHS FSP in use
    corr_subarray ->> fhs_fsp : SetFirstOutputTime()
    end loop
else #LightGreen _scanStarted = True
    subarray -> subarray : do nothing
end

lmc ->> subarray : EndScan()
loop #LightCyan each FspCorrSubarray
subarray ->> corr_subarray : EndScan()
end loop

loop #LightCyan each FHS FSP in use
corr_subarray ->> fhs_fsp : EndScan()
end loop

@enduml

Mid.CBF MCS Hardware Control

Reference