diff --git a/beams/tests/artifacts/egg_generator.py b/beams/tests/artifacts/egg_generator.py index 466cb3a..3cf06ef 100644 --- a/beams/tests/artifacts/egg_generator.py +++ b/beams/tests/artifacts/egg_generator.py @@ -9,7 +9,8 @@ from apischema import serialize from beams.tree_config.action import IncPVActionItem, SetPVActionItem -from beams.tree_config.base import BehaviorTreeItem, EPICSValue, FixedValue +from beams.tree_config.base import BehaviorTreeItem +from beams.tree_config.value import EPICSValue, FixedValue from beams.tree_config.composite import SequenceItem from beams.tree_config.condition import (BinaryConditionItem, BoundedConditionItem, diff --git a/beams/tests/test_bin.py b/beams/tests/test_bin.py index 22ff2e0..f9505a3 100644 --- a/beams/tests/test_bin.py +++ b/beams/tests/test_bin.py @@ -15,7 +15,7 @@ from beams.bin.main import main from beams.tests.conftest import cli_args, restore_logging from beams.tree_config import save_tree_item_to_path -from beams.tree_config.base import EPICSValue +from beams.tree_config.value import EPICSValue from beams.tree_config.composite import SequenceItem from beams.tree_config.condition import BinaryConditionItem diff --git a/beams/tests/test_serialize.py b/beams/tests/test_serialize.py index b056f25..9b8498c 100644 --- a/beams/tests/test_serialize.py +++ b/beams/tests/test_serialize.py @@ -1,7 +1,8 @@ from apischema import deserialize, serialize from beams.tree_config.action import IncPVActionItem, SetPVActionItem -from beams.tree_config.base import BehaviorTreeItem, EPICSValue, FixedValue +from beams.tree_config.base import BehaviorTreeItem +from beams.tree_config.value import EPICSValue, FixedValue from beams.tree_config.composite import SequenceItem from beams.tree_config.condition import BinaryConditionItem, ConditionOperator from beams.tree_config.idiom import CheckAndDoItem diff --git a/beams/tree_config/base.py b/beams/tree_config/base.py index ed5ba90..338b199 100644 --- a/beams/tree_config/base.py +++ b/beams/tree_config/base.py @@ -1,9 +1,7 @@ import logging from dataclasses import dataclass -from typing import Any import py_trees -from epics import caget from py_trees.behaviour import Behaviour from beams.serialization import as_tagged_union @@ -38,35 +36,3 @@ def get_tree(self) -> Behaviour: # grab file # de-serialize tree, return it raise NotImplementedError - - -@as_tagged_union -@dataclass -class BaseValue: - def get_value(self) -> Any: - raise NotImplementedError - - -@dataclass -class FixedValue(BaseValue): - value: Any - - def get_value(self) -> Any: - return self.value - - -@dataclass -class EPICSValue(BaseValue): - pv_name: str - as_string: bool = False - - def get_value(self) -> Any: - value = caget(self.pv_name, as_string=self.as_string) - logger.debug(f" <<-- (EPICSValue): caget({self.pv_name}) -> {value}") - return value - - -@dataclass -class OphydTarget(BaseValue): - device_name: str - component_path: list[str] diff --git a/beams/tree_config/condition.py b/beams/tree_config/condition.py index 514f4e4..e185ee3 100644 --- a/beams/tree_config/condition.py +++ b/beams/tree_config/condition.py @@ -4,7 +4,8 @@ from beams.behavior_tree.condition_node import ConditionNode from beams.serialization import as_tagged_union -from beams.tree_config.base import BaseItem, BaseValue, FixedValue +from beams.tree_config.base import BaseItem +from beams.tree_config.value import BaseValue, FixedValue from beams.typing_helper import Evaluatable diff --git a/beams/tree_config/idiom.py b/beams/tree_config/idiom.py index 96e2b63..fdcb808 100644 --- a/beams/tree_config/idiom.py +++ b/beams/tree_config/idiom.py @@ -49,4 +49,3 @@ class UseCheckConditionItem(BaseConditionItem): If used in any other context the tree will not be constructable. """ - ... diff --git a/beams/tree_config/value.py b/beams/tree_config/value.py new file mode 100644 index 0000000..8736061 --- /dev/null +++ b/beams/tree_config/value.py @@ -0,0 +1,59 @@ +import logging +from typing import Any +from dataclasses import dataclass + +import py_trees +from epics import caget +from beams.serialization import as_tagged_union + +logger = logging.getLogger(__name__) + + +@as_tagged_union +@dataclass +class BaseValue: + def get_value(self) -> Any: + raise NotImplementedError + + +@dataclass +class FixedValue(BaseValue): + value: Any + + def get_value(self) -> Any: + return self.value + + +@dataclass +class EPICSValue(BaseValue): + pv_name: str + as_string: bool = False + + def get_value(self) -> Any: + value = caget(self.pv_name, as_string=self.as_string) + logger.debug(f" <<-- (EPICSValue): caget({self.pv_name}) -> {value}") + return value + + +class BlackBoardValue(BaseValue): + bb_name: str = "" + key_name: str = "" + + def get_value(self) -> Any: + logger.debug(f" <<-- (BlackBoardValue): checking blackboard: {self.bb_name} \ + for key {self.key_name}") + bb_client = py_trees.blackboard.Client(name=self.bb_name) + try: + value = bb_client.get(self.key_name) + except AttributeError: # Note: seems like it should be KeyError, but in practice getting this one + logger.error(f"<<-- In blackboard: {self.bb_name} \ + key {self.key_name} does not exist \ + returning None") + return None + return value + + +@dataclass +class OphydTarget(BaseValue): + device_name: str + component_path: list[str] diff --git a/examples/mfx_dg1/mfx_tree.py b/examples/mfx_dg1/mfx_tree.py index de0c920..542c119 100644 --- a/examples/mfx_dg1/mfx_tree.py +++ b/examples/mfx_dg1/mfx_tree.py @@ -2,7 +2,7 @@ from beams.tree_config import save_tree_item_to_path from beams.tree_config.action import SetPVActionItem -from beams.tree_config.base import EPICSValue, FixedValue +from beams.tree_config.value import EPICSValue, FixedValue from beams.tree_config.composite import (SelectorItem, SequenceConditionItem, SequenceItem) from beams.tree_config.condition import (BinaryConditionItem,