Minimal working implementation, needs a lot of work
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Mon Jun 3 14:16:29 2024
|
||||
|
||||
@author: mohacsi_i
|
||||
"""
|
||||
from time import sleep
|
||||
from ophyd import Device, Signal, Component
|
||||
from websockets.sync.client import connect
|
||||
from websockets.exceptions import ConnectionClosedOK, ConnectionClosedError
|
||||
|
||||
import json
|
||||
|
||||
class StdDaqClientDevice(Device):
|
||||
""" Lightweight wrapper around the undocumented StdDaq websocket interface.
|
||||
This was meant to replace the documented python client.
|
||||
"""
|
||||
# Status attributes
|
||||
n_image = Component(Signal)
|
||||
file_path = Component(Signal)
|
||||
|
||||
def __init__(self, *args, parent: Device = None, **kwargs) -> None:
|
||||
super().__init__(*args, parent=parent, **kwargs)
|
||||
self.ws_server_url = (
|
||||
kwargs["daq_url"] if "daq_url" in kwargs else "ws://xbl-daq-29:8080")
|
||||
self._client = connect(self.ws_server_url)
|
||||
|
||||
self.n_image.set(100)
|
||||
self.file_path.set("/gpfs/test/test-beamline")
|
||||
|
||||
def configure(self, d: dict) -> tuple:
|
||||
"""
|
||||
Example:
|
||||
std.configure(d={'n_images': 234, 'file_path': "/data/test/raw"})
|
||||
"""
|
||||
if "num_images" in d:
|
||||
self.n_images.set(d['n_images'])
|
||||
del d['num_images']
|
||||
if "file_path" in d:
|
||||
self.output_file.set(d['file_path'])
|
||||
del d['file_path']
|
||||
return (old_config, new_config)
|
||||
|
||||
def stage(self):
|
||||
file_path = self.file_path.get()
|
||||
n_image = self.n_image.get()
|
||||
|
||||
message = {"command":"start", "path": file_path, "n_image": n_image}
|
||||
self.message(message)
|
||||
return super().stage()
|
||||
|
||||
def unstage(self):
|
||||
""" Stop a running acquisition
|
||||
|
||||
WARN: This will also close the connection!!!
|
||||
"""
|
||||
message = {"command":"stop"}
|
||||
self.message(message)
|
||||
return super().unstage()
|
||||
|
||||
def stop(self, *, success=False):
|
||||
""" Stop a running acquisition
|
||||
|
||||
WARN: This will also close the connection!!!
|
||||
"""
|
||||
message = {"command":"stop"}
|
||||
self.message(message)
|
||||
|
||||
def status(self):
|
||||
return self.message({"command": "status"})
|
||||
|
||||
def abort(self):
|
||||
return self.message({"command": "abort"})
|
||||
|
||||
def message(self, d: dict, timeout=1):
|
||||
"""
|
||||
|
||||
Note: finishing acquisition meang StdDAQ will close connections
|
||||
"""
|
||||
print(d)
|
||||
reply = None
|
||||
if isinstance(d, dict):
|
||||
msg = json.dumps(d)
|
||||
else:
|
||||
msg = str(d)
|
||||
# Send message (reopen connection if needed)
|
||||
try:
|
||||
self._client.send(msg)
|
||||
except ConnectionClosedError:
|
||||
# StdDAQ may reject connection for a few seconds
|
||||
try:
|
||||
self._client = connect(self.ws_server_url)
|
||||
except ConnectionRefusedError:
|
||||
sleep(5)
|
||||
self._client = connect(self.ws_server_url)
|
||||
self._client.send(msg)
|
||||
except ConnectionClosedOK:
|
||||
# StdDAQ may reject connection for a few seconds
|
||||
try:
|
||||
self._client = connect(self.ws_server_url)
|
||||
except ConnectionRefusedError:
|
||||
sleep(5)
|
||||
self._client = connect(self.ws_server_url)
|
||||
self._client.send(msg)
|
||||
# Wait for reply
|
||||
try:
|
||||
reply = self._client.recv(timeout)
|
||||
print(reply)
|
||||
except ConnectionClosedError:
|
||||
pass
|
||||
except TimeoutError:
|
||||
pass
|
||||
return reply
|
||||
|
||||
|
||||
Reference in New Issue
Block a user