def update_monitors(self):
     with self._bs.monitor_lock:
         print "UPDATING CONFIG LIST MONITORS"
         # Set the available configs
         self._bs.setParam(BlockserverPVNames.CONFIGS, compress_and_hex(convert_to_json(self.get_configs())))
         # Set the available comps
         self._bs.setParam(BlockserverPVNames.COMPS, compress_and_hex(convert_to_json(self.get_components())))
         # Update them
         self._bs.updatePVs()
 def handle_pv_read(self, pv):
     if pv == RUNCONTROL_GET_PV:
         js = convert_to_json(self.get_current_settings())
         value = compress_and_hex(js)
         return value
     elif pv == RUNCONTROL_OUT_PV:
         js = convert_to_json(self.get_out_of_range_pvs())
         value = compress_and_hex(js)
         return value
     return ""
 def update_get_details_monitors(self):
     """Updates the monitor for the active configuration, so the clients can see any changes.
     """
     with self.monitor_lock:
         js = convert_to_json(self._active_configserver.get_config_details())
         self.setParam(BlockserverPVNames.GET_CURR_CONFIG_DETAILS, compress_and_hex(js))
         self.updatePVs()
 def update_monitors(self):
     with self._bs.monitor_lock:
         print "UPDATING SYNOPTIC MONITORS"
         self._bs.setParam(SYNOPTIC_PRE + SYNOPTIC_GET_DEFAULT, compress_and_hex(self.get_default_synoptic_xml()))
         names = convert_to_json(self.get_synoptic_list())
         self._bs.setParam(SYNOPTIC_PRE + SYNOPTIC_NAMES, compress_and_hex(names))
         self._bs.updatePVs()
    def update_server_status(self, status=""):
        """Updates the monitor for the server status, so the clients can see any changes.

        Args:
            status (string): The status to set
        """
        if self._active_configserver is not None:
            d = dict()
            d['status'] = status
            with self.monitor_lock:
                self.setParam(BlockserverPVNames.SERVER_STATUS, compress_and_hex(convert_to_json(d)))
                self.updatePVs()
 def update_blocks_monitors(self):
     """Updates the monitors for the blocks and groups, so the clients can see any changes.
     """
     with self.monitor_lock:
         # Blocks
         bn = convert_to_json(self._active_configserver.get_blocknames())
         self.setParam(BlockserverPVNames.BLOCKNAMES, compress_and_hex(bn))
         # Groups
         # Update the PV, so that groupings are updated for any CA monitors
         grps = ConfigurationJsonConverter.groups_to_json(self._active_configserver.get_group_details())
         self.setParam(BlockserverPVNames.GROUPS, compress_and_hex(grps))
         # Update them
         self.updatePVs()
    def read(self, reason):
        """Overrides the read method of the pcaspy Driver class.

        Args:
            reason (string): The PV name.

        Returns:
            The PV value.
        """
        if reason == 'CS:BLOCKSERVER:BLOCKVALUES':
            ans = convert_to_json(self._get_organised_values())
            value = compress_and_hex(ans)
        else:
            value = self.getParam(reason)
        return value
    def read(self, reason):
        """A method called by SimpleServer when a PV is read from the BlockServer over Channel Access.

        Args:
            reason (string): The PV that is being requested (without the PV prefix)

        Returns:
            string : A compressed and hexed JSON formatted string that gives the desired information based on reason.
            If an Exception is thrown in the reading of the information this is returned in compressed and hexed JSON.
        """
        try:
            if reason == BlockserverPVNames.GROUPS:
                grps = ConfigurationJsonConverter.groups_to_json(self._active_configserver.get_group_details())
                value = compress_and_hex(grps)
            elif reason == BlockserverPVNames.CONFIGS:
                value = compress_and_hex(convert_to_json(self._config_list.get_configs()))
            elif reason == BlockserverPVNames.COMPS:
                value = compress_and_hex(convert_to_json(self._config_list.get_components()))
            elif reason == BlockserverPVNames.BLANK_CONFIG:
                js = convert_to_json(self.get_blank_config())
                value = compress_and_hex(js)
            elif reason == BlockserverPVNames.BUMPSTRIP_AVAILABLE:
                value = compress_and_hex(self.bumpstrip)
            elif reason == BlockserverPVNames.BANNER_DESCRIPTION:
                value = compress_and_hex(self.banner.get_description())
            else:
                # Check to see if it is a on-the-fly PV
                for handler in self.on_the_fly_handlers:
                    if handler.read_pv_exists(reason):
                        return handler.handle_pv_read(reason)

                value = self.getParam(reason)
        except Exception as err:
            value = compress_and_hex(convert_to_json("Error: " + str(err)))
            print_and_log(str(err), "MAJOR")
        return value
    def _initialise_config(self, init_gateway=True, full_init=False):
        """Responsible for initialising the configuration.
        Sets all the monitors, initialises the gateway, etc.

        Args:
            init_gateway (bool, optional): whether to initialise the gateway
            full_init (bool, optional): whether this requires a full initialisation, e.g. on loading a new
                configuration
        """
        # First stop all IOCS, then start the ones for the config
        # TODO: Should we stop all configs?
        iocs_to_start, iocs_to_restart = self._active_configserver.iocs_changed()

        if len(iocs_to_start) > 0 or len(iocs_to_restart) > 0:
            self._stop_iocs_and_start_config_iocs(iocs_to_start, iocs_to_restart)
        # Set up the gateway
        if init_gateway:
            self._gateway.set_new_aliases(self._active_configserver.get_block_details())

        self._config_list.active_config_name = self._active_configserver.get_config_name()
        self._config_list.active_components = self._active_configserver.get_component_names()
        self._config_list.update_monitors()

        self.update_blocks_monitors()

        self.update_get_details_monitors()
        self._active_configserver.update_archiver()

        for h in self.on_the_fly_handlers:
            h.initialise(full_init)

        # Update Web Server text
        self.server.set_config(convert_to_json(self._active_configserver.get_config_details()))

        # Restart the Blocks cache
        if self._block_cache is not None:
            print_and_log("Restarting block cache...")
            self._block_cache.restart()
    def write(self, reason, value):
        """A method called by SimpleServer when a PV is written to the DatabaseServer over Channel Access.

        Args:
            reason (string): The PV that is being requested (without the PV prefix)
            value (string): The data being written to the 'reason' PV

        Returns:
            bool : True
        """
        status = True
        try:
            if reason == 'ED:RBNUMBER:SP':
                #print_and_log("Updating to use experiment ID: " + value, "INFO", "DBSVR")
                self._ed.updateExperimentID(value)
            elif reason == 'ED:USERNAME:SP':
                self._ed.updateUsername(dehex_and_decompress(value))
        except Exception as err:
            value = compress_and_hex(convert_to_json("Error: " + str(err)))
            print_and_log(str(err), "MAJOR")
        # store the values
        if status:
            self.setParam(reason, value)
        return status
    def write(self, reason, value):
        """A method called by SimpleServer when a PV is written to the BlockServer over Channel Access. The write
            commands are queued as Channel Access is single-threaded.

            Note that the filewatcher is disabled as part of the write queue so any operations that intend to modify
            files should use the write queue.

        Args:
            reason (string): The PV that is being requested (without the PV prefix)
            value (string): The data being written to the 'reason' PV

        Returns:
            string : "OK" in compressed and hexed JSON if function succeeds. Otherwise returns the Exception in
            compressed and hexed JSON.
        """
        status = True
        try:
            data = dehex_and_decompress(value).strip('"')
            if reason == BlockserverPVNames.LOAD_CONFIG:
                with self.write_lock:
                    self.write_queue.append((self.load_config, (data,), "LOADING_CONFIG"))
            elif reason == BlockserverPVNames.SAVE_CONFIG:
                with self.write_lock:
                    self.write_queue.append((self.save_active_config, (data,), "SAVING_CONFIG"))
            elif reason == BlockserverPVNames.RELOAD_CURRENT_CONFIG:
                with self.write_lock:
                    self.write_queue.append((self.reload_current_config, (), "RELOAD_CURRENT_CONFIG"))
            elif reason == BlockserverPVNames.START_IOCS:
                with self.write_lock:
                    self.write_queue.append((self.start_iocs, (convert_from_json(data),), "START_IOCS"))
            elif reason == BlockserverPVNames.STOP_IOCS:
                with self.write_lock:
                    self.write_queue.append((self._ioc_control.stop_iocs, (convert_from_json(data),), "STOP_IOCS"))
            elif reason == BlockserverPVNames.RESTART_IOCS:
                with self.write_lock:
                    self.write_queue.append((self._ioc_control.restart_iocs, (convert_from_json(data), True),
                                             "RESTART_IOCS"))
            elif reason == BlockserverPVNames.SET_CURR_CONFIG_DETAILS:
                with self.write_lock:
                    self.write_queue.append((self._set_curr_config, (convert_from_json(data),), "SETTING_CONFIG"))
            elif reason == BlockserverPVNames.SAVE_NEW_CONFIG:
                with self.write_lock:
                    self.write_queue.append((self.save_inactive_config, (data,), "SAVING_NEW_CONFIG"))
            elif reason == BlockserverPVNames.SAVE_NEW_COMPONENT:
                with self.write_lock:
                    self.write_queue.append((self.save_inactive_config, (data, True), "SAVING_NEW_COMP"))
            elif reason == BlockserverPVNames.DELETE_CONFIGS:
                with self.write_lock:
                    self.write_queue.append((self._config_list.delete, (convert_from_json(data),),
                                             "DELETE_CONFIGS"))
            elif reason == BlockserverPVNames.DELETE_COMPONENTS:
                with self.write_lock:
                    self.write_queue.append((self._config_list.delete, (convert_from_json(data), True),
                                             "DELETE_COMPONENTS"))
            elif reason == BlockserverPVNames.BUMPSTRIP_AVAILABLE_SP:
                self.bumpstrip = data
                with self.write_lock:
                    self.write_queue.append((self.update_bumpstrip_availability, None, "UPDATE_BUMPSTRIP"))
            else:
                status = False
                # Check to see if it is a on-the-fly PV
                for h in self.on_the_fly_handlers:
                    if h.write_pv_exists(reason):
                        with self.write_lock:
                            self.write_queue.append((h.handle_pv_write, (reason, data), "SETTING_CONFIG"))
                        status = True
                        break

        except Exception as err:
            value = compress_and_hex(convert_to_json("Error: " + str(err)))
            print_and_log(str(err), "MAJOR")
        else:
            if status:
                value = compress_and_hex(convert_to_json("OK"))

        # store the values
        if status:
            self.setParam(reason, value)
        return status