diff --git a/README.md b/README.md index 92c92b35..f272138e 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,12 @@ ![Github link](https://badgen.net/github/tag/dgbowl/tomato/?icon=github) ![Github status](https://badgen.net/github/checks/dgbowl/tomato/?icon=github) -`tomato` is the instrument automation package developed at Empa. Currently supported -hardware is: +`tomato` is the instrument automation package developed at the [ConCat lab](https://tu.berlin/en/concat). Currently supported hardware is: + +- `example_counter`: an example device for testing purposes. + +Partially supported hardware includes: -- `dummy`: a Dummy device for testing purposes - `biologic`: device for BioLogic potentiostats via the EC-Lib library, Windows only. See the [Documentation](https://dgbowl.github.io/tomato) for more detailed info. diff --git a/src/tomato/drivers/example_counter/counter.py b/src/tomato/drivers/example_counter/counter.py index 3888b4da..834361f1 100644 --- a/src/tomato/drivers/example_counter/counter.py +++ b/src/tomato/drivers/example_counter/counter.py @@ -37,7 +37,7 @@ def run_counter(self, conn): self.started_at = None cmd = None - if conn.poll(1e-6): + if conn.poll(1e-3): cmd, attr, val = conn.recv() if cmd == "set": @@ -58,3 +58,5 @@ def run_counter(self, conn): elif cmd == "data": conn.send(data) data = [] + else: + time.sleep(1e-3) diff --git a/src/tomato/tomato/__init__.py b/src/tomato/tomato/__init__.py index cb26daa9..5b654c03 100644 --- a/src/tomato/tomato/__init__.py +++ b/src/tomato/tomato/__init__.py @@ -370,7 +370,8 @@ def reload( ret = _updater( context, port, "driver", dict(name=drv.name, settings=drv.settings) ) - logger.critical(f"{ret=}") + if ret.success is False: + return ret # check changes in devices for dev in devs.values(): @@ -378,7 +379,6 @@ def reload( dev.name not in daemon.devs or dev.channels != daemon.devs[dev.name].channels ): - logger.error(f"Here {dev.channels=} {dev.name=}") for channel in dev.channels: params = dict( address=dev.address, @@ -390,9 +390,10 @@ def reload( ) if ret.success is False: return ret - params = dict(name=dev.name, channels=dev.channels) + params = dev.dict() ret = _updater(context, port, "device", params) - logger.critical(f"{ret=}") + if ret.success is False: + return ret elif dev != daemon.devs[dev.name]: logger.error("updating devices not yet implemented") for devname in daemon.devs: @@ -402,16 +403,19 @@ def reload( for pip in pips.values(): if pip.name not in daemon.pips: ret = _updater(context, port, "pipeline", pip.dict()) - logger.critical(f"{ret=}") + if ret.success is False: + return ret else: logger.error("updating pipelines not yet implemented") for pip in daemon.pips.values(): if pip.name not in pips: params = dict(name=pip.name, delete=True) ret = _updater(context, port, "pipeline", params) - logger.critical(f"{ret=}") - - req.send_pyobj(dict(cmd="status", with_data=True, sender=f"{__name__}.reload")) + if ret.success is False: + return ret + req.send_pyobj( + dict(cmd="setup", settings=settings, sender=f"{__name__}.reload") + ) rep = req.recv_pyobj() if rep.msg == "running": diff --git a/tests/common/counter_multidev.yml b/tests/common/counter_multidev.yml new file mode 100644 index 00000000..0b3ca37b --- /dev/null +++ b/tests/common/counter_multidev.yml @@ -0,0 +1,14 @@ +version: "0.2" +sample: + name: counter_multidev +method: + - device: "counter-1" + technique: "count" + time: 1.0 + delay: 0.1 + - device: "counter-2" + technique: "count" + time: 1.0 + delay: 0.2 +tomato: + verbosity: "DEBUG" \ No newline at end of file diff --git a/tests/common/counter_multistep.yml b/tests/common/counter_multistep.yml new file mode 100644 index 00000000..b6b745c2 --- /dev/null +++ b/tests/common/counter_multistep.yml @@ -0,0 +1,14 @@ +version: "0.2" +sample: + name: counter_multistep +method: + - device: "counter" + technique: "count" + time: 1.0 + delay: 0.1 + - device: "counter" + technique: "count" + time: 1.0 + delay: 0.2 +tomato: + verbosity: "DEBUG" \ No newline at end of file diff --git a/tests/common/counter_multistep_multidev.yml b/tests/common/counter_multistep_multidev.yml new file mode 100644 index 00000000..8cddcded --- /dev/null +++ b/tests/common/counter_multistep_multidev.yml @@ -0,0 +1,18 @@ +version: "0.2" +sample: + name: counter_multistep_multidev +method: + - device: "counter-1" + technique: "count" + time: 1.0 + delay: 0.2 + - device: "counter-1" + technique: "count" + time: 1.0 + delay: 0.2 + - device: "counter-2" + technique: "count" + time: 2.0 + delay: 0.1 +tomato: + verbosity: "DEBUG" \ No newline at end of file diff --git a/tests/common/devices_multidev.json b/tests/common/devices_multidev.json new file mode 100644 index 00000000..85b2702f --- /dev/null +++ b/tests/common/devices_multidev.json @@ -0,0 +1,35 @@ +{ + "devices": [ + { + "name": "dev-counter-1", + "driver": "example_counter", + "address": "example-addr-1", + "channels": [1, 2, 3, 4], + "capabilities": ["count"], + "pollrate": 2 + }, + { + "name": "dev-counter-2", + "driver": "example_counter", + "address": "example-addr-2", + "channels": [5, 6, 7, 8], + "capabilities": ["count"], + "pollrate": 1 + } + ], + "pipelines": [ + { + "name": "pip-counter", + "devices": [ + {"tag": "counter", "name": "dev-counter-1", "channel": 1} + ] + }, + { + "name": "pip-multidev", + "devices": [ + {"tag": "counter-1", "name": "dev-counter-1", "channel": 4}, + {"tag": "counter-2", "name": "dev-counter-2", "channel": 5} + ] + } + ] +} \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py index 93b46e87..2ea2c0bd 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -30,7 +30,7 @@ def start_tomato_daemon(tmpdir: str, port: int = 12345): # setup_stuff os.chdir(tmpdir) subprocess.run(["tomato", "init", "-p", f"{port}", "-A", ".", "-D", "."]) - subprocess.run(["tomato", "start", "-p", f"{port}", "-A", ".", "-L", "."]) + subprocess.run(["tomato", "start", "-p", f"{port}", "-A", ".", "-L", ".", "-vv"]) yield # teardown_stuff diff --git a/tests/test_99_example_counter.py b/tests/test_99_example_counter.py index aeacc99e..1bf26bc5 100644 --- a/tests/test_99_example_counter.py +++ b/tests/test_99_example_counter.py @@ -2,10 +2,14 @@ import os import subprocess import time +import json +import yaml import xarray as xr from . import utils +PORT = 12345 + @pytest.mark.parametrize( "casename, npoints, prefix", @@ -14,6 +18,7 @@ ("counter_5_0.2", 25, "results.1"), ("counter_output_prefix", 20, "data"), ("counter_output_path", 20, os.path.join("newfolder", "results.1")), + ("counter_multistep", 15, "results.1"), ], ) def test_counter_npoints( @@ -81,3 +86,38 @@ def test_counter_snapshot( status = utils.job_status(1)["data"][1]["status"] assert status == "c" assert os.path.exists("snapshot.1.nc") + + +@pytest.mark.parametrize( + "casename, npoints", + [ + ("counter_multidev", 15), + ("counter_multistep_multidev", 30), + ], +) +def test_counter_multidev( + casename, npoints, datadir, start_tomato_daemon, stop_tomato_daemon +): + os.chdir(datadir) + with open("devices_multidev.json", "r") as inf: + jsdata = json.load(inf) + with open("devices.yml", "w") as ouf: + yaml.dump(jsdata, ouf) + utils.wait_until_tomato_running(port=PORT, timeout=3000) + subprocess.run(["tomato", "reload", "-p", f"{PORT}", "-A", "."]) + + utils.run_casenames([casename], [None], ["pip-multidev"]) + utils.wait_until_ketchup_status(jobid=1, status="r", port=PORT, timeout=10000) + utils.wait_until_ketchup_status(jobid=1, status="c", port=PORT, timeout=10000) + + ret = utils.job_status(1) + print(f"{ret=}") + status = utils.job_status(1)["data"][1]["status"] + assert status == "c" + files = os.listdir(os.path.join(".", "Jobs", "1")) + assert "jobdata.json" in files + assert "job-1.log" in files + assert os.path.exists("results.1.nc") + ds = xr.load_dataset("results.1.nc") + print(f"{ds=}") + assert ds["uts"].size == npoints