ap--/python-seabreeze

Ethernet Support for HDX

lovelesh-mis opened this issue · 7 comments

spectrometer and system information

  • model: OceanHDX
  • operating system: Windows/ Linux 64-bit
  • python version: 3.10
  • python-seabreeze version: current master
  • installed-via: python setup.py install

I am facing the same issue of USB timeout as in #133. I have tested with Flame-T and everything works fine but I get a timeout error with HDX. I am wondering if there is a mechanism to connect to HDX using Ethernet. pyseabreeze has add_ipv4_device_location function but is not implemented.

Can you provide how to set started with this implementation? I feel we can bypass the pyusb drivers issue in Linux by implementing ethernet based drivers.

I am facing a similar issue and we are looking into implementing communication via Ethernet for an OceanHDX spectrometer. I am currently looking into how much effort it would be to do this through the pyseabreeze backend (versus a standalone solution) -- pointers into the right direction would be very welcome!

@lovelesh-mis, have you started with the implementation yet?

I was able to get it working to some using Ethernet with static IP. I used @Dargaud's C Library for OceanHDX for reference. I designed my commands exactly as per his library. Socket library in windows and linux is platform agnostic and very reliable. Also, there is no driver issues as compared to USB. Wth my current setup, I can use Oceanview and my python code simultaneously.

I compared pyseabreeze commands to the C library mentioned above and they are exactly the same. So, I think one need to develop a mechanism to send the commands through an IP socket. I didnt have much idea about the pyseabreeze backend, so I went with standalone approach.
Also, OveanView implements a basic mDNS protocol to discover new devices over the network. You can just run wireshark and grab those packets. All ocean devices are programmed to send their IDs as multicast packets.

Oh, thanks for the hint with Dargaud's library! That looks promising :)
So if I understand correctly, you created a Python wrapper around that library mimicking the seabreeze API?

Do you know whether the library supports buffered readout? That is a feature we would particularly like to use in the future, once all basic functionality is there.

I have started to implement IPv4 socket communication into pyseabreeze and will give that a shot today. It will only support static IPs for now and I hard-coded most in the beginning, but the pyseabreeze design would allow for an implementation of multicast to search for devices in the future. If my tests work, I will try to upstream this. Otherwise, I might go the same route as you did.

ap-- commented

Hello everyone,

I wasn't aware of that library, we should link to it in the README for reference. If someone could test if the USB implementation in dargauds library is working reliably on windows, we might be able to find the issue with pyusb that causes issues for seabreeze.

If there's interest in developing a ethernet backend for pyseabreeze, I can help with some guidance on how it would fit into the current module design.

class PySeaBreezeTransport(ABC, Generic[DT]):
_required_init_kwargs: tuple[str, ...] = ()
@abstractmethod
def open_device(self, device: DT) -> None:
"""open a seabreeze device
Parameters
----------
device : seabreeze.pyseabreeze.devices.SeaBreezeDevice
"""
...
@property
@abstractmethod
def is_open(self) -> bool:
"""return if device is opened
Returns
-------
bool
"""
return False
@abstractmethod
def close_device(self) -> None:
"""close the seabreeze device"""
...
@abstractmethod
def write(self, data: bytes, timeout_ms: int | None = None, **kwargs: Any) -> int:
"""write data to the device"""
...
@abstractmethod
def read(
self,
size: int | None = None,
timeout_ms: int | None = None,
**kwargs: Any,
) -> bytes:
"""read data from the
Returns
-------
bytes
"""
...
@property
@abstractmethod
def default_timeout_ms(self) -> int: ...
@property
@abstractmethod
def protocol(self) -> PySeaBreezeProtocol: ...
@classmethod
@abstractmethod
def list_devices(cls) -> Iterable[DT]: ...
@classmethod
@abstractmethod
def register_model(cls, model_name: str, **kwargs: str) -> None: ...
@classmethod
@abstractmethod
def supported_model(cls, device: DT) -> str | None:
"""return if the device supports the transport or vice versa
Returns
-------
model_name : ``
"""
return None
@classmethod
@abstractmethod
def specialize(
cls, model_name: str, **kwargs: str
) -> type[PySeaBreezeTransport[Any]]: ...
a new Transport subclass would need to be implemented to handle the ethernet communication. (We should discuss in a new issue)
Also, that being said, it's probably easier to start with a minimal working example, and then take that and squeeze it into the correct structure for integration into python-seabreeze.

Cheers,
Andreas

Hej Andreas!

Thanks for the pointer -- I have made proof-of-concept implementation and would really appreciate your comments on that. It is far from done, but I would like to get your feedback on whether that approach is compatible with the structure of python-seabreeze.

Thanks! :)

ap-- commented

Closed via #243 thanks to amazing work by @hperrey ❤️

Will be available in 2.9.0