Skip to content

Commit

Permalink
Laser and power (#1)
Browse files Browse the repository at this point in the history
* first implementation for fakelaser and fakepowermeter

* fix fake powermeter

* append skeleton for device thorlabs

* Fix hunting lock because of timeout lack

* integrate hunt for thorlabs PM100A

* save tree config when loaded

* work on powermeter interface

* start working with lbx_488, it seems that ftdi usb does not work directly... need to investigate

* thorlabs PM100A: append read interface

* cobolt scan ok, usage nok

* improve tty serial connector

* communication ok with devices, need to implement drivers now

* apend function to debug cobolt commands

* Fake blc ok

* start working on connector serial_low_usb

* up

* connector serila_low_usb ok for oxxius

* start integrating oxxisu lbx488

* on/off laser

* up oxxius support

* oxxius almost ok, need to fix precision issues

* oxxius lbx488 support ok

* cobolt 05-01 almost ok

* update power meter with acq freq

* update decimals management

* cobolt 05-01 ok

* manage decimals limitation on powermeter

* allow multiple hunt on oxxisu

* set the powermeter to 5 decimals

* after a set on atts for blc, poll read value before leaving
  • Loading branch information
XdoctorwhoZ authored Feb 27, 2024
1 parent 746a48d commit 7e1e73b
Show file tree
Hide file tree
Showing 54 changed files with 2,708 additions and 88 deletions.
22 changes: 18 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,27 @@ RUN apt-get -y install udev
RUN apt-get -y install ffmpeg
RUN apt-get -y install libusb-1.0-0

#
WORKDIR /platform
COPY . /platform/


#
RUN python3.11 -m pip install coverage
RUN python3.11 -m pip install -r /platform/requirements.txt
RUN python3.11 -m pip install colorama==0.4.6
RUN python3.11 -m pip install paho-mqtt==1.6.1
RUN python3.11 -m pip install pyftdi==0.55.0
RUN python3.11 -m pip install pymodbus==3.3.2
RUN python3.11 -m pip install pyserial==3.5
RUN python3.11 -m pip install pyudev==0.24.0
RUN python3.11 -m pip install pyusb==1.2.1
RUN python3.11 -m pip install PyHamcrest==2.0.4
RUN python3.11 -m pip install aiofiles==23.2.1
RUN python3.11 -m pip install aiomonitor==0.6.0
RUN python3.11 -m pip install aioserial==1.3.1
RUN python3.11 -m pip install ThorlabsPM100==1.2.2
RUN python3.11 -m pip install python-usbtmc==0.8

#
WORKDIR /platform
COPY . /platform/

# Create the mirror directory
RUN mkdir -p /etc/panduza
Expand Down
4 changes: 4 additions & 0 deletions panduza_platform/connectors/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@


# from .thorlabs_pm100.connector import ConnectorThorlabsPM100

182 changes: 182 additions & 0 deletions panduza_platform/connectors/serial_low_usb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import time
import asyncio
import logging
import aioserial

import usb


from .serial_base import ConnectorSerialBase
from panduza_platform.log.driver import driver_logger

from .udev_tty import SerialPortFromUsbSetting

class ConnectorSerialLowUsb(ConnectorSerialBase):
"""
"""

# Hold instances mutex
__MUTEX = asyncio.Lock()

# Contains instances
__INSTANCES = {}

# Local logs
log = driver_logger("ConnectorSerialLowUsb")

###########################################################################
###########################################################################

@staticmethod
async def Get(**kwargs):
"""Singleton main getter
:Keyword Arguments:
* *usb_vendor* (``str``) --
ID_VENDOR_ID
* *usb_model* (``str``) --
ID_MODEL_ID
"""
# Log
ConnectorSerialLowUsb.log.debug(f"Get connector for {kwargs}")

async with ConnectorSerialLowUsb.__MUTEX:

# Log
ConnectorSerialLowUsb.log.debug(f"Lock acquired !")

if "usb_vendor" in kwargs:
usb_vendor = kwargs["usb_vendor"]
if "usb_model" in kwargs:
usb_model = kwargs["usb_model"]

usb_serial_short=""
if "usb_serial_short" in kwargs:
usb_serial_short = kwargs["usb_serial_short"]

instance_name = str(f"{usb_vendor}_{usb_model}_{usb_serial_short}")
print(instance_name)

# Create the new connector
if not (instance_name in ConnectorSerialLowUsb.__INSTANCES):
ConnectorSerialLowUsb.__INSTANCES[instance_name] = None
try:
new_instance = ConnectorSerialLowUsb(**kwargs)
# await new_instance.connect()

ConnectorSerialLowUsb.__INSTANCES[instance_name] = new_instance
ConnectorSerialLowUsb.log.info("connector created")
except Exception as e:
ConnectorSerialLowUsb.__INSTANCES.pop(instance_name)
raise Exception('Error during initialization').with_traceback(e.__traceback__)
else:
ConnectorSerialLowUsb.log.info("connector already created, use existing instance")

# Return the previously created
return ConnectorSerialLowUsb.__INSTANCES[instance_name]

###########################################################################
###########################################################################

def __init__(self, **kwargs):
"""Constructor
"""

# Init local mutex
self._mutex = asyncio.Lock()

# Init command mutex
self._cmd_mutex = asyncio.Lock()


usb_vendor = kwargs.get("usb_vendor")
usb_model = kwargs.get("usb_model")
usb_serial_short = kwargs.get("usb_serial_short")

# ConnectorSerialLowUsb.log.error("pooook")
# print(usb_vendor, usb_model, usb_serial_short)

dev = None
devs = usb.core.find(idVendor=usb_vendor, idProduct=usb_model, find_all=True)
for dev in devs:
if dev.serial_number == usb_serial_short:
dev = dev


if dev is None:
raise ValueError('Device not found')
# print(dev)
dev.reset()
dev.set_configuration()

cfg = dev.get_active_configuration()
intf = cfg[(0,0)]
# print(intf)

# Take first output/input endpoint avaiable

self.ep_out = usb.util.find_descriptor(
intf,
# match the first OUT endpoint
custom_match = \
lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_OUT)

self.ep_in = usb.util.find_descriptor(
intf,
# match the first OUT endpoint
custom_match = \
lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_IN)



# =============================================================================
# OVERRIDE FROM SERIAL_BASE

# ---

async def read(self, n_bytes = None):
"""Read from UART using asynchronous mode
"""
async with self._mutex:
data_array_b = self.ep_in.read(self.ep_in.wMaxPacketSize)
bytes_object = data_array_b.tobytes()
return bytes_object

# ---

async def write(self, message, time_lock_s=None):
"""write to UART using asynchronous mode
"""

async with self._mutex:
try:
# write the data
cmd = message.encode()
packet_to_send = cmd + b'\x00' * (self.ep_out.wMaxPacketSize - len(cmd))
self.ep_out.write(packet_to_send)

except Exception as e:
raise Exception('Error during writing to uart').with_traceback(e.__traceback__)


async def write_and_read(self, message, time_lock_s=None, n_bytes = None):
"""Read from UART using asynchronous mode
"""
async with self._mutex:
try:
# write the data
cmd = message.encode()
packet_to_send = cmd + b'\x00' * (self.ep_out.wMaxPacketSize - len(cmd))
self.ep_out.write(packet_to_send)

# Read
data_array_b = self.ep_in.read(self.ep_in.wMaxPacketSize)
bytes_object = data_array_b.tobytes()
return bytes_object
except Exception as e:
raise Exception('Error during writing to uart').with_traceback(e.__traceback__)
Loading

0 comments on commit 7e1e73b

Please sign in to comment.