コード例 #1
0
ファイル: EDDPipeline.py プロジェクト: TobiasWinchen/mpikat
    def setup_sensors(self):
        """
        Setup monitoring sensors.

        The EDDPipeline base provides default sensors. Should be called by
        every subclass to ensure default sensors are available.

        """
        self._pipeline_sensor_status = Sensor.discrete(
            "pipeline-status",
            description="Status of the pipeline",
            params=self.PIPELINE_STATES,
            default="idle",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._pipeline_sensor_status)

        self._edd_config_sensor = Sensor.string(
            "current-config",
            description="The current configuration for the EDD backend",
            default=json.dumps(self._config, indent=4),
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._edd_config_sensor)

        self._log_level = Sensor.string("log-level",
                                        description="Log level",
                                        default=logging.getLevelName(
                                            log.level),
                                        initial_status=Sensor.NOMINAL)
        self.add_sensor(self._log_level)
コード例 #2
0
  def setup_sensors(self):
    """Setup server sensors."""
    self.script.log(2, "KATCPServer::setup_sensors()")

    self._device_status = Sensor.discrete("device-status",
      description="Status of entire system",
      params=self.DEVICE_STATUSES,
      default="ok")
    self.add_sensor(self._device_status)

    self._beam_name = Sensor.string("beam-name",
      description="name of configured beam",
      unit="",
      default="")
    self.add_sensor(self._beam_name)

    # setup host based sensors   
    self._host_name = Sensor.string("host-name",
      description="hostname of this server",
      unit="",
      default="")
    self.add_sensor(self._host_name)

    self.script.log(2, "KATCPServer::setup_sensors lmc="+str(self.script.lmc))
    (host, port) = self.script.lmc.split(":")
    self.setup_sensors_host (host, port)

    self.script.log(2, "KATCPServer::setup_sensors beams="+str(self.script.beam))
    self.setup_sensors_beam (self.script.beam_name)
コード例 #3
0
    def setup_sensors(self):
        """
        @brief    Set up all sensors on the server

        @note     This is an internal method and is invoked by
                  the constructor of the base class.
        """
        super(EddMasterController, self).setup_sensors()
        self._control_mode_sensor = Sensor.string(
            "control-mode",
            description="The control mode for the EDD",
            default=self._control_mode,
            initial_status=Sensor.NOMINAL)
        self.add_sensor(self._control_mode_sensor)
        self._edd_config_sensor = Sensor.string(
            "current-config",
            description="The current configuration for the EDD backend",
            default="",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._edd_config_sensor)
        self._edd_scpi_interface_addr_sensor = Sensor.string(
            "scpi-interface-addr",
            description="The SCPI interface address for this instance",
            default="{}:{}".format(self._scpi_ip, self._scpi_port),
            initial_status=Sensor.NOMINAL)
        self.add_sensor(self._edd_scpi_interface_addr_sensor)
コード例 #4
0
    def setup_sensors(self):
        """
        @brief    Set up monitoring sensors.

        Sensor list:
        - device-status
        - local-time-synced
        - fbf0-status
        - fbf1-status

        @note     The following sensors are made available on top of default sensors
                  implemented in AsynDeviceServer and its base classes.

                  device-status:      Reports the health status of the FBFUSE and associated devices:
                                      Among other things report HW failure, SW failure and observation failure.
        """
        self._device_status_sensor = Sensor.discrete(
            "device-status",
            description = "Health status of FbfWorkerServer instance",
            params = self.DEVICE_STATUSES,
            default = "ok",
            initial_status = Sensor.NOMINAL)
        self.add_sensor(self._device_status_sensor)

        self._state_sensor = LoggingSensor.discrete(
            "state",
            params = self.STATES,
            description = "The current state of this worker instance",
            default = self.IDLE,
            initial_status = Sensor.NOMINAL)
        self._state_sensor.set_logger(log)
        self.add_sensor(self._state_sensor)

        self._delay_client_sensor = Sensor.string(
            "delay-engine-server",
            description = "The address of the currently set delay engine",
            default = "",
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._delay_client_sensor)

        self._antenna_capture_order_sensor = Sensor.string(
            "antenna-capture-order",
            description = "The order in which the worker will capture antennas internally",
            default = "",
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._antenna_capture_order_sensor)

        self._mkrecv_header_sensor = Sensor.string(
            "mkrecv-header",
            description = "The MKRECV/DADA header used for configuring capture with MKRECV",
            default = "",
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._mkrecv_header_sensor)
コード例 #5
0
ファイル: device_server.py プロジェクト: UCBerkeleySETI/spip
    def setup_sensors(self):
        """Setup server sensors."""
        self.script.log(2, "KATCPServer::setup_sensors()")

        self._device_status = Sensor.discrete(
            "device-status",
            description="Status of entire system",
            params=self.DEVICE_STATUSES,
            default="ok")
        self.add_sensor(self._device_status)

        self._beam_name = Sensor.string("beam-name",
                                        description="name of configured beam",
                                        unit="",
                                        default="")
        self.add_sensor(self._beam_name)

        # setup host based sensors
        self._host_name = Sensor.string("host-name",
                                        description="hostname of this server",
                                        unit="",
                                        default="")
        self.add_sensor(self._host_name)

        # GUI URL TODO remove hardcoding
        guis = [{
            "title": "PTUSE Web Interface",
            "description": "Live Pulsar timing monitoring plots",
            "href": self.script.cfg["SPIP_ADDRESS"]
        }]
        encoded = json.dumps(guis)
        self._gui_urls = Sensor.string("gui-urls",
                                       description="PTUSE GUI URL",
                                       unit="",
                                       default=encoded)
        self.add_sensor(self._gui_urls)
        self._gui_urls.set_value(encoded)

        # give LMC some time to prepare the socket
        time.sleep(5)

        self.script.log(
            1, "KATCPServer::setup_sensors lmc=" + str(self.script.lmc))
        (host, port) = self.script.lmc.split(":")
        self.setup_sensors_host(host, port)

        self.script.log(
            2, "KATCPServer::setup_sensors beams=" + str(self.script.beam))
        self.setup_sensors_beam(self.script.beam_name)
コード例 #6
0
    def setup_sensors(self):
        """
        @brief    Set up monitoring sensors.

        @note     The following sensors are made available on top of default
                  sensors implemented in AsynDeviceServer and its base classes.
        """
        self._device_status_sensor = Sensor.discrete(
            "device-status",
            description="Health status of ApsWorkerServer instance",
            params=self.DEVICE_STATUSES,
            default="ok",
            initial_status=Sensor.NOMINAL)
        self.add_sensor(self._device_status_sensor)

        self._capture_interface_sensor = Sensor.string(
            "capture-interface",
            description="The IP address of the NIC to be used for data capture",
            default=self._capture_interface,
            initial_status=Sensor.NOMINAL)
        self.add_sensor(self._capture_interface_sensor)

        self._state_sensor = LoggingSensor.discrete(
            "state",
            params=self.STATES,
            description="The current state of this worker instance",
            default=self.IDLE,
            initial_status=Sensor.NOMINAL)
        self._state_sensor.set_logger(log)
        self.add_sensor(self._state_sensor)
コード例 #7
0
    def setup_sensors(self):
        """
        @brief    Set up monitoring sensors.

        @note     The following sensors are made available on top of defaul sensors
                  implemented in AsynDeviceServer and its base classes.

                  device-status:      Reports the health status of the FBFUSE and associated devices:
                                      Among other things report HW failure, SW failure and observation failure.
        """
        self._device_status = Sensor.discrete(
            "device-status",
            description="Health status of BLUSE",
            params=self.DEVICE_STATUSES,
            default="ok",
            initial_status=Sensor.NOMINAL)
        self.add_sensor(self._device_status)

        self._local_time_synced = Sensor.boolean(
            "local-time-synced",
            description="Indicates BLUSE is NTP syncronised.",
            default=True,  # TODO: implement actual NTP synchronization request
            initial_status=Sensor.NOMINAL)
        self.add_sensor(self._local_time_synced)

        self._version = Sensor.string(
            "version",
            description="Reports the current BLUSE version",
            default=str(self.VERSION_INFO[1:]).strip('()').replace(
                ' ', '').replace(",", '.'),  # e.g. '1.0'
            initial_status=Sensor.NOMINAL)
        self.add_sensor(self._version)
コード例 #8
0
    def __init__(self, name_suffix, nsum=100):
        """
        List of sensors and handler to be connected to a mkrecv process
        """
        self.sensors = {}

        self.sensors['global_payload_frac'] = Sensor.float(
            "global-payload-received-fraction-{}".format(name_suffix),
            description="Ratio of received and expected payload.",
            params=[0, 1])
        self.sensors['received_heaps_frac'] = Sensor.float(
            "received-heaps-frac-{}".format(name_suffix),
            description="Fraction of received heaps for last {} slots.".format(
                100),
            params=[0, 1])
        self.sensors['slot_received_heaps'] = Sensor.integer(
            "slot_received-heaps-{}".format(name_suffix),
            description="Received heaps.",
        )
        self.sensors['slot_expected_heaps'] = Sensor.integer(
            "slot_expected-heaps-{}".format(name_suffix),
            description="Expected heaps.",
        )

        self.sensors['missing_heaps'] = Sensor.string(
            "missing-heaps-{}".format(name_suffix),
            description="Missing heaps per multicast group.",
        )

        self.__received_heaps = 0.
        self.__expected_heaps = 0.
        self.__idx = 0
        self.__nsum = nsum

        self.__missing_heaps = np.zeros(8)
コード例 #9
0
ファイル: fbfuse_ca_server.py プロジェクト: ewanbarr/mpikat
    def request_target_configuration_start(self, req, product_id,
                                           target_string):
        """
        @brief      Set up a beam configuration sensor for the FBFUSE instance

        @param      product_id     The product identifier
        @param      target_string  A KATPOINT target string (boresight pointing position)
        """
        log.info(
            "Received target configuration request for '{}' with target: {}".
            format(product_id, target_string))
        if not product_id in self._configuration_sensors:
            log.debug(
                "Creating configuration sensor for '{}'".format(product_id))
            self._configuration_sensors[product_id] = Sensor.string(
                "{}-beam-position-configuration".format(product_id),
                description="Configuration description for FBF beam placement",
                default="",
                initial_status=Sensor.UNKNOWN)
            self.add_sensor(self._configuration_sensors[product_id])
            self.mass_inform(Message.inform('interface-changed'))
        initial_config = yield self.get_target_config(product_id,
                                                      target_string)
        self.update_target_config(product_id, initial_config)
        raise Return(("ok", ))
コード例 #10
0
 def setup_sensors(self):
     """Set up basic monitoring sensors.
     """
     for name, params in self._parser.items():
         if params["type"] == "float":
             sensor = Sensor.float(name,
                                   description=params["description"],
                                   unit=params.get("units", None),
                                   default=params.get("default", 0.0),
                                   initial_status=Sensor.UNKNOWN)
         elif params["type"] == "string":
             sensor = Sensor.string(name,
                                    description=params["description"],
                                    default=params.get("default", ""),
                                    initial_status=Sensor.UNKNOWN)
         elif params["type"] == "int":
             sensor = Sensor.integer(name,
                                     description=params["description"],
                                     default=params.get("default", 0),
                                     unit=params.get("units", None),
                                     initial_status=Sensor.UNKNOWN)
         elif params["type"] == "bool":
             sensor = Sensor.boolean(name,
                                     description=params["description"],
                                     default=params.get("default", False),
                                     initial_status=Sensor.UNKNOWN)
         else:
             raise Exception("Unknown sensor type '{0}' requested".format(
                 params["type"]))
         self.add_sensor(sensor)
コード例 #11
0
    def setup_sensors(self):
        """
        @brief    Setup the default KATCP sensors.

        @note     As this call is made only upon an PAF configure call a mass inform
                  is required to let connected clients know that the proxy interface has
                  changed.
        """
        self._state_sensor = LoggingSensor.discrete(
            "state",
            description="Denotes the state of this PAF instance",
            params=self.STATES,
            default=self.IDLE,
            initial_status=Sensor.NOMINAL)
        self._state_sensor.set_logger(self.log)
        self.add_sensor(self._state_sensor)

        self._servers_sensor = Sensor.string(
            "servers",
            description=
            "The worker server instances currently allocated to this product",
            default=",".join([
                "{s.hostname}:{s.port}".format(s=server)
                for server in self._servers
            ]),
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._servers_sensor)
        self._parent.mass_inform(Message.inform('interface-changed'))
        self._state_sensor.set_value(self.IDLE)
コード例 #12
0
    def setup_sensors(self):
        """
        @brief Setup monitoring sensors
        """
        EDDPipeline.setup_sensors(self)

        self._bandpass = Sensor.string(
            "bandpass_PNG",
            description="band-pass data (base64 encoded)",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._bandpass)

        self._level = Sensor.string(
            "level_PNG",
            description="ADC Level (base64 encoded)",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._level)
コード例 #13
0
    def setup_sensors(self):
        """
        @brief    Set up monitoring sensors.
        """
        self._target_sensors = []
        for beam in self._beam_manager.get_beams():
            sensor = Sensor.string("{}-target".format(beam.idx),
                                   description="Target for beam {}".format(
                                       beam.idx),
                                   default=beam.target.format_katcp(),
                                   initial_status=Sensor.UNKNOWN)
            self.add_sensor(sensor)
            beam.register_observer(lambda beam, sensor=sensor: sensor.
                                   set_value(beam.target.format_katcp()))

        antenna_map = {
            a.name: a.format_katcp()
            for a in self._beam_manager.antennas
        }
        self._antennas_sensor = Sensor.string(
            "antennas",
            description=
            "JSON breakdown of the antennas (in KATPOINT format) associated with this delay engine",
            default=json.dumps(antenna_map),
            initial_status=Sensor.NOMINAL)
        self.add_sensor(self._antennas_sensor)

        self._phase_reference_sensor = Sensor.string(
            "phase-reference",
            description=
            "A KATPOINT target string denoting the F-engine phasing centre",
            default="unset,radec,0,0",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._phase_reference_sensor)

        reference_antenna = Antenna(
            "reference,{ref.lat},{ref.lon},{ref.elev}".format(
                ref=self._beam_manager.antennas[0].ref_observer))
        self._reference_antenna_sensor = Sensor.string(
            "reference-antenna",
            description=
            "A KATPOINT antenna string denoting the reference antenna",
            default=reference_antenna.format_katcp(),
            initial_status=Sensor.NOMINAL)
        self.add_sensor(self._reference_antenna_sensor)
コード例 #14
0
ファイル: device_server.py プロジェクト: ajameson/spip
  def setup_sensors(self):
    """Setup server sensors."""
    self.script.log(2, "KATCPServer::setup_sensors()")

    self._device_status = Sensor.discrete("device-status",
      description="Status of entire system",
      params=self.DEVICE_STATUSES,
      default="ok")
    self.add_sensor(self._device_status)

    self._beam_name = Sensor.string("beam-name",
      description="name of configured beam",
      unit="",
      default="")
    self.add_sensor(self._beam_name)

    # setup host based sensors   
    self._host_name = Sensor.string("host-name",
      description="hostname of this server",
      unit="",
      default="")
    self.add_sensor(self._host_name)

    # GUI URL TODO remove hardcoding
    guis = [ { "title": "PTUSE Web Interface",
               "description": "Live Pulsar timing monitoring plots", 
               "href": self.script.cfg["SPIP_ADDRESS"] } ]
    encoded = json.dumps(guis)
    self._gui_urls = Sensor.string("gui-urls",
      description="PTUSE GUI URL",
      unit="",
      default=encoded)
    self.add_sensor(self._gui_urls) 
    self._gui_urls.set_value(encoded)

    # give LMC some time to prepare the socket
    time.sleep(5)

    self.script.log(1, "KATCPServer::setup_sensors lmc="+str(self.script.lmc))
    (host, port) = self.script.lmc.split(":")
    self.setup_sensors_host (host, port)

    self.script.log(2, "KATCPServer::setup_sensors beams="+str(self.script.beam))
    self.setup_sensors_beam (self.script.beam_name)
コード例 #15
0
    def setup_sensors(self):
        """
        @brief  Set up monitoring sensors.

        @note   The following sensors are made available on top of default sensors
                implemented in AsynDeviceServer and its base classes.

                device-status:  Reports the health status of the controller and associated devices:
                                Among other things report HW failure, SW failure and observation failure.

                local-time-synced:  Indicates whether the local time of the servers
                                    is synchronised to the master time reference (use NTP).
                                    This sensor is aggregated from all nodes that are part
                                    of FBF and will return "not sync'd" if any nodes are
                                    unsyncronised.

                products:   The list of product_ids that controller is currently handling
        """
        self._device_status = Sensor.discrete(
            "device-status",
            description="Health status of FBFUSE",
            params=self.DEVICE_STATUSES,
            default="ok",
            initial_status=Sensor.NOMINAL)
        self.add_sensor(self._device_status)

        self._local_time_synced = Sensor.boolean(
            "local-time-synced",
            description="Indicates FBF is NTP syncronised.",
            default=True,
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._local_time_synced)

        def ntp_callback():
            log.debug("Checking NTP sync")
            try:
                synced = check_ntp_sync()
            except Exception:
                log.exception("Unable to check NTP sync")
                self._local_time_synced.set_value(False)
            else:
                if not synced:
                    log.warning("Server is not NTP synced")
                self._local_time_synced.set_value(synced)

        ntp_callback()
        self._ntp_callback = PeriodicCallback(ntp_callback,
                                              NTP_CALLBACK_PERIOD)
        self._ntp_callback.start()

        self._products_sensor = Sensor.string(
            "products",
            description="The names of the currently configured products",
            default="",
            initial_status=Sensor.NOMINAL)
        self.add_sensor(self._products_sensor)
コード例 #16
0
 def setup_sensors(self):
     """
     @brief  Set up monitoring sensors.
     """
     super(FbfMasterController, self).setup_sensors()
     self._ip_pool_sensor = Sensor.string(
         "output-ip-range",
         description="The multicast address allocation for coherent beams",
         default=self._ip_pool.format_katcp(),
         initial_status=Sensor.NOMINAL)
     self.add_sensor(self._ip_pool_sensor)
コード例 #17
0
    def setup_sensors(self):
        self._config_sensor = Sensor.string(
            "configuration",
            description="The current configuration of the capture instance",
            default="",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._config_sensor)

        self._mkrecv_header_sensor = Sensor.string(
            "mkrecv-capture-header",
            description=
            "The MKRECV/DADA header used for configuring capture with MKRECV",
            default="",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._mkrecv_header_sensor)

        self._apsuse_args_sensor = Sensor.string(
            "apsuse-arguments",
            description="The command line arguments used to invoke apsuse",
            default="",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._apsuse_args_sensor)

        self._mkrecv_heap_loss = Sensor.float(
            "fbf-heap-loss",
            description=("The percentage of FBFUSE heaps lost "
                         "(within MKRECV statistics window)"),
            default=0.0,
            initial_status=Sensor.UNKNOWN,
            unit="%")
        self.add_sensor(self._mkrecv_heap_loss)

        self._ingress_buffer_percentage = Sensor.float(
            "ingress-buffer-fill-level",
            description=("The percentage fill level for the capture"
                         "buffer between MKRECV and APSUSE"),
            default=0.0,
            initial_status=Sensor.UNKNOWN,
            unit="%")
        self.add_sensor(self._ingress_buffer_percentage)
コード例 #18
0
    def setup_sensors(self):
        """Setup some server sensors."""
	
        self._add_result = Sensor.float("add.result",
                                        "Last ?add result.", "", [-10000, 10000])

        self._time_result = Sensor.timestamp("time.result",
                                             "Last ?time result.", "")

        self._eval_result = Sensor.string("eval.result",
                                          "Last ?eval result.", "")

        self._fruit_result = Sensor.discrete("fruit.result",
                                             "Last ?pick-fruit result.", "", self.FRUIT)
        self._device_armed = Sensor.boolean(
            "device-armed",
            description="Is the CAM server armed?",
            initial_status=Sensor.NOMINAL,
            default=True)
        self._bandwidth = Sensor.float("bandwidth", default=300)
        self._sourcename = Sensor.string("sourcename", default="none")
        self._source_ra = Sensor.string("source_RA", default=0)
        self._source_dec = Sensor.string("source_DEC", default=0)
        self._exposure_time = Sensor.float("EXP_time", default=0)

        self.add_sensor(self._sourcename)
        self.add_sensor(self._source_ra)
        self.add_sensor(self._source_dec)
        self.add_sensor(self._exposure_time)

        self.add_sensor(self._bandwidth)
        self.add_sensor(self._device_armed)
        self.add_sensor(self._add_result)
        self.add_sensor(self._time_result)
        self.add_sensor(self._eval_result)
        self.add_sensor(self._fruit_result)

        self._systemp_result = Sensor.float("add.result",
                                            "Last ?add result.", "", [-10000, 10000])
        self.add_sensor(self._systemp_result)
コード例 #19
0
    def setup_sensors(self):
        """Setup some server sensors."""
        self._add_result = Sensor.float("add.result",
            "Last ?add result.", "", [-10000, 10000])

        self._time_result = Sensor.timestamp("time.result",
            "Last ?time result.", "")

        self._eval_result = Sensor.string("eval.result",
            "Last ?eval result.", "")

        self._fruit_result = Sensor.discrete("fruit.result",
            "Last ?pick-fruit result.", "", self.FRUIT)

        self._james_result = Sensor.string("james.result",
            "Last ?james result.", "")

        self.add_sensor(self._add_result)
        self.add_sensor(self._time_result)
        self.add_sensor(self._eval_result)
        self.add_sensor(self._fruit_result)
        self.add_sensor(self._james_result)
コード例 #20
0
    def setup_sensors(self):
        """
        Setup monitoring sensors
        """
        EDDPipeline.setup_sensors(self)

        self._spectra_written = Sensor.integer(
            "written-packages",
            description="Number of spectra written to file.",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._spectra_written)

        self._incomplete_heaps = Sensor.integer(
            "incomplete-heaps",
            description="Incomplete heaps received.",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._incomplete_heaps)

        self._complete_heaps = Sensor.integer(
            "complete-heaps",
            description="Complete heaps received.",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._complete_heaps)

        self._current_file = Sensor.string("current-file",
                                           description="Current filename.",
                                           initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._current_file)

        self._current_file_size = Sensor.float("current-file-size",
                                               description="Current filesize.",
                                               initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._current_file_size)

        self._bandpass = Sensor.string(
            "bandpass",
            description="band-pass data (base64 encoded)",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._bandpass)
コード例 #21
0
    def setup_sensors(self):
        """
        Setup monitoring sensors
        """
        EDDPipeline.setup_sensors(self)

        self._fw_connection_status = Sensor.discrete(
            "fits-writer-connection-status",
            description="Status of the fits writer conenction",
            params=["Unmanaged", "Connected", "Unconnected"],
            default="Unmanaged",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._fw_connection_status)

        self._fw_packages_sent = Sensor.integer(
            "fw-sent-packages",
            description=
            "Number of packages sent to fits writer in this measurement",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._fw_packages_sent)

        self._fw_packages_dropped = Sensor.integer(
            "fw-dropped-packages",
            description=
            "Number of packages dropped by fits writer in this measurement",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._fw_packages_dropped)

        self._incomplete_heaps = Sensor.integer(
            "incomplete-heaps",
            description="Incomplete heaps received.",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._incomplete_heaps)

        self._complete_heaps = Sensor.integer(
            "complete-heaps",
            description="Complete heaps received.",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._complete_heaps)

        self._invalid_packages = Sensor.integer(
            "invalid-packages",
            description="Number of invalid packages dropped.",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._invalid_packages)

        self._bandpass = Sensor.string(
            "bandpass",
            description="band-pass data (base64 encoded)",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._bandpass)
コード例 #22
0
    def setup_sensors(self):
        """
        @brief Setup monitoring sensors
        """
        self._device_status = Sensor.discrete(
            "device-status",
            "Health status of PafWorkerServer",
            params=self.DEVICE_STATUSES,
            default="ok",
            initial_status=Sensor.NOMINAL)
        self.add_sensor(self._device_status)

        self._pipeline_sensor_name = Sensor.string("pipeline-name",
                                                   "the name of the pipeline",
                                                   "")
        self.add_sensor(self._pipeline_sensor_name)

        self._pipeline_sensor_status = Sensor.discrete(
            "pipeline-status",
            description="Status of the pipeline",
            params=self.PIPELINE_STATES,
            default="idle",
            initial_status=Sensor.NOMINAL)
        self.add_sensor(self._pipeline_sensor_status)

        self._ip_address = Sensor.string(
            "ip",
            description="the ip address of the node controller",
            default=os.environ['PAF_NODE_IP'],
            initial_status=Sensor.NOMINAL)
        self.add_sensor(self._ip_address)

        self._mac_address = Sensor.string(
            "mac",
            description="the mac address of the node controller",
            default=os.environ['PAF_NODE_MAC'],
            initial_status=Sensor.NOMINAL)
        self.add_sensor(self._mac_address)
コード例 #23
0
    def setup_sensors(self):
        """
        Setup katcp monitoring sensors.
        """
        EDDPipeline.setup_sensors(self)

        self._configuration_graph = Sensor.string(
            "configuration_graph",
            description="Graph of configuration",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._configuration_graph)
        self._provision_sensor = Sensor.string(
            "provision",
            description="Current provision configuration",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._provision_sensor)

        self._productStatusSummarySensor = Sensor.string(
            "product-status-summary",
            description="Status of all controlled products",
            default="{}",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._productStatusSummarySensor)
コード例 #24
0
    def setup_sensors(self):
        super(PafMasterController, self).setup_sensors()
        self._paf_config_sensor = Sensor.string(
            "current-config",
            description="The currently set configuration for the PAF backend",
            default="",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._paf_config_sensor)

        self._status_server_sensor = Sensor.address(
            "status-server-address",
            description="The address of the status server",
            default="",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._status_server_sensor)
コード例 #25
0
    def setup_sensors(self):
        """
        @brief    Setup the default KATCP sensors.

        @note     As this call is made only upon an EDD product configure call a mass inform
                  is required to let connected clients know that the proxy interface has
                  changed.
        """
        super(EddRoach2ProductController, self).setup_sensors()
        self._firmware_server_sensor = Sensor.string(
            "firmware-server",
            description=
            "The address of the firmware server started by this product",
            default="",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._firmware_server_sensor)
        self._parent.mass_inform(Message.inform('interface-changed'))
コード例 #26
0
    def setup_sensors(self):
        """Setup some server sensors."""
        self._add_result = Sensor.float("add.result",
            "Last ?add result.", "", [-10000, 10000])
        self._add_result.set_value(0, Sensor.UNREACHABLE)

        self._time_result = Sensor.timestamp("time.result",
            "Last ?time result.", "")
        self._time_result.set_value(0, Sensor.INACTIVE)

        self._eval_result = Sensor.string("eval.result",
            "Last ?eval result.", "")
        self._eval_result.set_value('', Sensor.UNKNOWN)

        self._fruit_result = Sensor.discrete("fruit.result",
            "Last ?pick-fruit result.", "", self.FRUIT)
        self._fruit_result.set_value('apple', Sensor.ERROR)

        self.add_sensor(self._add_result)
        self.add_sensor(self._time_result)
        self.add_sensor(self._eval_result)
        self.add_sensor(self._fruit_result)
コード例 #27
0
ファイル: edd_worker_server.py プロジェクト: ewanbarr/mpikat
    def setup_sensors(self):
        """
        @brief Setup monitoring sensors
        """
        self._device_status = Sensor.discrete(
            "device-status",
            "Health status of PafWorkerServer",
            params=self.DEVICE_STATUSES,
            default="ok",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._device_status)

        self._pipeline_sensor_name = Sensor.string("pipeline-name",
                                                   "the name of the pipeline",
                                                   "")
        self.add_sensor(self._pipeline_sensor_name)

        self._pipeline_sensor_status = Sensor.discrete(
            "pipeline-status",
            description="Status of the pipeline",
            params=self.PIPELINE_STATES,
            default="idle",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._pipeline_sensor_status)
コード例 #28
0
    def setup_sensors(self):
        """Set up basic monitoring sensors.
        """
        for name, params in self._parser.items():
            v = params.copy()
            v.pop('updater')
            if 'range' in v:
                v.pop('range')

            self.__eddDataStore.addTelescopeDataItem(name, v)
            if params["type"] == "float":
                sensor = Sensor.float(name,
                                      description=params["description"],
                                      unit=params.get("units", None),
                                      default=params.get("default", 0.0),
                                      initial_status=Sensor.UNKNOWN)
            elif params["type"] == "string":
                sensor = Sensor.string(name,
                                       description=params["description"],
                                       default=params.get("default", ""),
                                       initial_status=Sensor.UNKNOWN)
            elif params["type"] == "int":
                sensor = Sensor.integer(name,
                                        description=params["description"],
                                        default=params.get("default", 0),
                                        unit=params.get("units", None),
                                        initial_status=Sensor.UNKNOWN)
            elif params["type"] == "bool":
                sensor = Sensor.boolean(name,
                                        description=params["description"],
                                        default=params.get("default", False),
                                        initial_status=Sensor.UNKNOWN)
            else:
                raise Exception("Unknown sensor type '{0}' requested".format(
                    params["type"]))
            self.add_sensor(sensor)
コード例 #29
0
    def setup_sensors(self):
        """
        @brief Setup monitoring sensors
        """
        EDDPipeline.setup_sensors(self)

        self._edd_config_sensor = Sensor.string(
            "current-config",
            description="The current configuration for the EDD backend",
            default=json.dumps(DEFAULT_CONFIG, indent=4),
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._edd_config_sensor)

        self._output_rate_status = Sensor.float(
            "output-rate",
            description="Output data rate [Gbyte/s]",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._output_rate_status)

        self._polarization_sensors = {}
        for p in POLARIZATIONS:
            self._polarization_sensors[p] = {}
            self._polarization_sensors[p]["mkrecv_sensors"] = MkrecvSensors(p)
            for s in self._polarization_sensors[p][
                    "mkrecv_sensors"].sensors.itervalues():
                self.add_sensor(s)
            self._polarization_sensors[p][
                "input-buffer-fill-level"] = Sensor.float(
                    "input-buffer-fill-level-{}".format(p),
                    description=
                    "Fill level of the input buffer for polarization{}".format(
                        p),
                    params=[0, 1])
            self.add_sensor(
                self._polarization_sensors[p]["input-buffer-fill-level"])
            self._polarization_sensors[p][
                "input-buffer-total-write"] = Sensor.float(
                    "input-buffer-total-write-{}".format(p),
                    description=
                    "Total write into input buffer for polarization {}".format(
                        p),
                    params=[0, 1])

            self.add_sensor(
                self._polarization_sensors[p]["input-buffer-total-write"])
            self._polarization_sensors[p][
                "output-buffer-fill-level"] = Sensor.float(
                    "output-buffer-fill-level-{}".format(p),
                    description=
                    "Fill level of the output buffer for polarization {}".
                    format(p))
            self._polarization_sensors[p][
                "output-buffer-total-read"] = Sensor.float(
                    "output-buffer-total-read-{}".format(p),
                    description=
                    "Total read from output buffer for polarization {}".format(
                        p))
            self.add_sensor(
                self._polarization_sensors[p]["output-buffer-total-read"])
            self.add_sensor(
                self._polarization_sensors[p]["output-buffer-fill-level"])
コード例 #30
0
    def setup_sensors(self):
        """
        @brief    Setup the default KATCP sensors.

        @note     As this call is made only upon an FBFUSE configure call a mass inform
                  is required to let connected clients know that the proxy interface has
                  changed.
        """
        self._state_sensor = LoggingSensor.discrete(
            "state",
            description = "Denotes the state of this FBF instance",
            params = self.STATES,
            default = self.IDLE,
            initial_status = Sensor.NOMINAL)
        self._state_sensor.set_logger(self.log)
        self.add_sensor(self._state_sensor)

        self._ca_address_sensor = Sensor.string(
            "configuration-authority",
            description = "The address of the server that will be deferred to for configurations",
            default = "",
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._ca_address_sensor)

        self._available_antennas_sensor = Sensor.string(
            "available-antennas",
            description = "The antennas that are currently available for beamforming",
            default = json.dumps({antenna.name:antenna.format_katcp() for antenna in self._katpoint_antennas}),
            initial_status = Sensor.NOMINAL)
        self.add_sensor(self._available_antennas_sensor)

        self._phase_reference_sensor = Sensor.string(
            "phase-reference",
            description="A KATPOINT target string denoting the F-engine phasing centre",
            default="unset,radec,0,0",
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._phase_reference_sensor)

        reference_antenna = Antenna("reference,{ref.lat},{ref.lon},{ref.elev}".format(
            ref=self._katpoint_antennas[0].ref_observer))
        self._reference_antenna_sensor = Sensor.string(
            "reference-antenna",
            description="A KATPOINT antenna string denoting the reference antenna",
            default=reference_antenna.format_katcp(),
            initial_status=Sensor.NOMINAL)
        self.add_sensor(self._reference_antenna_sensor)

        self._bandwidth_sensor = Sensor.float(
            "bandwidth",
            description = "The bandwidth this product is configured to process",
            default = self._default_sb_config['bandwidth'],
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._bandwidth_sensor)

        self._nchans_sensor = Sensor.integer(
            "nchannels",
            description = "The number of channels to be processesed",
            default = self._n_channels,
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._nchans_sensor)

        self._cfreq_sensor = Sensor.float(
            "centre-frequency",
            description = "The centre frequency of the band this product configured to process",
            default = self._default_sb_config['centre-frequency'],
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._cfreq_sensor)

        self._cbc_nbeams_sensor = Sensor.integer(
            "coherent-beam-count",
            description = "The number of coherent beams that this FBF instance can currently produce",
            default = self._default_sb_config['coherent-beams-nbeams'],
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._cbc_nbeams_sensor)

        self._cbc_nbeams_per_group = Sensor.integer(
            "coherent-beam-count-per-group",
            description = "The number of coherent beams packed into a multicast group",
            default = 1,
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._cbc_nbeams_per_group)

        self._cbc_ngroups = Sensor.integer(
            "coherent-beam-ngroups",
            description = "The number of multicast groups used for coherent beam transmission",
            default = 1,
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._cbc_ngroups)

        self._cbc_nbeams_per_server_set = Sensor.integer(
            "coherent-beam-nbeams-per-server-set",
            description = "The number of beams produced by each server set",
            default = 1,
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._cbc_nbeams_per_server_set)

        self._cbc_tscrunch_sensor = Sensor.integer(
            "coherent-beam-tscrunch",
            description = "The number time samples that will be integrated when producing coherent beams",
            default = self._default_sb_config['coherent-beams-tscrunch'],
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._cbc_tscrunch_sensor)

        self._cbc_fscrunch_sensor = Sensor.integer(
            "coherent-beam-fscrunch",
            description = "The number frequency channels that will be integrated when producing coherent beams",
            default = self._default_sb_config['coherent-beams-fscrunch'],
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._cbc_fscrunch_sensor)

        self._cbc_antennas_sensor = Sensor.string(
            "coherent-beam-antennas",
            description = "The antennas that will be used when producing coherent beams",
            default = self._default_sb_config['coherent-beams-antennas'],
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._cbc_antennas_sensor)

        self._cbc_mcast_groups_sensor = Sensor.string(
            "coherent-beam-multicast-groups",
            description = "Multicast groups used by this instance for sending coherent beam data",
            default = "",
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._cbc_mcast_groups_sensor)

        self._cbc_mcast_groups_mapping_sensor = Sensor.string(
            "coherent-beam-multicast-group-mapping",
            description = "Mapping of mutlicast group address to the coherent beams in that group",
            default= "",
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._cbc_mcast_groups_mapping_sensor)

        self._ibc_nbeams_sensor = Sensor.integer(
            "incoherent-beam-count",
            description = "The number of incoherent beams that this FBF instance can currently produce",
            default = 1,
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._ibc_nbeams_sensor)

        self._ibc_tscrunch_sensor = Sensor.integer(
            "incoherent-beam-tscrunch",
            description = "The number time samples that will be integrated when producing incoherent beams",
            default = self._default_sb_config['incoherent-beam-tscrunch'],
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._ibc_tscrunch_sensor)

        self._ibc_fscrunch_sensor = Sensor.integer(
            "incoherent-beam-fscrunch",
            description = "The number frequency channels that will be integrated when producing incoherent beams",
            default = self._default_sb_config['incoherent-beam-fscrunch'],
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._ibc_fscrunch_sensor)

        self._ibc_antennas_sensor = Sensor.string(
            "incoherent-beam-antennas",
            description = "The antennas that will be used when producing incoherent beams",
            default = self._default_sb_config['incoherent-beam-antennas'],
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._ibc_antennas_sensor)

        self._ibc_mcast_group_sensor = Sensor.string(
            "incoherent-beam-multicast-group",
            description = "Multicast group used by this instance for sending incoherent beam data",
            default = "",
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._ibc_mcast_group_sensor)

        self._servers_sensor = Sensor.string(
            "servers",
            description = "The worker server instances currently allocated to this product",
            default = ",".join(["{s.hostname}:{s.port}".format(s=server) for server in self._servers]),
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._servers_sensor)

        self._nserver_sets_sensor = Sensor.integer(
            "nserver-sets",
            description = "The number of server sets (independent subscriptions to the F-engines)",
            default = 1,
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._nserver_sets_sensor)

        self._nservers_per_set_sensor = Sensor.integer(
            "nservers-per-set",
            description = "The number of servers per server set",
            default = 1,
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._nservers_per_set_sensor)

        self._delay_config_server_sensor = Sensor.string(
            "delay-config-server",
            description = "The address of the delay configuration server for this product",
            default = "",
            initial_status = Sensor.UNKNOWN)
        self.add_sensor(self._delay_config_server_sensor)
コード例 #31
0
    def setup_sensors(self):
        """
        @brief Setup monitoring sensors
        """
        EDDPipeline.setup_sensors(self)
        self._tscrunch = Sensor.string("tscrunch_PNG",
                                       description="tscrunch png",
                                       default=BLANK_IMAGE,
                                       initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._tscrunch)

        self._fscrunch = Sensor.string("fscrunch_PNG",
                                       description="fscrunch png",
                                       default=BLANK_IMAGE,
                                       initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._fscrunch)

        self._profile = Sensor.string("profile_PNG",
                                      description="pulse profile png",
                                      default=BLANK_IMAGE,
                                      initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._profile)

        self._central_freq = Sensor.string("_central_freq",
                                           description="_central_freq",
                                           default="N/A",
                                           initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._central_freq)

        self._source_name_sensor = Sensor.string("target_name",
                                                 description="target name",
                                                 default="N/A",
                                                 initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._source_name_sensor)

        self._nchannels = Sensor.string("_nchannels",
                                        description="_nchannels",
                                        default="N/A",
                                        initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._nchannels)

        self._nbins = Sensor.string("_nbins",
                                    description="_nbins",
                                    default="N/A",
                                    initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._nbins)

        self._time_processed = Sensor.string("_time_processed",
                                             description="_time_processed",
                                             default=0,
                                             initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._time_processed)

        self._dm_sensor = Sensor.string("_source_dm",
                                        description="_source_dm",
                                        default=0,
                                        initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._dm_sensor)

        self._par_dict_sensor = Sensor.string("_par_dict_sensor",
                                              description="_par_dict_sensor",
                                              default="N/A",
                                              initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._par_dict_sensor)
        self._directory_size_sensor = Sensor.string(
            "_directory_size_sensor",
            description="_directory_size_sensor",
            default=0,
            initial_status=Sensor.UNKNOWN)
        self.add_sensor(self._directory_size_sensor)
        self._input_buffer_fill_level = Sensor.float(
            "input-buffer-fill-level",
            description="Fill level of the input buffer",
            params=[0, 1])
        self.add_sensor(self._input_buffer_fill_level)

        self._input_buffer_total_write = Sensor.float(
            "input-buffer-total-write",
            description="Total write into input buffer ",
            params=[0, 1])
        self.add_sensor(self._input_buffer_total_write)

        self._output_buffer_fill_level = Sensor.float(
            "output-buffer-fill-level",
            description="Fill level of the output buffer")
        self.add_sensor(self._output_buffer_fill_level)
        self._output_buffer_total_read = Sensor.float(
            "output-buffer-total-read",
            description="Total read from output buffer")
        self.add_sensor(self._output_buffer_total_read)

        self._polarization_sensors = {}
コード例 #32
0
    def prepare(self, sb_id):
        """
        @brief      Prepare the beamformer for streaming

        @detail     This method evaluates the current configuration creates a new DelayEngine
                    and passes a prepare call to all allocated servers.
        """
        if not self.idle:
            raise FbfProductStateError([self.IDLE], self.state)
        self.log.info("Preparing FBFUSE product")
        self._state_sensor.set_value(self.PREPARING)
        self.log.debug("Product moved to 'preparing' state")
        # Here we need to parse the streams and assign beams to streams:
        #mcast_addrs, mcast_port = parse_stream(self._streams['cbf.antenna_channelised_voltage']['i0.antenna-channelised-voltage'])

        if not self._ca_client:
            self.log.warning("No configuration authority found, using default configuration parameters")
            cm = self.set_sb_configuration(self._default_sb_config)
        else:
            #TODO: get the schedule block ID into this call from somewhere (configure?)
            try:
                config = yield self.get_ca_sb_configuration(sb_id)
                cm = self.set_sb_configuration(config)
            except Exception as error:
                self.log.error("Configuring from CA failed with error: {}".format(str(error)))
                self.log.warning("Reverting to default configuration")
                cm = self.set_sb_configuration(self._default_sb_config)

        cbc_antennas_names = parse_csv_antennas(self._cbc_antennas_sensor.value())
        cbc_antennas = [self._antenna_map[name] for name in cbc_antennas_names]
        self._beam_manager = BeamManager(self._cbc_nbeams_sensor.value(), cbc_antennas)
        self._delay_config_server = DelayConfigurationServer("127.0.0.1", 0, self._beam_manager)
        self._delay_config_server.start()
        self.log.info("Started delay engine at: {}".format(self._delay_config_server.bind_address))
        de_ip, de_port = self._delay_config_server.bind_address
        self._delay_config_server_sensor.set_value((de_ip, de_port))

        # Need to tear down the beam sensors here
        # Here calculate the beam to multicast map
        self._beam_sensors = []
        mcast_to_beam_map = {}
        groups = [ip for ip in self._cbc_mcast_groups]
        idxs = [beam.idx for beam in self._beam_manager.get_beams()]
        for group in groups:
            self.log.debug("Allocating beams to {}".format(str(group)))
            key = str(group)
            for _ in range(self._cbc_nbeams_per_group.value()):
                if not key in mcast_to_beam_map:
                    mcast_to_beam_map[str(group)] = []
                value = idxs.pop(0)
                self.log.debug("--> Allocated {} to {}".format(value, str(group)))
                mcast_to_beam_map[str(group)].append(value)
        self._cbc_mcast_groups_mapping_sensor.set_value(json.dumps(mcast_to_beam_map))
        for beam in self._beam_manager.get_beams():
            sensor = Sensor.string(
                "coherent-beam-{}".format(beam.idx),
                description="R.A. (deg), declination (deg) and source name for coherent beam with ID {}".format(beam.idx),
                default=self._beam_to_sensor_string(beam),
                initial_status=Sensor.UNKNOWN)
            beam.register_observer(lambda beam, sensor=sensor:
                sensor.set_value(self._beam_to_sensor_string(beam)))
            self._beam_sensors.append(sensor)
            self.add_sensor(sensor)
        self._parent.mass_inform(Message.inform('interface-changed'))

        #Here we actually start to prepare the remote workers
        ip_splits = self._streams.split(N_FENG_STREAMS_PER_WORKER)

        # This is assuming lower sideband and bandwidth is always +ve
        fbottom = self._feng_config['centre-frequency'] - self._feng_config['bandwidth']/2.

        coherent_beam_config = {
        'tscrunch':self._cbc_tscrunch_sensor.value(),
        'fscrunch':self._cbc_fscrunch_sensor.value(),
        'antennas':self._cbc_antennas_sensor.value()
        }

        incoherent_beam_config = {
        'tscrunch':self._ibc_tscrunch_sensor.value(),
        'fscrunch':self._ibc_fscrunch_sensor.value(),
        'antennas':self._ibc_antennas_sensor.value()
        }

        prepare_futures = []
        for ii, (server, ip_range) in enumerate(zip(self._servers, ip_splits)):
            chan0_idx = cm.nchans_per_worker * ii
            chan0_freq =  fbottom + chan0_idx * cm.channel_bandwidth
            future = server.prepare(ip_range.format_katcp(), cm.nchans_per_group,
                        chan0_idx, chan0_freq, cm.channel_bandwidth, mcast_to_beam_map,
                        self._feng_config['feng-antenna-map'], coherent_beam_config,
                        incoherent_beam_config, de_ip, de_port)
            prepare_futures.append(future)

        failure_count = 0
        for future in prepare_futures:
            try:
                yield future
            except Exception as error:
                log.error("Failed to configure server with error: {}".format(str(error)))
                failure_count += 1

        if failure_count > 0:
            self._state_sensor.set_value(self.ERROR)
            self.log.info("Failed to prepare FBFUSE product")
        else:
            self._state_sensor.set_value(self.READY)
            self.log.info("Successfully prepared FBFUSE product")