diff --git a/src/ibex_bluesky_core/devices/dae/__init__.py b/src/ibex_bluesky_core/devices/dae/__init__.py
index 7ee57d2..dfc971a 100644
--- a/src/ibex_bluesky_core/devices/dae/__init__.py
+++ b/src/ibex_bluesky_core/devices/dae/__init__.py
@@ -10,7 +10,8 @@ def convert_xml_to_names_and_values(xml) -> Dict[str, str]:
elements = get_all_elements_in_xml_with_child_called_name(xml)
for element in elements:
name, value = _get_names_and_values(element)
- names_and_values[name] = value
+ if name is not None:
+ names_and_values[name] = value
return names_and_values
@@ -20,15 +21,15 @@ def get_all_elements_in_xml_with_child_called_name(xml):
return elements
-def _get_names_and_values(element) -> Tuple[str, str]:
+def _get_names_and_values(element) -> tuple[Any, Any] | tuple[None, None]:
name = element.find("Name")
- if name is not None and hasattr(name, "text"):
+ if name is not None and name.text is not None:
name = name.text
- value = element.find("Val")
- if value is not None and hasattr(value, "text"):
- value = value.text
- # TODO hmmmm, should we get choices here and store them somewhere? not sure.
- return name, value
+ value = element.find("Val")
+ if value is not None and value.text is not None:
+ value = value.text
+ return name, value
+ return None, None
def set_value_in_dae_xml(elements: List[ET.ElementTree], name: str, value: Any):
diff --git a/tests/devices/test_dae.py b/tests/devices/test_dae.py
index 71819ee..18060d3 100644
--- a/tests/devices/test_dae.py
+++ b/tests/devices/test_dae.py
@@ -1,9 +1,14 @@
# pyright: reportMissingParameterType=false
+from enum import Enum
+from xml.etree import ElementTree as ET
import pytest
from ibex_bluesky_core.devices.dae.dae import Dae, RunstateEnum
from ophyd_async.core import get_mock_put
+from src.ibex_bluesky_core.devices.dae import set_value_in_dae_xml, convert_xml_to_names_and_values
+from src.ibex_bluesky_core.devices.dae.dae_controls import BeginRunExBits
+
@pytest.fixture
async def dae() -> Dae:
@@ -50,3 +55,125 @@ async def test_trigger_calls_triggers_begin_and_end(dae: Dae):
get_mock_put(dae.controls.begin_run).assert_called_once()
get_mock_put(dae.controls.end_run).assert_called_once()
+
+async def test_begin_run_sets_begin_run_ex(dae: Dae):
+ get_mock_put(dae.controls.begin_run_ex.begin_run_ex).assert_not_called()
+ await dae.controls.begin_run_ex.set(BeginRunExBits.NONE)
+ get_mock_put(dae.controls.begin_run_ex.begin_run_ex).assert_called_once()
+
+async def test_begin_run_ex_with_options_sets_begin_run_ex_correctly(dae: Dae):
+ get_mock_put(dae.controls.begin_run_ex.begin_run_ex).assert_not_called()
+ await dae.controls.begin_run_ex.set(BeginRunExBits.NONE+BeginRunExBits.BEGINIFPAUSED+BeginRunExBits.BEGINIFDELAYED)
+ get_mock_put(dae.controls.begin_run_ex.begin_run_ex).assert_called_once()
+ assert get_mock_put(dae.controls.begin_run_ex.begin_run_ex).call_args.args == (3,)
+
+
+INITIAL_XML = """
+
+
+ {name}
+ {initial_val}
+
+
+ """
+
+
+def test_set_value_in_xml_sets_a_value():
+ name = "test"
+ initial_val = "123"
+
+ root = ET.fromstring(INITIAL_XML.format(name=name, initial_val=initial_val))
+ value_to_set = "234"
+ set_value_in_dae_xml(root.findall(".//child"), name, value_to_set)
+
+ assert root[0][1].text == value_to_set
+
+
+def test_set_value_with_enum_in_xml_sets_a_value():
+ name = "test"
+ initial_val = "456"
+
+ class SomeEnum(Enum):
+ TEST = "789"
+
+ root = ET.fromstring(INITIAL_XML.format(name=name, initial_val=initial_val))
+ value_to_set = SomeEnum.TEST
+ set_value_in_dae_xml(root.findall(".//child"), name, value_to_set)
+
+ assert root[0][1].text == value_to_set.value
+
+
+def test_set_value_with_none_in_xml_doesnt_set_a_value():
+ name = "test"
+ initial_val = "456"
+
+ root = ET.fromstring(INITIAL_XML.format(name=name, initial_val=initial_val))
+ set_value_in_dae_xml(root.findall(".//child"), name, None)
+
+ assert root[0][1].text == initial_val
+
+
+def test_set_value_with_no_valid_children_in_xml_doesnt_set_a_value():
+ name = "test"
+ initial_val = "456"
+
+ root = ET.fromstring(INITIAL_XML.format(name=name, initial_val=initial_val))
+ set_value_in_dae_xml(root.findall(".//child"), name + "thisisnowinvalid", "789")
+
+ assert root[0][1].text == initial_val
+
+
+def test_get_names_and_values_from_xml():
+ name = "test"
+ initial_val = "456"
+ test_xml = f"""
+
+
+ Cluster
+ 2
+
+
+ {name}
+ {initial_val}
+
+
+ """
+ root = ET.fromstring(test_xml)
+ ret = convert_xml_to_names_and_values(root)
+ assert ret[name] == initial_val
+
+
+def test_get_names_and_values_without_name_does_not_get_parsed():
+ test_xml = f"""
+
+
+ Cluster
+ 2
+
+
+
+
+
+
+ """
+ root = ET.fromstring(test_xml)
+ ret = convert_xml_to_names_and_values(root)
+ assert not ret
+
+
+def test_get_names_and_values_without_value_does_not_get_parsed():
+ test_xml = f"""
+
+
+ Cluster
+ 2
+
+
+ test
+
+
+
+ """
+ root = ET.fromstring(test_xml)
+ ret = convert_xml_to_names_and_values(root)
+ assert not ret
diff --git a/tests/devices/test_init.py b/tests/devices/test_init.py
index e640391..affcfda 100644
--- a/tests/devices/test_init.py
+++ b/tests/devices/test_init.py
@@ -2,7 +2,12 @@
import pytest
-from ibex_bluesky_core.devices import compress_and_hex, dehex_and_decompress, get_pv_prefix, isis_epics_signal_rw
+from ibex_bluesky_core.devices import (
+ compress_and_hex,
+ dehex_and_decompress,
+ get_pv_prefix,
+ isis_epics_signal_rw,
+)
def test_can_dehex_and_decompress():