def test_command_process_bad_reply(reply): command = ArchonCommand("ping", 1) with pytest.warns(ArchonUserWarning): command.process_reply(reply) assert command.status == command.status.FAILED
def parser(cmd: ArchonCommand): if cmd.command_string == after_command: reply = f"?{cmd.command_id:02X}\n" cmd._mark_done(ArchonCommandStatus.FAILED) else: reply = f"<{cmd.command_id:02X}\n" cmd._mark_done() cmd.replies = [ArchonCommandReply(reply.encode(), cmd)] return cmd
def send_command( self, command_string: str, command_id: Optional[int] = None, **kwargs, ) -> ArchonCommand: """Sends a command to the Archon. Parameters ---------- command_string The command to send to the Archon. Will be converted to uppercase. command_id The command id to associate with this message. If not provided, a sequential, autogenerated one will be used. kwargs Other keyword arguments to pass to `.ArchonCommand`. """ command_id = command_id or self._get_id() if command_id > MAX_COMMAND_ID or command_id < 0: raise ArchonError( f"Command ID must be in the range [0, {MAX_COMMAND_ID:d}]." ) command = ArchonCommand( command_string, command_id, controller=self, **kwargs, ) self.__running_commands[command_id] = command self.write(command.raw) return command
async def test_command_get_replies(): async def background(command: ArchonCommand): command.process_reply(b"<01pong1") await asyncio.sleep(0.01) command.process_reply(b"<01pong1") await asyncio.sleep(0.02) command._mark_done() command = ArchonCommand("ping", 1, expected_replies=None) asyncio.create_task(background(command)) replies = [] async for reply in command.get_replies(): replies.append(reply) assert command.succeeded() assert len(replies) == 2
async def test_command_two_replies(): command = ArchonCommand("ping", 1, expected_replies=2, timeout=0.1) assert command.status == command.status.RUNNING command.process_reply(b"<01pong1") assert command.status == command.status.RUNNING await asyncio.sleep(0.01) command.process_reply(b"<01pong2") assert command.status == command.status.DONE
def default_parser(cmd: ArchonCommand): if cmd.command_string == "SYSTEM": cmd._mark_done() cmd.replies = [ArchonCommandReply(b"<00SYSTEM=0 MOD1_TYPE=1", cmd)] return cmd r_n = int(cmd.command_string[7:11], 16) cmd._mark_done() if r_n < 3: reply = f"<{r_n:02X}LINE{r_n}={r_n}\n" elif r_n < 5: reply = f"<{r_n:02X}LINE{r_n}={r_n}={r_n}\n" else: reply = f"<{r_n:02X}\n" cmd.replies = [ArchonCommandReply(reply.encode(), cmd)] return cmd
async def background(command: ArchonCommand): command.process_reply(b"<01pong1") await asyncio.sleep(0.01) command.process_reply(b"<01pong1") await asyncio.sleep(0.02) command._mark_done()
async def test_command_timeout(): command = ArchonCommand("ping", 1, expected_replies=2, timeout=0.01) assert command.status == command.status.RUNNING await asyncio.sleep(0.02) assert command.status == command.status.TIMEDOUT
def test_command_process_reply_failed(): command = ArchonCommand("ping", 1) command.process_reply(b"?01") assert command.status == command.status.FAILED
def test_command_bad_command_id(command_id): with pytest.raises(ValueError): ArchonCommand("ping", command_id)
def parser(cmd: ArchonCommand): cmd._mark_done(ArchonCommandStatus.DONE) cmd.replies = [] return cmd
def send_command_internal(cmd_str: str, **kwargs): cmd = ArchonCommand(cmd_str, 0) (parser or default_parser)(cmd) return cmd