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_monitors(self):
     """ Writes new device screens data to PVs """
     with self._bs.monitor_lock:
         print "UPDATING DEVICES MONITORS"
         self._bs.setParam(GET_SCHEMA, compress_and_hex(self.get_devices_schema()))
         self._bs.setParam(GET_SCREENS, compress_and_hex(self._data))
         self._bs.updatePVs()
    def _add_all_parameter_pvs(self):
        """
        Add PVs for each beamline parameter in the reflectometry configuration to the server's PV database.
        """
        param_info = {}
        for group in BeamlineParameterGroup:
            param_info[group] = []
        align_info = []
        for parameter in self._beamline.parameters.values():
            try:
                param_info_record = self._add_parameter_pvs(parameter)
                if param_info_record is not None:
                    for group in parameter.group_names:
                        param_info[group].append(param_info_record)
                    if parameter.define_current_value_as is not None:
                        align_info_record = {
                            "name": param_info_record["name"],
                            "prepended_alias": param_info_record["prepended_alias"],
                            "type": "align",
                            "description": ""
                        }
                        align_info.append(align_info_record)

            except Exception as err:
                STATUS_MANAGER.update_error_log("Error adding PV for parameter {}: {}".format(parameter.name, err), err)
                STATUS_MANAGER.update_active_problems(
                    ProblemInfo("Error adding parameter PV", parameter.name, Severity.MAJOR_ALARM))

        for param_group in BeamlineParameterGroup:
            self._add_pv_with_fields(PARAM_INFO_LOOKUP[param_group], None, STANDARD_2048_CHAR_WF_FIELDS,
                                     BeamlineParameterGroup.description(param_group), None,
                                     value=compress_and_hex(json.dumps(param_info[param_group])))

        self._add_pv_with_fields(ALIGN_INFO, None, STANDARD_2048_CHAR_WF_FIELDS, "All alignment pvs information",
                                 None, value=compress_and_hex(json.dumps(align_info)))
 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 _create_standard_pvs(self):
        self._bs.add_string_pv_to_db(SYNOPTIC_PRE + SYNOPTIC_NAMES, 16000)
        self._bs.add_string_pv_to_db(SYNOPTIC_PRE + SYNOPTIC_GET_DEFAULT, 16000)
        self._bs.add_string_pv_to_db(SYNOPTIC_PRE + SYNOPTIC_BLANK + SYNOPTIC_GET, 16000)
        self._bs.add_string_pv_to_db(SYNOPTIC_PRE + SYNOPTIC_SET_DETAILS, 16000)
        self._bs.add_string_pv_to_db(SYNOPTIC_PRE + SYNOPTIC_DELETE, 16000)
        self._bs.add_string_pv_to_db(SYNOPTIC_PRE + SYNOPTIC_SCHEMA, 16000)

        # Set values for PVs that don't change
        self.update_pv_value(SYNOPTIC_PRE + SYNOPTIC_BLANK + SYNOPTIC_GET,
                             compress_and_hex(self.get_blank_synoptic()))
        self.update_pv_value(SYNOPTIC_PRE + SYNOPTIC_SCHEMA, compress_and_hex(self.get_synoptic_schema()))
 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 test_when_devices_screens_file_does_not_exist_then_current_uses_blank_devices_data(self):
        # Arrange
        self.dm.initialise()

        # Assert
        self.assertTrue(len(self.file_io.files) == 0)
        self.assertEquals(self.bs.pvs[GET_SCREENS], compress_and_hex(self.dm.get_blank_devices()))
 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_bumpstrip_availability(self):
     """Updates the monitor for the configurations, so the clients can see any changes.
         """
     with self.monitor_lock:
         # set the available configs
         self.setParam(BlockserverPVNames.BUMPSTRIP_AVAILABLE, compress_and_hex(self.bumpstrip))
         # Update them
         self.updatePVs()
 def _update_component_dependencies_pv(self, name):
     # Updates PV with list of configs that depend on a component
     configs = []
     if name in self._comp_dependencies.keys():
         configs = self._comp_dependencies[name]
     if name in self._component_metas.keys():
         # Check just in case component failed to load
         pv_name = BlockserverPVNames.get_dependencies_pv(self._component_metas[name].pv)
         self._update_pv_value(pv_name, compress_and_hex(json.dumps(configs)))
    def encode4return(self, data):
        """Converts data to JSON, compresses it and converts it to hex.

        Args:
            data (string): The data to encode

        Returns:
            string : The encoded data
        """
        return compress_and_hex(json.dumps(data).encode('ascii', 'replace'))
    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 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 _create_pv(self, data):
        """Creates a single PV based on a name and data. Adds this PV to the dictionary returned on get_synoptic_list

        Args:
            data (string): Starting data for the pv, the pv name is derived from the name tag of this
        """
        name = self._get_synoptic_name_from_xml(data)
        if name not in self._synoptic_pvs:
            # Extra check, if a non-case sensitive match exist remove it
            for key in self._synoptic_pvs.keys():
                if name.lower() == key.lower():
                    self._synoptic_pvs.pop(key)
            pv = create_pv_name(name, self._synoptic_pvs.values(), "SYNOPTIC")
            self._synoptic_pvs[name] = pv

        # Create the PV
        self._bs.add_string_pv_to_db(SYNOPTIC_PRE + self._synoptic_pvs[name] + SYNOPTIC_GET, 16000)
        # Update the value
        self.update_pv_value(SYNOPTIC_PRE + self._synoptic_pvs[name] + SYNOPTIC_GET, compress_and_hex(data))
    def _add_constants_pvs(self):
        """
        Add pvs for the beamline constants
        """

        beamline_constant_info = []

        for beamline_constant in self._beamline.beamline_constants:
            try:
                const_alias = create_pv_name(beamline_constant.name, list(self.PVDB.keys()), CONST_PREFIX,
                                             limit=20, allow_colon=True)
                prepended_alias = "{}:{}".format(CONST_PREFIX, const_alias)

                if isinstance(beamline_constant.value, bool):
                    value = 1 if bool(beamline_constant.value) else 0
                    fields = PARAM_FIELDS_BINARY
                elif isinstance(beamline_constant.value, str):
                    value = beamline_constant.value
                    fields = STANDARD_2048_CHAR_WF_FIELDS
                else:
                    value = float(beamline_constant.value)
                    fields = STANDARD_FLOAT_PV_FIELDS

                self._add_pv_with_fields(prepended_alias, None, fields, beamline_constant.description, None,
                                         interest="MEDIUM", value=value)
                logger.info("Adding Constant {} with value {}".format(beamline_constant.name, beamline_constant.value))
                beamline_constant_info.append(
                    {"name": beamline_constant.name,
                     "prepended_alias": prepended_alias,
                     "type": "float_value",
                     "description": beamline_constant.description})
            except Exception as err:
                STATUS_MANAGER.update_error_log("Error adding constant {}: {}".format(beamline_constant.name, err), err)
                STATUS_MANAGER.update_active_problems(
                    ProblemInfo("Error adding PV for beamline constant", beamline_constant.name, Severity.MAJOR_ALARM))

        self._add_pv_with_fields(BEAMLINE_CONSTANT_INFO, None, STANDARD_2048_CHAR_WF_FIELDS, "All value parameters",
                                 None, value=compress_and_hex(json.dumps(beamline_constant_info)))
    def _add_all_driver_pvs(self):
        """
        Add all pvs for the drivers.
        """
        self.drivers_pv = {}
        driver_info = []
        for driver in self._beamline.drivers:
            if driver.has_engineering_correction:
                correction_alias = create_pv_name(driver.name, list(self.PVDB.keys()), "COR", limit=12,
                                                  allow_colon=True)
                prepended_alias = "{}:{}".format("COR", correction_alias)

                self._add_pv_with_fields(prepended_alias, None, STANDARD_FLOAT_PV_FIELDS, "Engineering Correction",
                                         None, archive=True)
                self._add_pv_with_fields("{}:DESC".format(prepended_alias), None, STANDARD_2048_CHAR_WF_FIELDS,
                                         "Engineering Correction Full Description", None)

                self.drivers_pv[driver] = prepended_alias

                driver_info.append({"name": driver.name, "prepended_alias": prepended_alias})

        self._add_pv_with_fields(DRIVER_INFO, None, STANDARD_2048_CHAR_WF_FIELDS, "All corrections information",
                                 None, value=compress_and_hex(json.dumps(driver_info)))
    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 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 _create_pv(self):
     self._bs.add_string_pv_to_db(BlockserverPVNames.CONF_DESC_RULES, 16000)
     self._bs.setParam(BlockserverPVNames.CONF_DESC_RULES, compress_and_hex(json.dumps(self.rules)))
     self._bs.updatePVs()
    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
def put_and_decode_ans(pv, value):
    caput(pv, compress_and_hex(value), wait=True)
    raw = caget(pv, True)
    js = dehex_and_decompress(raw)
    ans = json.loads(js)
    return ans
 def _update_component_pv(self, name, data):
     # Updates pvs with new data
     pv_name = BlockserverPVNames.get_component_details_pv(self._component_metas[name].pv)
     self._update_pv_value(pv_name, compress_and_hex(json.dumps(data)))
    def update(self, xml_data):
        """Updates the synoptic list when modifications are made via the filesystem.

        Args:
            xml_data (string): The xml data to update the PV with

        """
        name = self._get_synoptic_name_from_xml(xml_data)
        self._add_to_version_control(name, "%s modified on filesystem" % name)

        names = self._synoptic_pvs.keys()
        if name in names:
            self.update_pv_value(SYNOPTIC_PRE + self._synoptic_pvs[name] + SYNOPTIC_GET, compress_and_hex(xml_data))
        else:
            self._create_pv(xml_data)

        self.update_monitors()