This assistant is used for test script generation
# ๐ง Assistant Rules: Semiconductor Test Script Generator
## โ๏ธ Instrumentation & Libraries
- Use **PyVISA** exclusively for instrument communication.
- Do not simulate/mock instruments unless asked.
- Request missing context: DUT config, instrument models, spec values.
## ๐งน Code Style
- Follow **PEP8**.
- Use clear names and parameterize values.
- Ensure Python 3.8+ compatibility.
## ๐ Documentation
- Script docstring: purpose, setup, usage
- Function docstrings: inputs, outputs, logic
- Comment non-obvious logic
## Constraints
- Try to provide modular functions based on the prompts attached as context.
- Do not provide any additional code other than the ones requested by the user.
No Docs configured
Create a function `initialize_instruments(context)` that uses **PyVISA** to initialize and configure lab instruments as defined in `context["instrument_config"]`.
---
### ๐ Function Behavior
- Use `pyvisa.ResourceManager()` to establish a VISA session. - Iterate through each instrument in `context["instrument_config"]`. Each config entry must contain:
- A unique instrument key (e.g., `"psu"`, `"dmm"`, `"eload"`)
- A VISA resource address (e.g., `"USB::0x1234::5678::INSTR"`)
- Optional init options such as `"baud_rate"`, `"timeout"`, `"termination"`, etc.
- Connect to each instrument and apply the initial configuration parameters if specified. - Store the open instrument handle in `context["instruments"]` using the same key. - Ensure graceful error handling:
- Raise a clear error if an instrument cannot be initialized.
- Optionally log or print status messages for each step.
- Do **not** include any measurement, stimulus, or sweeping logic. - Return the updated `context` with connected instrument handles.
---
### ๐ฆ Example `context["instrument_config"]`
```python {
"psu": {
"address": "USB0::0x1AB1::0x0E11::DP832::INSTR",
"timeout": 5000,
"termination": "\n"
},
"dmm": {
"address": "GPIB0::22::INSTR",
"timeout": 3000
}
} ```
### Example Output
```python context["instruments"] = {
"psu": <pyvisa.resources.Resource>,
"dmm": <pyvisa.resources.Resource>
} ```
### Example Implementation
```python import pyvisa
def initialize_instruments(context: dict) -> dict:
rm = pyvisa.ResourceManager()
instrument_handles = {}
for name, config in context.get("instrument_config", {}).items():
try:
instr = rm.open_resource(config["address"])
if "timeout" in config:
instr.timeout = config["timeout"]
if "termination" in config:
instr.write_termination = config["termination"]
instr.read_termination = config["termination"]
instrument_handles[name] = instr
except Exception as e:
raise RuntimeError(f"Failed to initialize {name}: {e}")
context["instruments"] = instrument_handles
return context
```
Create a function `execute_test(context)` to carry out a **single instance of a validation test** based on the test type defined in `context['test_config']['type']`. Use only the fixed/static test conditions provided in `context['test_config']` (e.g., `vin`, `iload`, etc.) โ do **not** implement sweeping logic.
Store the measured result in `context['raw_result']`.
---
### ๐ง Key Instructions
- Read the test type from `context['test_config']['type']`. - Fetch static input conditions like:
- Input voltage: `vin = context['test_config'].get('vin')`
- Load current: `iload = context['test_config'].get('iload')`
- Use instrument handles stored in `context['instruments']`, which may include:
- `"psu"`: Power Supply
- `"eload"`: Electronic Load
- `"dmm"`: Digital Multimeter
- General measurement steps (adjust depending on test type):
1. Set PSU voltage and enable output
2. Set electronic load current and enable input
3. Wait/stabilize (e.g., `time.sleep(0.5)`)
4. Use DMM or other instruments to measure relevant DUT output
5. Save all measurements and inputs to `context['raw_result']`
- Store results in the format:
```python
context['raw_result'] = {
"vin": <float>,
"iload": <float>,
"measured_output": <float>,
"timestamp": "<UTC ISO timestamp>"
}
```
Do not compare against spec limits or print results โ that belongs in a later log_results() step.
### Example context['test_config'] ```python
{
"type": "load_regulation",
"vin": 5.0,
"iload": 0.1,
"expected": {
"min": 4.8,
"typ": 5.0,
"max": 5.2
}
}
```
### Example Structure ```python
def execute_test(context: dict) -> dict:
import time
instruments = context["instruments"]
test_config = context["test_config"]
vin = test_config.get("vin")
iload = test_config.get("iload")
psu = instruments["psu"]
eload = instruments["eload"]
dmm = instruments["dmm"]
psu.write(f"VOLT {vin}")
psu.write("OUTP ON")
eload.write(f"CURR {iload}")
eload.write("INPUT ON")
time.sleep(0.5)
measured_output = float(dmm.query("MEAS:VOLT?"))
context["raw_result"] = {
"vin": vin,
"iload": iload,
"measured_output": measured_output,
"timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
}
return context
```
### Constraints - Only handle a single point of measurement โ no loops or parameter sweeps. - Make sure logic adapts based on test type, but avoids hardcoding values. - Modular structure should make it easy to add more test types later.
Create a function `log_results(context)` that logs test input conditions and measured outputs from `context['raw_result']` into a CSV file. This function should **not perform any pass/fail validation** โ it must simply persist the data. ---
### ๐ง Instructions
- The `context['raw_result']` will contain:
- **Input conditions** (e.g., `vin`, `iload`, `temp`, etc.)
- **Measured outputs** (e.g., `vout_measured`, `dropout_voltage`, etc.)
- Keys in `raw_result` are dynamic โ do not assume fixed field names.
- Add a `timestamp` field to each row using **UTC ISO 8601 format**, if not already present.
- Write this data as a row in a file named `results.csv` in the current working directory.
- If `results.csv` does not exist, create it and include a header row using `raw_result` keys.
- If it exists, append the row without rewriting headers.
- After writing, update the context with the absolute file path:
```python
context["log_result"] = {"file_path": "<absolute path>"}
```
### Example Template
```python
import csv
import os
import time
def log_results(context: dict) -> dict:
raw = context["raw_result"]
if "timestamp" not in raw:
raw["timestamp"] = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
filename = "results.csv"
file_exists = os.path.isfile(filename)
with open(filename, mode="a", newline="") as f:
writer = csv.DictWriter(f, fieldnames=raw.keys())
if not file_exists:
writer.writeheader()
writer.writerow(raw)
context["log_result"] = {"file_path": os.path.abspath(filename)}
return context
```
### Constraints - Do not hardcode test condition names. - Do not include any pass/fail logic. - Ensure compatibility with Python 3.8+. - Output must be a well-formed CSV with dynamic headers based on the keys in raw_result. - Keep the function idempotent and safe for repeated appends.
No Data configured
No MCP Servers configured