Metadata-Version: 2.4
Name: insty
Version: 0.1.1
Summary: 基于VISA协议的统一仪器控制库
Author: Quincy
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/Quincy-Zh/insty
Project-URL: Repository, https://github.com/Quincy-Zh/insty
Project-URL: Bug Tracker, https://github.com/Quincy-Zh/insty/issues
Keywords: visa,instrument-control,scpi,automation,test-measurement
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pyvisa
Requires-Dist: typing-extensions>=4.0
Dynamic: license-file

# Insty

[![PyPI version](https://badge.fury.io/py/insty.svg)](https://badge.fury.io/py/insty)
[![Python Versions](https://img.shields.io/pypi/pyversions/insty.svg)](https://pypi.org/project/insty/)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![Downloads](https://static.pepy.tech/badge/insty)](https://pepy.tech/project/insty)

> Stop writing vendor-specific drivers. Just talk to your instruments.

**Insty** 是一个基于 VISA 协议的 Python 库，为测试自动化提供**统一的仪器访问接口**。通过将仪器抽象为类型角色（数字电源、万用表、示波器等），你只需几行 Python 代码就能控制不同厂商的仪器，无需记忆各厂商差异化的驱动 API。

## 特性

- 🎯 **角色化接口**：按仪器类型获取控制对象，语义清晰（`get_power_supply()`、`get_dmm()` 等）
- 🔌 **厂商无关**：屏蔽 Keysight、R&S、Keithley、Tektronix 等不同品牌的驱动差异
- 🚀 **惰性发现**：仪器按需连接，启动快速；支持全量扫描和手动刷新设备表
- 🔧 **可扩展**：支持自定义传输后端（默认使用 VISA）和注册新仪器驱动
- 🐍 **Pythonic**：API 设计符合 Python 习惯，简洁直观

## 安装

```bash
pip install insty
```

### 首次使用前的环境准备

`insty` 依赖 `pyvisa` 和一个可用的 VISA 后端。推荐按以下顺序选择：

1. **NI-VISA**（最稳定，推荐）：从 [NI 官网](https://www.ni.com/visa) 下载安装
2. **R&S VISA**：罗德与施瓦茨提供的 VISA 实现
3. **pyvisa-py**（纯 Python 实现，无需安装驱动）：
   ```bash
   pip install pyvisa-py
   ```

验证后端是否正常工作：

```python
import pyvisa
rm = pyvisa.ResourceManager()
print(rm.list_resources())  # 应列出所有可用的仪器地址
```

## 快速开始

### 角色化接口（推荐）

测试脚本通过 `TestBench` 按「角色」获取仪器实例：

```python
from insty import TestBench

mngr = TestBench(device_table=".device_table.json")

# 获取数字电源并设置电压
ps = mngr.get_power_supply(address="USB0::0x0957::0x2C07::MY12345678::0::INSTR")
ps.set_voltage(3.3)
print(f"实际输出电压: {ps.measure_voltage():.3f} V")  # 实际输出电压: 3.301 V

# 获取高低温箱并设定温度
thermal = mngr.get_thermal()
thermal.set_temperature(-40)
thermal.wait(timeout=300)  # 等待温度稳定
print("温度已稳定在 -40°C")

# 获取数字万用表读取电压
vm = mngr.get_dmm(address="USB0::0x0957::0x0B18::MY12345678::0::INSTR")
print(f"当前电压读数: {vm.read_voltage():.4f} V")  # 当前电压读数: 3.2962 V

# 获取示波器并触发单次采集
osc = mngr.get_oscilloscope()
osc.execute("single")
freq = osc.read_frequency()
print(f"信号频率: {freq:.2f} Hz")  # 信号频率: 1000.00 Hz

mngr.close()
```

**可用角色接口：**

- `get_power_supply()` — 数字电源
- `get_thermal()` — 高低温发生器
- `get_dmm()` — 数字万用表
- `get_waveform_generator()` — 信号发生器
- `get_oscilloscope()` — 示波器
- `get_frequency_counter()` — 频率计数器

不传 `address` 参数时，自动匹配唯一在线仪器；多台同类型仪器时会报错并提示使用 `address=` 指定。

仪器在首次调用 `get_*` 方法时惰性发现。设备连接变化后可随时调用 `mngr.scan()` 进行全量识别，重建设备表。

### 底层 API（InstrumentManager）

如果需要更细粒度的控制，可以直接使用 `InstrumentManager`：

```python
from insty import InstrumentManager

mgr = InstrumentManager(device_table=".device_table.json")

# 发现在线仪器（仅做存在性检查，不做 *IDN?）
infos = mgr.discover()
for info in infos:
    print(info.address, info.label, info.inst_type, info.supported)

# 打开特定仪器
inst = mgr.open(info.address, info.label)
inst.write("SYSTem:REMote")
data = inst.query("MEASure:VOLTage?")
print(f"读取数据: {data}")

inst.close()
mgr.close_all()
```

**关键方法：**
- `discover()` — 快速检查哪些地址在线
- `full_scan()` — 对每个地址执行 `*IDN?`，串口设备还会逐档波特率试探，全量识别仪器类型
- `register_backend()` — 注册更多传输后端（默认内置 `VisaTransportBackend`）

## 支持的仪器

`Insty` 通过统一的抽象接口支持多厂商仪器，目前已覆盖以下类型：

| 仪器类型 | 抽象基类 | 已适配仪器 |
| :--- | :--- | :--- |
| 数字电源 | `PowerSupplyBase` | ITECH::IT6302 |
| 数字万用表 | `DMMBase` | KEITHLEY::DMM6500 |
| 示波器 | `OscilloscopeBase` | ZHIYUAN::ZDS1000 |
| 高低温发生器 | `ThermalChamberBase` | TEMPTRONIC::ATS710 |
| 频率计数器 | `FrequencyCounterBase` | AGILENT::53220A |
| 信号发生器 | `WaveformGeneratorBase` | AGILENT::33519, AGILENT::33519, AGILENT::33512B |

> 只要仪器支持标准 SCPI 指令集，`Insty` 就能通过 `InstrumentRegistry` 快速适配。欢迎提交 PR 新增厂商驱动！

## 导出 API 一览

`Insty` 提供清晰的模块化导出：

**面向用户的高层接口：**
- `TestBench` — 面向测试脚本的角色化接口（推荐入口）

**核心管理器：**
- `InstrumentManager` — 仪器管理器（发现、连接、生命周期管理）
- `InstrumentRegistry` — 驱动注册表，通过以下方法显式注册：
  - `register_power_supply()`
  - `register_thermal_chamber()`
  - `register_waveform_generator()`
  - `register_dmm()`
  - `register_oscilloscope()`
  - `register_frequency_counter()`

**数据类型与枚举：**
- `InstrumentType` — 仪器类型枚举
- `InstrumentInfo` — 已发现仪器信息（`address` / `label` / `inst_type` / `supported`）

**抽象基类（自定义驱动时继承）：**
- `PowerSupplyBase`
- `ThermalChamberBase`
- `WaveformGeneratorBase`
- `DMMBase`
- `OscilloscopeBase`
- `FrequencyCounterBase`

**传输层：**
- `TransportBackend` — 传输后端抽象基类
- `VisaTransportBackend` — VISA 默认实现

**工具函数：**
- `frange(start, stop, step)` — 浮点等差数列（含端点）
- `make_instrument(name, resource)` — 驱动工厂方法

## 贡献

欢迎提交 Issue、Feature Request 或 Pull Request！

- **新增仪器驱动**：继承对应的 `*Base` 类并注册到 `InstrumentRegistry`
- **新增传输后端**：实现 `TransportBackend` 接口
- **报告问题**：请在 Issue 中附上完整的错误堆栈和仪器型号

详细指南请参考 [CONTRIBUTING.md](./CONTRIBUTING.md)。

## 感谢

最后感谢 deepseek 和 OpenCode，除了协助我写代码，还指导我把这份代码上传到 PyPi。

## License

Apache License 2.0，详见 [LICENSE](./LICENSE)。
