diff --git a/p4pillon/config_reader.py b/p4pillon/config_reader.py index 36e1e9c..7e2d6ea 100644 --- a/p4pillon/config_reader.py +++ b/p4pillon/config_reader.py @@ -14,6 +14,13 @@ logger = logging.getLogger(__name__) +# A list of rule/handler specific configs in the YAML to be passed to a non-standard rule/handler. +# The list contains tuples of a tag name (the string used to identify the parameters for this rule) +# and the parameter type, e.g. dictionary, integer. +# The tag in the YAML must have the same name as the rule for it to be processed +# correctly by SharedNT. +rule_configs = [("calc", dict)] + def parse_config_file(filename: str, server: Server | None = None) -> dict[str, BasePVRecipe]: """ @@ -53,9 +60,9 @@ def parse_config(yaml_obj: dict[str, dict[str, Any]], server: Server | None = No pvrecipes[name] = recipe if server is not None: - if hasattr(recipe, "calc"): - recipe.calc["server"] = server - recipe.calc["pv_name"] = name + if "calc" in recipe.rule_configs: + recipe.rule_configs["calc"]["server"] = server + recipe.rule_configs["calc"]["pv_name"] = name server.add_pv(name, recipe) return pvrecipes @@ -116,12 +123,17 @@ def process_config(pvname: str, pvdetails: dict[str, Any]) -> BasePVRecipe: else: pvrecipe = PVScalarRecipe(PVTypes[pvdetails["type"]], pvdetails["description"], initial) - supported_configs = [("read_only", bool), ("calc", dict)] - for config, config_type in supported_configs: - # Process variables in the configuration that are attributes of the pvrecipe class + # Set read only + temp_config = pvdetails.get("read_only") + if temp_config is not None and isinstance(temp_config, bool): + pvrecipe.read_only = temp_config + + # Process configuration in the yaml specific to a supported rule + # and add this to pvrecipe.rule_configs + for config, config_type in rule_configs: temp_config = pvdetails.get(config) if temp_config is not None and isinstance(temp_config, config_type): - setattr(pvrecipe, config, temp_config) + pvrecipe.rule_configs[config] = temp_config if "control" in pvdetails: pvrecipe.set_control_limits(**get_field_config(pvdetails, "control")) diff --git a/p4pillon/pvrecipe.py b/p4pillon/pvrecipe.py index 7e4fde4..a844fbd 100644 --- a/p4pillon/pvrecipe.py +++ b/p4pillon/pvrecipe.py @@ -102,6 +102,9 @@ def __post_init__(self): self.construct_settings = {} self.config_settings = {} + # Rule specific configs to be passed to SharedNT + self.rule_configs = {} + self.construct_settings["valtype"] = self.pvtype.value self.construct_settings["extra"] = [("descriptor", "s")] self.config_settings["descriptor"] = self.description @@ -132,8 +135,8 @@ def build_pv( ) kwargs = {} - if hasattr(self, "calc"): - kwargs["calc"] = self.calc + for name, config in self.rule_configs.items(): + kwargs[name] = config logger.debug(debug_str) diff --git a/p4pillon/rules/calc_rule.py b/p4pillon/rules/calc_rule.py index 48d60c1..c43d667 100644 --- a/p4pillon/rules/calc_rule.py +++ b/p4pillon/rules/calc_rule.py @@ -33,26 +33,13 @@ def __init__(self, **kwargs): super().__init__() self._variables = [] self._calc_str: str = "" - if "calc" in kwargs: - self.set_calc(kwargs["calc"]) + self.set_calc(calc=kwargs) name = "calc" nttypes = [SupportedNTTypes.ALL] fields = [] add_automatically = False - # @property - # def name(self) -> str: - # return "calc" - - # @property - # def fields(self) -> None: - # """ - # A return value of None means this rule is not dependent on any fields in the PV and - # will thus always be applicable. - # """ - # return None - class MonitorCB: """ The MonitorCB class is used to provide call back methods for subscribing to Context.monitor @@ -71,7 +58,7 @@ def cb(self, v: Value): See https://epics-base.github.io/p4p/client.html#monitor for further information.""" self._server.put_pv_value(self._pv_name, {}) - def set_calc(self, calc) -> None: + def set_calc(self, calc: dict) -> None: """ Define the calculation to be performed. The required argument calc is a dictionary with the following keys: diff --git a/p4pillon/server/server.py b/p4pillon/server/server.py index d4894d3..999cdd0 100644 --- a/p4pillon/server/server.py +++ b/p4pillon/server/server.py @@ -146,5 +146,10 @@ def put_pv_value(self, pv_name: str, value): """ Put the value to a PV using the server Context member self._ctxt """ - logger.debug("Trying putting value %r to pv %s", value, pv_name) - self._ctxt.put(pv_name, value) + shared_pv = self[pv_name] + if shared_pv: + logger.debug("Trying SharedNT post to pv %s with value %r ", pv_name, value) + shared_pv.post(value) + else: + logger.debug("Trying Context put to pv %s with value %r ", pv_name, value) + self._ctxt.put(pv_name, value)