diff --git a/superxas_bec/devices/timepix/beamline_test.py b/superxas_bec/devices/timepix/beamline_test.py new file mode 100644 index 0000000..559e4cf --- /dev/null +++ b/superxas_bec/devices/timepix/beamline_test.py @@ -0,0 +1,53 @@ +from ophyd_devices.devices.areadetector.cam import ASItpxCam +from ophyd import Component as Cpt +from ophyd_devices import TransitionStatus +from superxas_bec.devices.timepix.timepix_fly_client.timepix_fly_interface import NetAddresses + +class SuperXasTimePix(ADBase) + cam = Cpt(ASItpxCam, 'cam1:') + +if __name__ == """__main__""": + import time + + from superxas_bec.devices.timepix.timepix import Timepix + from superxas_bec.devices.timepix.timepix_fly_client.timepix_fly_mock_server import ( + TimePixFlyMockServer, + ) + + timepix_control = SuperXasTimePix(name='timepix_control', prefix='X10DA-ES-TPX1:') + # timepix_control.wait_for_connection(all_signals=True, timeout=10) + # Create a Timepix object + timepix = Timepix(name="TimePixDetector") + timepix.on_connected() + + ## LOOP for a scan + timepix.stage() + net_addresses:NetAddresses = timepix.timepix_fly_client.get_net_addresses() + print(f"Net addresses: {net_addresses}") + file_path = f"tcp://connect@{net_addresses.data_socket_for_asi}" + print(f"Using file path: {file_path}") + period = 1 + num_images =5 + timepix_control.cam.trigger_mode.set(0).wait(timeout=10) + timepix_control.cam.acquire_period.set(period).wait(timeout=10) + timepix_control.cam.acquire_time.set(period-2e-3).wait(timeout=10) + timepix_control.cam.num_images.set(num_images).wait(timeout=10) + timepix_control.cam.raw_enable.set(True).wait(timeout=10) + timepix_control.cam.raw_file_path.set(file_path).wait(timeout=10) + timepix_control.cam.raw_file_template.set('test_raw').wait(timeout=10) + + timepix.pre_scan() # This sends the address to the ASI server from TimePixFly + status = TransitionStatus(timepix_control.cam.acquire, [1, 0]) + timepix_control.cam.acquire.put(1) + status.wait(timeout=20) + # time.sleep(5) + time.sleep(5) + print(timepix._data_buffer) + print(timepix.timepix_fly_client.last_error()) + + # status = timepix.complete() + # status.wait(timeout=10) + # for ii, msg in enumerate(timepix._data_buffer): + # print(f"Received data {ii} with message type {msg['type']}") + timepix.unstage() + timepix.destroy() diff --git a/superxas_bec/devices/timepix/timepix.py b/superxas_bec/devices/timepix/timepix.py index 982475e..a651b31 100644 --- a/superxas_bec/devices/timepix/timepix.py +++ b/superxas_bec/devices/timepix/timepix.py @@ -159,7 +159,7 @@ class Timepix(PSIDeviceBase, Device): self.cancel_on_stop(status) self.timepix_fly_client.add_status_callback( status, - success=[TimePixFlyStatus.SETUP], + success=[TimePixFlyStatus.AWAIT_CONNECTION], error=[TimePixFlyStatus.EXCEPT, TimePixFlyStatus.SHUTDOWN], ) self.timepix_fly_client.start() # --> State goes to setup diff --git a/superxas_bec/devices/timepix/timepix_fly_client/timepix_fly_client.py b/superxas_bec/devices/timepix/timepix_fly_client/timepix_fly_client.py index c7ee696..44f9fbb 100644 --- a/superxas_bec/devices/timepix/timepix_fly_client/timepix_fly_client.py +++ b/superxas_bec/devices/timepix/timepix_fly_client/timepix_fly_client.py @@ -21,6 +21,7 @@ from websockets.sync.client import ClientConnection, connect from superxas_bec.devices.timepix.timepix_fly_client.timepix_fly_interface import ( LastError, + NetAddresses, OtherConfigModel, PixelMap, PixelMapFromFile, @@ -51,6 +52,7 @@ class TimePixFlyStatus(str, enum.Enum): COLLECT = "collect" SHUTDOWN = "shutdown" UNDEFINED = "undefined" + AWAIT_CONNECTION = "await_connection" EXCEPT = "except" @@ -419,3 +421,13 @@ class TimepixFlyClient: f"Value must be an instance of OtherConfigModel. Received {type(other_config)}, {other_config}." ) self._put(put_cmd="other-config", value=other_config.model_dump(), put_response_model=None) + + def get_net_addresses(self) -> dict[str, str]: + """ + Get the network addresses of the TimePix detector by sending a GET request + to the net-addresses endpoint. + + Returns: + dict[str, str]: A dictionary containing the network addresses of the TimePix detector. + """ + return self._get(get_cmd="net-addresses", get_response_model=NetAddresses) diff --git a/superxas_bec/devices/timepix/timepix_fly_client/timepix_fly_interface.py b/superxas_bec/devices/timepix/timepix_fly_client/timepix_fly_interface.py index b128c6c..43fb705 100644 --- a/superxas_bec/devices/timepix/timepix_fly_client/timepix_fly_interface.py +++ b/superxas_bec/devices/timepix/timepix_fly_client/timepix_fly_interface.py @@ -119,3 +119,33 @@ class TimepixDataFrame(TimePixResponse): class TimepixEndFrame(TimePixResponse): pass + + +# Habe ein GET /net-addresses call implementiert +# // /net-addresses GET applicable net addresses +# // GET return: +# // - status 200 +# // - data +# // { +# // "type":"NetAddresses", +# // "control":"127.0.0.1:8452", // own rest interface +# // "address":"127.0.0.1:8451", // own address, the destination of ASI server raw data +# // "server":"127.0.0.1:8080" // ASI server rest interface address +# // } + + +class NetAddresses(TimePixResponse): + """ + NetAddresses is a Pydantic model that represents the network addresses used by the TimePix detector. + + Attributes: + - type: str - The type of the response, default is "NetAddresses". + - control: str - The address of the REST interface for control commands. + - address: str - The address where the ASI server sends raw data. + - server: str - The address of the ASI server's REST interface. + """ + + type: str = "NetAddresses" + timepix_rest_host: str + data_socket_for_asi: str + asi_rest_host: str