Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions src/fastcs/demo/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from fastcs.attributes import AttributeIO, AttributeIORef, AttrR, AttrRW, AttrW
from fastcs.connections import IPConnection, IPConnectionSettings
from fastcs.controllers import Controller
from fastcs.controllers import Controller, ControllerVector
from fastcs.datatypes import Enum, Float, Int, Waveform
from fastcs.logging import logger
from fastcs.methods import command, scan
Expand Down Expand Up @@ -80,15 +80,16 @@ def __init__(self, settings: TemperatureControllerSettings) -> None:

self._settings = settings

self._ramp_controllers: list[TemperatureRampController] = []
for index in range(1, settings.num_ramp_controllers + 1):
controller = TemperatureRampController(index, self.connection)
self._ramp_controllers.append(controller)
self.add_sub_controller(f"R{index}", controller)
self.ramps = ControllerVector(
{
index: TemperatureRampController(index, self.connection)
for index in range(1, settings.num_ramp_controllers + 1)
}
)

@command()
async def cancel_all(self) -> None:
for rc in self._ramp_controllers:
for rc in self.ramps.values():
await rc.enabled.put(OnOffEnum.Off, sync_setpoint=True)
# TODO: The requests all get concatenated and the sim doesn't handle it
await asyncio.sleep(0.1)
Expand Down Expand Up @@ -118,14 +119,14 @@ async def update_voltages(self):

await self.voltages.update(voltages)

for index, controller in enumerate(self._ramp_controllers):
for index, controller in self.ramps.items():
self.log_event(
"Update voltages",
topic=controller.voltage,
query=query,
response=voltages,
)
await controller.voltage.update(float(voltages[index]))
await controller.voltage.update(float(voltages[index - 1]))


class TemperatureRampController(Controller):
Expand Down
59 changes: 59 additions & 0 deletions tests/demo/test_controllers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from unittest.mock import AsyncMock

import numpy as np
import pytest

from fastcs.connections import IPConnectionSettings
from fastcs.controllers import ControllerVector
from fastcs.demo.controllers import (
TemperatureController,
TemperatureControllerSettings,
TemperatureRampController,
)


@pytest.fixture
def controller() -> TemperatureController:
settings = TemperatureControllerSettings(
num_ramp_controllers=4,
ip_settings=IPConnectionSettings(ip="localhost", port=25565),
)
controller = TemperatureController(settings)
controller.post_initialise()
return controller


def test_ramps_is_controller_vector(controller: TemperatureController):
assert isinstance(controller.ramps, ControllerVector)
assert list(controller.ramps) == [1, 2, 3, 4]
for index, ramp in controller.ramps.items():
assert isinstance(ramp, TemperatureRampController)
assert controller.ramps[index] is ramp


@pytest.mark.asyncio
async def test_cancel_all_disables_every_ramp(controller: TemperatureController):
controller.connection.send_command = AsyncMock() # type: ignore[method-assign]

await controller.cancel_all()

sent_commands = [
call.args[0] for call in controller.connection.send_command.call_args_list
]
for index in controller.ramps:
assert f"N{index:02d}=0\r\n" in sent_commands
Comment on lines +37 to +44

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should do the checks on the attributes, not on the call arguments to send_command; check that enabled on each ramp has been set to false. This could be achieved simply by mocking out enabled.put(), and checking that this was called with OnOffEnum.Off for all ramps.



@pytest.mark.asyncio
async def test_update_voltages_updates_waveform_and_each_ramp(
controller: TemperatureController,
):
controller.connection.send_query = AsyncMock(return_value="[1, 2, 3, 4]\r\n")

await controller.update_voltages()

np.testing.assert_array_equal(
controller.voltages.get(), np.array([1, 2, 3, 4], dtype=np.int32)
)
for index, ramp in controller.ramps.items():
assert ramp.voltage.get() == pytest.approx(float(index))
Loading