Skip to content

Automatic test#17802 #26

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c991fa9
Added map commands & unit test
Cynthia-Tsai Mar 24, 2025
83d33da
Added map commands & unit test
Cynthia-Tsai Mar 24, 2025
014d6ea
Merge branch 'master' into David.Liu/AutomaticTest#17802
MPIDavidLiu Mar 26, 2025
96afe41
Modify the rule of new API(LoaderCommandGroup&StatusCommandGroup)
MPIDavidLiu Mar 27, 2025
c10e0be
Modify TestLoaderCommandGroup.py
MPIDavidLiu Mar 28, 2025
8e8794c
Modify statuscommandgroup.py rule,UnitTest and add enumeration
MPIDavidLiu Mar 28, 2025
62e87fb
update the command follow the rule
Hoca-Chen Apr 1, 2025
87d90bf
Added map cmd & unit test
Cynthia-Tsai Apr 1, 2025
732b882
#18000 and #18087 Simplify AuxCommandGroup and QalibriaCommandFroup API
AdamLin0108 Apr 7, 2025
c6a09e7
Merge branch 'David.Liu/AutomaticTest#17802' of https://github.com/Se…
AdamLin0108 Apr 7, 2025
9dbf0d8
Jeff add chuck and project handling commands
MPIDavidLiu Apr 8, 2025
73430b6
Create 新文字文件.txt
MPIDavidLiu Apr 8, 2025
ba21af2
Delete 新文字文件.txt
MPIDavidLiu Apr 8, 2025
b927756
Test
MPIDavidLiu Apr 10, 2025
8b5b690
Test
MPIDavidLiu Apr 10, 2025
a7c832a
Jeff add chuck and project handling commands
MPIDavidLiu Apr 10, 2025
328ffff
add Cynthia vision API
MPIDavidLiu Apr 10, 2025
deecc1a
add Cynthia vision unit test
MPIDavidLiu Apr 10, 2025
e14609c
Merge branch 'David.Liu/AutomaticTest#17802' of https://github.com/Se…
MPIDavidLiu Apr 10, 2025
c94252c
add John's remote command.
MPIDavidLiu Apr 10, 2025
fb9c304
Update TestStatusCommandGroup.py
Johnwu1020 Apr 11, 2025
9a8294f
Merge branch 'David.Liu/AutomaticTest#17802' into AutomaticTest#17802
MPIDavidLiu Apr 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
304 changes: 182 additions & 122 deletions sentio_prober_control/Sentio/CommandGroups/AuxCommandGroup.py

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -88,7 +88,6 @@ def prealign(self, marker: OrientationMarker, angle: int) -> None:
self.comm.send(f"loader:prealign {marker.toSentioAbbr()}, {angle}")
Response.check_resp(self.comm.read_line())


def query_wafer_status(self, station : LoaderStation, slot : int) -> Tuple[LoaderStation, int, int, int, float] | None:

"""Query the status of a wafer in a loader station.
@@ -187,13 +186,11 @@ def start_prepare_station(self, station: LoaderStation, angle: float | None = No
return Response.check_resp(self.comm.read_line())


@deprecated("duplicate functionality; Use SentioProber.move_chuck_work_area!")
def switch_work_area(self, area: str):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is a duplication of the fiunctionality of move_chuck_work_area. Its name violates the rule that the python api names should match remote command names. Therefore it has been marked as deprecated.

Is there a reason to remove the deprecation marker?

self.comm.send("move_chuck_work_area {0}".format(area))
resp = Response.check_resp(self.comm.read_line())
return resp.message()


def transfer_wafer(
self,
src_station: LoaderStation,
52 changes: 35 additions & 17 deletions sentio_prober_control/Sentio/CommandGroups/QAlibriaCommandGroup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
from deprecated import deprecated
from sentio_prober_control.Sentio.Response import Response
from sentio_prober_control.Sentio.CommandGroups.CommandGroupBase import CommandGroupBase
from sentio_prober_control.Sentio.ProberBase import ProberException
from typing import List
from enum import Enum

class DriftType(Enum):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All enum declarations should be in the file Enumerations.py. THe implementation of all enums should be consistent throughout the code base. Please use numeric values for the enums in combination with a toSentioAbbr() function

DriftRef = "DriftRef"
Drift = "Drift"

class QAlibriaCommandGroup(CommandGroupBase):
"""
@@ -81,25 +88,27 @@ def set_calibration_drift_probe12(self):
# New / Additional Commands
# -------------------------------------------------------------------------

def get_calibration_status(self) -> str:
def check_calibration_status(self) -> None:
"""
Retrieve the status of QAlibria.
Checks the calibration status of QAlibria.

Wraps SENTIO's "qal:get_calibration_status" remote command.

Returns:
str: The status string of QAlibria (e.g., "OK"). If "OK" and
the system is in Remote mode, calibration is ready.
Raises:
ProberException: If the calibration status is not "OK".
"""
self.comm.send("qal:get_calibration_status")
resp = Response.check_resp(self.comm.read_line())
return resp.message()
status = resp.message().strip()
if status.upper() != "OK":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think this logic ever triggers because get_calibration status will return an error code if something is off. At least if the remote command specification is correct.

In general i would oppose parsing remote command response strings to determine wether an action failed or not because this will break if someone in the future decides that SENTIO will return something alse then "ok". Please rely on error codes.

raise ProberException(f"Calibration status error: {status}")



def measurement_execute(
self,
file_name: str,
ports: str = "1,2",
ports: List[int] = [1, 2],
correct_by_vna: bool = True,
enable_use_ratio: bool = False,
enable_switch_term: bool = False
@@ -111,14 +120,18 @@ def measurement_execute(

Args:
file_name: The path to the SNP file.
ports: The port(s) used for the measurement, e.g. "1,2".
ports: A list of port numbers used for the measurement (e.g. [1, 2]).
correct_by_vna: Whether to apply VNA correction (True/False).
enable_use_ratio: Whether to enable 'Use Ratio b/a' (True/False).
enable_switch_term: Whether to enable switch term (True/False).

Raises:
ProberException: If the remote command returns an error.
"""
ports_str = ",".join(str(port) for port in ports)
cmd = (
f"qal:measurement_execute "
f"{file_name},{ports},"
f"{file_name},{ports_str},"
f"{str(correct_by_vna).lower()},"
f"{str(enable_use_ratio).lower()},"
f"{str(enable_switch_term).lower()}"
@@ -135,18 +148,21 @@ def reset_ets(self) -> None:
self.comm.send("qal:reset_ets")
Response.check_resp(self.comm.read_line())


def set_ets(self, ports: str, path: str) -> None:
def set_ets(self, port: int, path: str, ets_mode: int = 0) -> None:
"""
Set error terms in the buffer.

Wraps SENTIO's "qal:set_ets" remote command.

Args:
ports: Port(s) of error terms (e.g. "12").
port: Port of error terms (e.g. 12).
path: Path to the error terms file in the buffer (e.g. "D:\\temp\\ets.txt").
ets_mode: An integer parameter as defined by the remote command spec (default is 0).

Raises:
ProberException: If the remote command returns an error.
"""
cmd = f"qal:set_ets {ports},{path}"
cmd = f"qal:set_ets {port},{path},{ets_mode}"
self.comm.send(cmd)
Response.check_resp(self.comm.read_line())

@@ -164,19 +180,21 @@ def send_ets_to_vna(self, cal_set_name: str) -> None:
self.comm.send(cmd)
Response.check_resp(self.comm.read_line())


def clear_dut_network(self, dut_name: str, drift_type: str, update_ui: bool) -> None:
def clear_dut_network(self, dut_name: str, drift_type: DriftType, update_ui: bool) -> None:
"""
Clear network data for a DUT.

Wraps SENTIO's "qal:clear_dut_network" remote command.

Args:
dut_name: The name of the DUT (e.g. "RefDUT").
drift_type: The type of drift data to clear ("DriftRef" or "Drift").
drift_type: The type of drift data to clear (DriftType.DriftRef or DriftType.Drift).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please specify the type as requested by google docstyle format: "drift_type (DriftType)" . The system we are using to create the documentation needs this information to create the proper links in the API documentation.

update_ui: Whether to update the UI (True/False).

Raises:
ProberException: If the remote command returns an error.
"""
cmd = (f"qal:clear_dut_network {dut_name},{drift_type},{str(update_ui).lower()}")
cmd = f"qal:clear_dut_network {dut_name},{drift_type.value},{str(update_ui).lower()}"
self.comm.send(cmd)
Response.check_resp(self.comm.read_line())

69 changes: 69 additions & 0 deletions sentio_prober_control/Sentio/CommandGroups/SetupCommandGroup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from typing import Tuple

from sentio_prober_control.Sentio.Enumerations import ThermoChuckState
from sentio_prober_control.Sentio.Response import Response
from sentio_prober_control.Sentio.CommandGroups.ModuleCommandGroupBase import (
ModuleCommandGroupBase,
)


class SetupCommandGroup(ModuleCommandGroupBase):
"""A command group for accessing setup module functions."""
def __init__(self, comm) -> None:
super().__init__(comm, "setup")

def get_contact_counter(self) -> int:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This command should not be here. Since the underlying remote command has a "contact_counter" subgroup the python api should also have such a command group.

We either change the remote command or we have to create a new command group.

"""Retrieves the contact counter value.

Returns:
An integer representing the number of times the chuck moved into contact height,
excluding moves on cleaning substrate.
"""
self.comm.send("setup:contact_counter:get")
resp = Response.check_resp(self.comm.read_line())
return int(resp.message())

def reset_contact_counter(self) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above; Python API should mirror remote command API; We need a command group for "contact_counter" or we need to change the underlying remote command.

"""Resets the contact counter."""
self.comm.send("setup:contact_counter:reset")
Response.check_resp(self.comm.read_line())

def remote_light_off_at_contact(self, status: bool) -> str:
"""Defines whether light is switched off at contact height in remote mode.

Args:
status (BooleanStatus): True/False, ON/OFF as defined in Enum.

Returns:
Response: Response object for result checking.
"""
self.comm.send(f"setup:remote:light_off_at_contact {status}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above; Python API should mirror remote command API; We need a command group for "remote" or we need to change the underlying remote command.

resp = Response.check_resp(self.comm.read_line())
return resp.message()

def remote_light_on_at_separation(self, status: bool) -> str:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above; Python API should mirror remote command API; We need a command group for "remote" or we need to change the underlying remote command.

"""Defines whether light is switched on at separation height in remote mode.

Args:
status (BooleanStatus): True/False, ON/OFF as defined in Enum.

Returns:
Response: Response object for result checking.
"""
self.comm.send(f"setup:remote:light_on_at_separation {status}")
resp = Response.check_resp(self.comm.read_line())
return resp.message()

def remote_scope_follow_off(self, status: bool) -> str:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above; Python API should mirror remote command API; We need a command group for "remote" or we need to change the underlying remote command.

"""Defines whether scope follow mode is switched off in remote mode.

Args:
status (BooleanStatus): True/False, ON/OFF as defined in Enum.
Note: ON disables scope follow.

Returns:
Response: Response object for result checking.
"""
self.comm.send(f"setup:remote:scope_follow_off {status}")
resp = Response.check_resp(self.comm.read_line())
return resp.message()
Original file line number Diff line number Diff line change
@@ -137,7 +137,7 @@ def move_origin(self, probe: ProbeSentio) -> None:
A Response object containing the command execution status.
"""
self.comm.send(f"siph:move_origin {probe.toSentioAbbr()}")
return Response.check_resp(self.comm.read_line())
Response.check_resp(self.comm.read_line())

def move_position_uvw(self, probe: ProbeSentio, axis: UvwAxis, degree: float) -> float:
"""Move the SiPH positioner target axis with a relative degree.
Loading