From c1b8bb4a344dd7d5e1f7ddb1076e9c81a435955a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Romain=20BRON=C3=88S?= <romain.brones@synchrotron-soleil.fr>
Date: Thu, 25 Jan 2024 16:48:21 +0100
Subject: [PATCH] Keep working

* Have configuration of blocks working
* Have basic deals with deviceserver working
---
 FofbTool/CommandLineInterface.py |  46 ++--
 FofbTool/Configuration.py        | 362 ++++++++++++++++++-------------
 FofbTool/Utils.py                | 112 +++++++++-
 3 files changed, 343 insertions(+), 177 deletions(-)

diff --git a/FofbTool/CommandLineInterface.py b/FofbTool/CommandLineInterface.py
index a15663d..9e448bf 100755
--- a/FofbTool/CommandLineInterface.py
+++ b/FofbTool/CommandLineInterface.py
@@ -16,6 +16,7 @@ if __name__ == '__main__':
     # Safer import: add the parent dir in path
     sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
     import FofbTool.Utils
+    import FofbTool.Configuration
 
 
     # Get the module logger
@@ -30,27 +31,17 @@ if __name__ == '__main__':
     parser = argparse.ArgumentParser("FofbTool")
     parser.add_argument("--log", default="info",
             help="Log level (error, warning, info, debug)")
-    parser.add_argument("--init-opcua", action="store_true",
+
+    parser.add_argument("--DS-init-opcua", action="store_true",
             help="Run init on opcua devices.")
-    parser.add_argument("--init-watcher", action="store_true",
+    parser.add_argument("--DS-init-watcher", action="store_true",
             help="Run init on the Fofb-Watcher device, and then the Fofb-Command.")
-    parser.add_argument("--conf-DS", action="store_true",
+    parser.add_argument("--DS-conf", action="store_true",
             help="Applying attribute configuration on Tango Device Servers. This is required after restart of devices.")
-    parser.add_argument("--stop", action="store_true",
-            )
-    parser.add_argument("--conf", action="store_true",
-            )
-    parser.add_argument("--start", action="store_true",
-            )
-    parser.add_argument("--disable-corr", action="store_true",
-            help="Disable cellnode corrector output frames."
-            )
-    parser.add_argument("--respmat", default=None,
-            help="Configure response matrix from file"
-            )
-    parser.add_argument("node", default="allnodes", nargs='*',
-            choices=('c01', 'c06', 'c09', 'c14', 'central', 'allcells', 'allnodes'),
-            help="Node to apply the selected actions. Default is all.")
+
+    parser.add_argument("--configure", choices=["combpm", "ccn", "comcorr", "corr", "all", "every"], nargs="+",
+            help="Configuration commands for the Fofb applications blocs."+
+            " 'all' is for all com, not configuring corrector. 'every' configure everything.")
 
     args = parser.parse_args()
 
@@ -59,15 +50,28 @@ if __name__ == '__main__':
 
     logger.debug(args)
 
-    if args.init_opcua:
+    ## Device Server related commands
+    if args.DS_init_opcua:
         FofbTool.Utils.init_opcua()
 
-    if args.init_watcher:
+    if args.DS_init_watcher:
         FofbTool.Utils.init_watcher()
 
-    if args.conf_DS:
+    if args.DS_conf:
         FofbTool.Utils.confds_opcua()
 
+    for conf in args.configure:
+        if conf in ("combpm", "all", "every"):
+            FofbTool.Utils.conf_all_combpm()
+        if conf in ("comcorr", "all", "every"):
+            FofbTool.Utils.conf_all_comcorr()
+        if conf in ("ccn", "all", "every"):
+            FofbTool.Utils.conf_all_ccn()
+        if conf in ("corr", "every"):
+            FofbTool.Configuration.centralnode_configure_corr()
+
+    exit(0)
+
     if args.stop:
         for cnp in cellnode_subscribers:
             cellnode_stop_ccn(cnp)
diff --git a/FofbTool/Configuration.py b/FofbTool/Configuration.py
index 359d5f5..1b1f2b3 100755
--- a/FofbTool/Configuration.py
+++ b/FofbTool/Configuration.py
@@ -1,108 +1,148 @@
-#!/usr/bin/env python
+###################################################################################################
+#    CONFIGURATION FUNCTIONS
+###################################################################################################
+#
+# Contains functions to configure blocks of the FOFB application.
+#
+###################################################################################################
 
 import tango
 import logging
 import argparse
 import numpy as np
 import time
+import FofbTool.Utils
 
 
 # Get the module logger
 logger = logging.getLogger("FofbTool")
 
+
 ###################################################################################################
-#    TANGO DEVICE PROXIES
+#    CONFIGURE COM BPM
 ###################################################################################################
 
-cellnode_subscribers = [ tango.DeviceProxy("ans/dg/fofb-cellnode-{}".format(cell)) for cell in ("C01", "C06", "C09", "C14") ]
+# Filter list depends on the cellnode. These are the default values.
+bpmfilterlist = {
+        "cellnode-c01":np.array(list(range(1,23))+list(range(115,123))),
+        "cellnode-c06":np.array(range(23,53)),
+        "cellnode-c09":np.array(range(53,83)),
+        "cellnode-c14":np.array(range(83,115)),
+        }
+
+def cellnode_configure_combpm(cellnodename, bpmallowed=None):
+    """
+    Configure the combpm block of a CellNode.
+    The BPM data allowed through are either taken in the argument, or default to nominal values.
+
+
+    PARAMETERS
+    ----------
+    cellnodename: str
+        The target cellnode, ie 'cellnode-c09'
+    bpmallowed: [int], None
+        List of BPMID allowed through the block. If None, default to nominal values.
+
+    RETURN
+    ------
+    success: boolean
+        True if configuration is a success
+    """
+
+    # Get device proxy
+    try:
+        p = FofbTool.Utils.tangopath_cellnodes[cellnodename.lower()]
+    except KeyError:
+        logger.error("Wrong cellnodename. Possibilities are {}".format(FofbTool.Utils.tangopath_cellnodes.keys()))
+        return False
+
+    try:
+        prx= tango.DeviceProxy(p)
+    except tango.DevFailed as e:
+        logger.error("Failed to get the Device proxy to '{}'".format(p))
+        logger.debug(str(e))
+        return False
+
+    # Select BPM id allowed to pass through
+    if bpmallowed is None:
+        logger.debug("Default to nominal values for BPM filter")
+        bpmallowed = bpmfilterlist[cellnodename.lower()]
 
-centralnode_subscriber = tango.DeviceProxy("ans/dg/fofb-centralnode")
 
-bpmmanager = tango.DeviceProxy("ans/dg/bpm-manager")
+    logger.debug("Activate BPMs {} in the filter for {}".format(bpmallowed, p))
+    f = prx["combpm_filter_table"].value
+    f[:] = 0
+    f[np.array(bpmallowed)] = 0x80
+    prx["combpm_filter_table"] = f
 
-fofbcommand = tango.DeviceProxy("ans/dg/fofb-command")
+    logger.info("Configuration of ComBpm done on {}.".format(p))
+    return True
 
 
 ###################################################################################################
-#    OPERATION FUNCTIONS
+#    CONFIGURE CCN: COM CELLNODES
 ###################################################################################################
 
-def cellnode_stop_ccn(cnp):
-    logger.info("Stopping CCN on {}".format(cnp.name()))
-    cnp["ccnpack0_control"] = False
-    cnp["ccnunpack0_control"] = False
-
-def cellnode_start_ccn(cnp):
-    logger.info("Starting CCN on {}".format(cnp.name()))
-    cnp["ccneth0_reset"] = 0x60000001 # impossible to write 0xE0000001
-    cnp["ccneth0_gt_reset"] = 1
-    cnp["ccneth0_gt_reset"] = 0
-    cnp["ccneth0_reset"] = 0
-    cnp["ccnpack0_control"] = True
-    cnp["ccnunpack0_control"] = True
-
-def cellnode_ack_ccn(snp):
-    logger.info("Ack CCN error on {}".format(cnp.name()))
-    cnp["ccnpack0_reset_error"] = True
-    cnp["ccnunpack0_reset_error"] = True
-    cnp["ccnpack0_reset_error"] = False
-    cnp["ccnunpack0_reset_error"] = False
-
-def centralnode_stop_ccn(cnp):
-    logger.info("Stopping CCN on {}".format(cnp.name()))
-    for n in range(4):
-        cnp["ccnpack{}_control".format(n)] = False
-        cnp["ccnunpack{}_control".format(n)] = False
 
-def centralnode_start_ccn(cnp):
-    logger.info("Starting CCN on {}".format(cnp.name()))
-    for n in range(4):
-        cnp["ccneth{}_reset".format(n)] = 0x60000001 # impossible to write 0xE0000001
-        cnp["ccneth{}_gt_reset".format(n)] = 1
-        cnp["ccneth{}_gt_reset".format(n)] = 0
-        cnp["ccneth{}_reset".format(n)] = 0
-        cnp["ccnpack{}_control".format(n)] = True
-        cnp["ccnunpack{}_control".format(n)] = True
-        cnp["ccnpack{}_reset_error".format(n)] = True
-        cnp["ccnunpack{}_reset_error".format(n)] = True
-        cnp["ccnpack{}_reset_error".format(n)] = False
-        cnp["ccnunpack{}_reset_error".format(n)] = False
-
-def cellnode_configure_ccn(cnp, nbpm=None, npsc=100):
+def cellnode_configure_ccn(cellnodename, nbpm=None, npsc=100):
     """
-    Configure the ComCellNode block.
+    Configure the ComCellNode block on a cellnode.
+    Automatically set the number of bpm/psc packets and MAC length.
 
     PARAMETERS
     ----------
+    cellnodename: str
+        The target cellnode, ie 'cellnode-c09'
     nbpm:
         Number of BPM allowed by the filter, hence the number of expected BPM packets.
         If None, auto detect the number from the combpm_filter_table attribute.
     npsc:
         Number of total PSC, hence the number of expected PSC packets.
+        Default to 100.
 
+    RETURN
+    ------
+    success: boolean
+        True if configuration is a success
     """
 
+    # Get device proxy
+    try:
+        p = FofbTool.Utils.tangopath_cellnodes[cellnodename.lower()]
+    except KeyError:
+        logger.error("Wrong cellnodename. Possibilities are {}".format(FofbTool.Utils.tangopath_cellnodes.keys()))
+        return False
+
+    try:
+        prx= tango.DeviceProxy(p)
+    except tango.DevFailed as e:
+        logger.error("Failed to get the Device proxy to '{}'".format(p))
+        logger.debug(str(e))
+        return False
+
     if nbpm is None:
         # Get number of BPM activated in the filter
-        nbpm = int((cnp["combpm_filter_table"].value == 0x80).sum())
-        logger.debug("{} bpm allowed in the filter on {}".format(nbpm, cnp.name()))
+        nbpm = int((prx["combpm_filter_table"].value == 0x80).sum())
+        logger.debug("{} bpm allowed in the filter on {}".format(nbpm, p))
 
     maclen = 10*nbpm+10
     logger.debug("Configure packeter framesize (mac length) to {}".format(maclen))
-    cnp["ccnpack0_framesize"] = maclen
+    prx["ccnpack0_framesize"] = maclen
 
     logger.debug("Configure packeter npackets to {}".format(nbpm-1))
-    cnp["ccnpack0_npackets"] = nbpm-1
+    prx["ccnpack0_npackets"] = nbpm-1
 
     maclen = npsc*6+10
     logger.debug("Configure unpacketer framesize (mac length) to {}".format(maclen))
-    cnp["ccnunpack0_framesize"] = maclen
+    prx["ccnunpack0_framesize"] = maclen
 
-    logger.info("Configuration of CCN done on {}.".format(cnp.name()))
+    logger.info("Configuration of CCN done on {}.".format(p))
+    return True
 
-def centralnode_configure_ccn(cnp, nbpm=[30,30,30,32], npsc=100):
+def centralnode_configure_ccn(nbpm=[30,30,30,32], npsc=100):
     """
-    Configure the ComCellNode block.
+    Configure the ComCellNode block on the centralnode.
+    Automatically set the number of bpm/psc packets and MAC length.
 
     PARAMETERS
     ----------
@@ -111,120 +151,142 @@ def centralnode_configure_ccn(cnp, nbpm=[30,30,30,32], npsc=100):
     npsc:
         Number of total PSC, hence the number of expected PSC packets.
 
+    RETURN
+    ------
+    success: boolean
+        True if configuration is a success
     """
+    p = FofbTool.Utils.tangopath_nodes["centralnode"]
+    try:
+        prx= tango.DeviceProxy(p)
+    except tango.DevFailed as e:
+        logger.error("Failed to get the Device proxy to '{}'".format(p))
+        logger.debug(str(e))
+        return False
 
     for n in range(4):
-
         maclen = npsc*6+10
         logger.debug("Configure packeter {} framesize (mac length) to {}".format(n, maclen))
-        cnp["ccnpack{}_framesize".format(n)] = maclen
+        prx["ccnpack{}_framesize".format(n)] = maclen
 
         logger.debug("Configure packeter {}  npackets to {}".format(n, npsc-1))
-        cnp["ccnpack{}_npackets".format(n)] = npsc-1
+        prx["ccnpack{}_npackets".format(n)] = npsc-1
 
         maclen = 10*nbpm[n]+10
         logger.debug("Configure unpacketer {} framesize (mac length) to {}".format(n, maclen))
-        cnp["ccnunpack{}_framesize".format(n)] = maclen
-
-    logger.info("Configuration of CCN done on {}.".format(cnp.name()))
-
-
-def cellnode_stop_combpm(cnp):
-    logger.info("Stopping ComBpm on {}".format(cnp.name()))
-    cnp["combpm_reset"] = 1
-    cnp["combpm_gt_control"] = 0x5
-
-def cellnode_start_combpm(cnp):
-    logger.info("Starting ComBpm on {}".format(cnp.name()))
-    cnp["combpm_reset"] = 0
-    cnp["combpm_gt_control"] = 0x1
-    cnp["combpm_reset_error"] = True
-    cnp["combpm_reset_error"] = False
-
-def cellnode_configure_combpm(cnp):
-
-    # Filter list depends on the cellnode
-    filterlist = {
-            "C01":np.array(list(range(1,23))+list(range(115,123))),
-            "C06":np.array(range(23,53)),
-            "C09":np.array(range(53,83)),
-            "C14":np.array(range(83,115)),
-            }
-
-    for k in filterlist.keys():
-        if k in cnp.name():
-            logger.debug("Activate BPMs {} in the filter for {}".format(filterlist[k], cnp.name()))
-            f = cnp["combpm_filter_table"].value
-            f[:] = 0
-            f[np.array(filterlist[k])] = 0x80
-            cnp["combpm_filter_table"] = f
-
-    logger.info("Configuration of ComBpm done on {}.".format(cnp.name()))
-
-def cellnode_configure_comcorr(cnp, enable=True):
-
-    pscidlist = {
-        'C01':[50,100,49,99,255,255,255,255,2,52,1,51,255,255,255,255,56,6,3,53,4,54,5,55,10,60,7,57,8,58,9,59],
-        'C06':[12,62,11,61,255,255,255,255,14,64,13,63,255,255,255,255,68,18,15,65,16,66,17,67,22,72,19,69,20,70,21,71],
-        'C09':[24,74,23,73,255,255,255,255,26,76,25,75,255,255,255,255,80,30,27,77,28,78,29,79,34,84,31,81,32,82,33,83],
-        'C14':[36,86,35,85,37,87,38,88,40,90,39,89,255,255,255,255,94,44,41,91,42,92,43,93,48,98,45,95,46,96,47,97]
-        }
+        prx["ccnunpack{}_framesize".format(n)] = maclen
 
-    for k in pscidlist.keys():
-        if k in cnp.name():
-            logger.debug("Set PSCIDs {} in the filter for {}".format(pscidlist[k], cnp.name()))
-            f= cnp["comcorr_line_id"].value
-            f[:] = pscidlist[k]
-            f[:] = f+ 0x10000*bool(enable)
-            logger.debug("Set comcorr_line_id {} for {}".format(f, cnp.name()))
-            cnp["comcorr_line_id"] = f
+    logger.info("Configuration of CCN done on {}.".format(p))
+    return True
 
-    logger.info("Configuration of ComCorr done on {}.".format(cnp.name()))
+###################################################################################################
+#    CONFIGURE COM CORR
+###################################################################################################
 
-def centralnode_configure_corr(cnp):
+pscidlist = {
+    'cellnode-c01':[50,100,49,99,255,255,255,255,2,52,1,51,255,255,255,255,56,6,3,53,4,54,5,55,10,60,7,57,8,58,9,59],
+    'cellnode-c06':[12,62,11,61,255,255,255,255,14,64,13,63,255,255,255,255,68,18,15,65,16,66,17,67,22,72,19,69,20,70,21,71],
+    'cellnode-c09':[24,74,23,73,255,255,255,255,26,76,25,75,255,255,255,255,80,30,27,77,28,78,29,79,34,84,31,81,32,82,33,83],
+    'cellnode-c14':[36,86,35,85,37,87,38,88,40,90,39,89,255,255,255,255,94,44,41,91,42,92,43,93,48,98,45,95,46,96,47,97]
+    }
 
-    # Legacy
-    cnp["corr_k1a_x"]=256
-    cnp["corr_k1b_x"]=0
-    cnp["corr_k1ic_x"]=64
-    cnp["corr_k1d_x"]=16300
+def cellnode_configure_comcorr(cellnodename, pscid=None, enable=True):
+    """
+    Configure the comcorr block of a CellNode.
+    The PSC ID either taken in the argument, or default to nominal values.
 
-    cnp["corr_k1a_y"]=256
-    cnp["corr_k1b_y"]=0
-    cnp["corr_k1ic_y"]=64
-    cnp["corr_k1d_y"]=16300
 
-    # Unitary
-    cnp["corr_k2a_x"]=128
-    cnp["corr_k2b_x"]=0
-    cnp["corr_k2ic_x"]=8192
-    cnp["corr_k2d_x"]=0
+    PARAMETERS
+    ----------
+    cellnodename: str
+        The target cellnode, ie 'cellnode-c09'
+    pscid: [int], None
+        List of 32 PSCID to program on the output board. If None, default to nominal values.
+
+    enable: boolean
+        Enable or not the hardware outputs.
+
+    RETURN
+    ------
+    success: boolean
+        True if configuration is a success
+    """
 
-    cnp["corr_k2a_y"]=128
-    cnp["corr_k2b_y"]=0
-    cnp["corr_k2ic_y"]=8192
-    cnp["corr_k2d_y"]=0
+    # Get device proxy
+    try:
+        p = FofbTool.Utils.tangopath_cellnodes[cellnodename.lower()]
+    except KeyError:
+        logger.error("Wrong cellnodename. Possibilities are {}".format(FofbTool.Utils.tangopath_cellnodes.keys()))
+        return False
+
+    try:
+        prx= tango.DeviceProxy(p)
+    except tango.DevFailed as e:
+        logger.error("Failed to get the Device proxy to '{}'".format(p))
+        logger.debug(str(e))
+        return False
+
+    if pscid is None:
+        logger.debug("Default to nominal values for PSCID")
+        pscid = pscidlist[cellnodename.lower()]
+    else:
+        if len(pscid) != 32:
+            logger.error("pscid shall have length 32")
+            return False
+
+
+    logger.debug("Set PSCIDs {} in the filter for {}".format(pscid, p))
+    f= prx["comcorr_line_id"].value
+    f[:] = pscid
+    f[:] = f+ 0x10000*bool(enable)
+    logger.debug("Set comcorr_line_id {} for {}".format(f, p))
+    prx["comcorr_line_id"] = f
+
+    logger.info("Configuration of ComCorr done on {}.".format(p))
+    return True
 
-    f= cnp["corr_pscid"].value
-    f[0:100] = range(1,101)
-    cnp["corr_pscid"] = f
+###################################################################################################
+#    CONFIGURE MATRIX CORRECTOR
+###################################################################################################
 
-    logger.info("Configuration of Corr done on {}.".format(cnp.name()))
+def centralnode_configure_corr():
+    """
+    Configure the correction algorithm on the centralnode.
+    """
+    p = FofbTool.Utils.tangopath_nodes["centralnode"]
+    try:
+        prx= tango.DeviceProxy(p)
+    except tango.DevFailed as e:
+        logger.error("Failed to get the Device proxy to '{}'. Configuration of corrector algorithm failed.".format(p))
+        logger.debug(str(e))
+        return False
 
-def fofbcommand_writeref(what='current'):
-    if what=="current":
-        fofbcommand["x_ref_orbit"] = (bpmmanager.xmeanorbit*1e6).astype(int)
-        fofbcommand["y_ref_orbit"] = (bpmmanager.zmeanorbit*1e6).astype(int)
+    # Legacy
+    prx["corr_k1a_x"]=256
+    prx["corr_k1b_x"]=0
+    prx["corr_k1ic_x"]=64
+    prx["corr_k1d_x"]=16300
 
-    if what=="oldref":
-        fofbcommand["x_ref_orbit"] = (bpmmanager.xreforbit*1e6).astype(int)
-        fofbcommand["y_ref_orbit"] = (bpmmanager.zreforbit*1e6).astype(int)
+    prx["corr_k1a_y"]=256
+    prx["corr_k1b_y"]=0
+    prx["corr_k1ic_y"]=64
+    prx["corr_k1d_y"]=16300
 
-    if what=="zeros":
-        fofbcommand["x_ref_orbit"] = np.zeros(122, dtype=int)
-        fofbcommand["y_ref_orbit"] = np.zeros(122, dtype=int)
+    # Unitary
+    prx["corr_k2a_x"]=128
+    prx["corr_k2b_x"]=0
+    prx["corr_k2ic_x"]=8192
+    prx["corr_k2d_x"]=0
+
+    prx["corr_k2a_y"]=128
+    prx["corr_k2b_y"]=0
+    prx["corr_k2ic_y"]=8192
+    prx["corr_k2d_y"]=0
+
+    f= prx["corr_pscid"].value
+    f[0:100] = range(1,101)
+    prx["corr_pscid"] = f
 
-def fofbcommand_writemat(filename='respmat.npy'):
+    logger.info("Configuration of Corr done on {}.".format(p))
+    return True
 
-    fofbcommand["x_inv_resp_mat"] = np.hstack([np.zeros((50, 1)), np.load(filename)[50:], np.zeros((50,5))]).astype(int)
-    fofbcommand["y_inv_resp_mat"] = np.hstack([np.zeros((50, 1)), np.load(filename)[:50], np.zeros((50,5))]).astype(int)
diff --git a/FofbTool/Utils.py b/FofbTool/Utils.py
index 15da6a9..02237b8 100644
--- a/FofbTool/Utils.py
+++ b/FofbTool/Utils.py
@@ -8,25 +8,30 @@
 
 import tango
 import logging
-import DeviceAttributeConfiguration
+import FofbTool.DeviceAttributeConfiguration
 
 # Get the module logger
 logger = logging.getLogger("FofbTool")
 
-tangopath_nodes = {
-        "centralnode":"ans/dg/fofb-centralnode",
+tangopath_cellnodes = {
         "cellnode-c01":"ans/dg/fofb-cellnode-c01",
         "cellnode-c06":"ans/dg/fofb-cellnode-c06",
         "cellnode-c09":"ans/dg/fofb-cellnode-c09",
         "cellnode-c14":"ans/dg/fofb-cellnode-c14",
         }
 
+tangopath_nodes = {
+        "centralnode":"ans/dg/fofb-centralnode",
+        }
+tangopath_nodes.update(tangopath_cellnodes)
+
 tangopath = {
         "fofb-watcher":"ans/dg/fofb-watcher",
         "fofb-command":"ans/dg/fofb-command",
         "fofb-manager":"ans/dg/fofb-manager",
         "bpm-manager":"ans/dg/bpm-manager",
-        }.update(tangopath_nodes)
+        }
+tangopath.update(tangopath_nodes)
 
 def init_opcua():
     """
@@ -72,12 +77,107 @@ def confds_opcua():
 
         try:
             if 'central' in n:
-                DeviceAttributeConfiguration.set_attr_config_centralnode(prx)
+                FofbTool.DeviceAttributeConfiguration.set_attr_config_centralnode(prx)
             else:
-                DeviceAttributeConfiguration.set_attr_config_cellnode(prx)
+                FofbTool.DeviceAttributeConfiguration.set_attr_config_cellnode(prx)
         except tango.DevFailed as e:
             logger.error("Could not set attribute configuration for '{}', got DevFailed.".format(p))
             logger.debug(str(e))
 
 
+def check_fofbnotrunning():
+    """
+    Check if the FOFB is not running.
+    If it fails to know, return False and log error.
+
+    RETURN
+    ------
+    running: Boolean
+        True if FOFB is not running
+    """
+
+    try:
+        prx = tango.DeviceProxy(tangopath["fofb-watcher"])
+    except tango.DevFailed as e:
+        logger.error("Failed to get the Device proxy to '{}'".format(tangopath["fofb-watcher"]))
+        logger.debug(str(e))
+        return False
+
+    try:
+        return not (prx.fofbrunning_x or prx.fofbrunning_y)
+    except tango.DevFailed as e:
+        logger.error("Failed to read the FOFB status on device Fofb-Watcher")
+        logger.debug(str(e))
+        return False
+
+def conf_all_combpm():
+    """
+    Run default configuration of all combpm blocks.
+    Check beforehand that the FOFB is not running.
+
+    RETURN
+    ------
+    running: Boolean
+        True if FOFB is not running
+    """
+
+    if not check_fofbnotrunning():
+        logger.warning("Not running configuration of combpm because FOFB seems to be running.")
+        return False
+
+    success=True
+    for i,(n,p) in enumerate(tangopath_cellnodes.items()):
+        s=FofbTool.Configuration.cellnode_configure_combpm(n)
+        success = success and s
+
+    return success
+
+
+def conf_all_comcorr():
+    """
+    Run default configuration of all comcorr blocks.
+    Check beforehand that the FOFB is not running.
+
+    RETURN
+    ------
+    running: Boolean
+        True if FOFB is not running
+    """
+
+    if not check_fofbnotrunning():
+        logger.warning("Not running configuration of comcorr because FOFB seems to be running.")
+        return False
+
+    success=True
+    for i,(n,p) in enumerate(tangopath_cellnodes.items()):
+        s=FofbTool.Configuration.cellnode_configure_comcorr(n)
+        success = success and s
+
+    return success
+
+
+def conf_all_ccn():
+    """
+    Run default configuration of all comcellnode blocks.
+    Check beforehand that the FOFB is not running.
+
+    RETURN
+    ------
+    running: Boolean
+        True if FOFB is not running
+    """
+
+    if not check_fofbnotrunning():
+        logger.warning("Not running configuration of comcorr because FOFB seems to be running.")
+        return False
+
+    success=True
+    for i,(n,p) in enumerate(tangopath_cellnodes.items()):
+        s=FofbTool.Configuration.cellnode_configure_ccn(n)
+        success = success and s
+
+    s=FofbTool.Configuration.centralnode_configure_ccn()
+    success = success and s
+
+    return success
 
-- 
GitLab