"""Board commands with mandatory acknowledgements.""" import logging import time from .constants import WAIT_AFTER_SEND_SEC from .exceptions import CommunicationError from .protocol import Protocol logger = logging.getLogger(__name__) DEVICE_MAIN_MESSAGE_ID = 0x00FF class LaserController: """Control constant setpoints or LD1 current variation through one serial port.""" def __init__(self, port: str, *, pi_coeff1_p: int, pi_coeff1_i: int, pi_coeff2_p: int, pi_coeff2_i: int): self._protocol = Protocol(port) self._pi = dict(pi_coeff1_p=pi_coeff1_p, pi_coeff1_i=pi_coeff1_i, pi_coeff2_p=pi_coeff2_p, pi_coeff2_i=pi_coeff2_i) def connect(self) -> bool: self._protocol.connect() logger.info("Connected to laser controller on port %s", self._protocol.port) return True def disconnect(self) -> None: self._protocol.disconnect() logger.info("Disconnected from laser controller") def set_manual_mode(self, temp1: float, temp2: float, current1: float, current2: float, message_id: int) -> None: manual = dict(temp1=temp1, temp2=temp2, current1=current1, current2=current2) self._send_and_read_state(Protocol.encode_decode_enable(**manual, **self._pi, message_id=message_id)) logger.debug("Manual setpoints: %s", manual) def start_variation(self, params: dict) -> None: self._send_and_read_state(Protocol.encode_task_enable( **params, pi_coeff1_p=self._pi["pi_coeff1_p"], pi_coeff1_i=self._pi["pi_coeff1_i"], pi_coeff2_p=self._pi["pi_coeff2_p"], pi_coeff2_i=self._pi["pi_coeff2_i"], )) logger.info("LD1 current variation started: %s", params) def reset(self) -> None: self._send_and_read_state(b"\x22\x22") logger.info("Device reset command sent") def _send(self, command: bytes) -> None: self._protocol.send_raw(command) time.sleep(WAIT_AFTER_SEND_SEC) def _send_and_read_state(self, command: bytes) -> None: self._send(command) state = Protocol.decode_state(self._protocol.receive_raw(2)) if state: raise CommunicationError(f"Device rejected command: STATE 0x{state:04x}")