mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2025-12-18 21:41:16 +00:00
* Cleanup registry to be easy-understanding (#76) * delete deprecated mock devices * rename categories * combine chromatographic devices * rename rviz simulation nodes * organic virtual devices * parse vessel_id * run registry completion before merge --------- Co-authored-by: Xuwznln <18435084+Xuwznln@users.noreply.github.com> * fix: workstation handlers and vessel_id parsing * fix: working dir error when input config path feat: report publish topic when error * modify default discovery_interval to 15s * feat: add trace log level * feat: 添加ChinWe设备控制类,支持串口通信和电机控制功能 (#79) * fix: drop_tips not using auto resource select * fix: discard_tips error * fix: discard_tips * fix: prcxi_res * add: prcxi res fix: startup slow * feat: workstation example * fix pumps and liquid_handler handle * feat: 优化protocol node节点运行日志 * fix all protocol_compilers and remove deprecated devices * feat: 新增use_remote_resource参数 * fix and remove redundant info * bugfixes on organic protocols * fix filter protocol * fix protocol node * 临时兼容错误的driver写法 * fix: prcxi import error * use call_async in all service to avoid deadlock * fix: figure_resource * Update recipe.yaml * add workstation template and battery example * feat: add sk & ak * update workstation base * Create workstation_architecture.md * refactor: workstation_base 重构为仅含业务逻辑,通信和子设备管理交给 ProtocolNode * refactor: ProtocolNode→WorkstationNode * Add:msgs.action (#83) * update: Workstation dev 将版本号从 0.10.3 更新为 0.10.4 (#84) * Add:msgs.action * update: 将版本号从 0.10.3 更新为 0.10.4 * simplify resource system * uncompleted refactor * example for use WorkstationBase * feat: websocket * feat: websocket test * feat: workstation example * feat: action status * fix: station自己的方法注册错误 * fix: 还原protocol node处理方法 * fix: build * fix: missing job_id key * ws test version 1 * ws test version 2 * ws protocol * 增加物料关系上传日志 * 增加物料关系上传日志 * 修正物料关系上传 * 修复工站的tracker实例追踪失效问题 * 增加handle检测,增加material edge关系上传 * 修复event loop错误 * 修复edge上报错误 * 修复async错误 * 更新schema的title字段 * 主机节点信息等支持自动刷新 * 注册表编辑器 * 修复status密集发送时,消息出错 * 增加addr参数 * fix: addr param * fix: addr param * 取消labid 和 强制config输入 * Add action definitions for LiquidHandlerSetGroup and LiquidHandlerTransferGroup - Created LiquidHandlerSetGroup.action with fields for group name, wells, and volumes. - Created LiquidHandlerTransferGroup.action with fields for source and target group names and unit volume. - Both actions include response fields for return information and success status. * Add LiquidHandlerSetGroup and LiquidHandlerTransferGroup actions to CMakeLists * Add set_group and transfer_group methods to PRCXI9300Handler and update liquid_handler.yaml * result_info改为字典类型 * 新增uat的地址替换 * runze multiple pump support (cherry picked from commit49354fcf39) * remove runze multiple software obtainer (cherry picked from commit8bcc92a394) * support multiple backbone (cherry picked from commit4771ff2347) * Update runze pump format * Correct runze multiple backbone * Update runze_multiple_backbone * Correct runze pump multiple receive method. * Correct runze pump multiple receive method. * 对于PRCXI9320的transfer_group,一对多和多对多 * 移除MQTT,更新launch文档,提供注册表示例文件,更新到0.10.5 * fix import error * fix dupe upload registry * refactor ws client * add server timeout * Fix: run-column with correct vessel id (#86) * fix run_column * Update run_column_protocol.py (cherry picked from commite5aa4d940a) * resource_update use resource_add * 新增版位推荐功能 * 重新规定了版位推荐的入参 * update registry with nested obj * fix protocol node log_message, added create_resource return value * fix protocol node log_message, added create_resource return value * try fix add protocol * fix resource_add * 修复移液站错误的aspirate注册表 * Feature/xprbalance-zhida (#80) * feat(devices): add Zhida GC/MS pretreatment automation workstation * feat(devices): add mettler_toledo xpr balance * balance * 重新补全zhida注册表 * PRCXI9320 json * PRCXI9320 json * PRCXI9320 json * fix resource download * remove class for resource * bump version to 0.10.6 * 更新所有注册表 * 修复protocolnode的兼容性 * 修复protocolnode的兼容性 * Update install md * Add Defaultlayout * 更新物料接口 * fix dict to tree/nested-dict converter * coin_cell_station draft * refactor: rename "station_resource" to "deck" * add standardized BIOYOND resources: bottle_carrier, bottle * refactor and add BIOYOND resources tests * add BIOYOND deck assignment and pass all tests * fix: update resource with correct structure; remove deprecated liquid_handler set_group action * feat: 将新威电池测试系统驱动与配置文件并入 workstation_dev_YB2 (#92) * feat: 新威电池测试系统驱动与注册文件 * feat: bring neware driver & battery.json into workstation_dev_YB2 * add bioyond studio draft * bioyond station with communication init and resource sync * fix bioyond station and registry * fix: update resource with correct structure; remove deprecated liquid_handler set_group action * frontend_docs * create/update resources with POST/PUT for big amount/ small amount data * create/update resources with POST/PUT for big amount/ small amount data * refactor: add itemized_carrier instead of carrier consists of ResourceHolder * create warehouse by factory func * update bioyond launch json * add child_size for itemized_carrier * fix bioyond resource io * Workstation templates: Resources and its CRUD, and workstation tasks (#95) * coin_cell_station draft * refactor: rename "station_resource" to "deck" * add standardized BIOYOND resources: bottle_carrier, bottle * refactor and add BIOYOND resources tests * add BIOYOND deck assignment and pass all tests * fix: update resource with correct structure; remove deprecated liquid_handler set_group action * feat: 将新威电池测试系统驱动与配置文件并入 workstation_dev_YB2 (#92) * feat: 新威电池测试系统驱动与注册文件 * feat: bring neware driver & battery.json into workstation_dev_YB2 * add bioyond studio draft * bioyond station with communication init and resource sync * fix bioyond station and registry * create/update resources with POST/PUT for big amount/ small amount data * refactor: add itemized_carrier instead of carrier consists of ResourceHolder * create warehouse by factory func * update bioyond launch json * add child_size for itemized_carrier * fix bioyond resource io --------- Co-authored-by: h840473807 <47357934+h840473807@users.noreply.github.com> Co-authored-by: Xie Qiming <97236197+Andy6M@users.noreply.github.com> * 更新物料接口 * Workstation dev yb2 (#100) * Refactor and extend reaction station action messages * Refactor dispensing station tasks to enhance parameter clarity and add batch processing capabilities - Updated `create_90_10_vial_feeding_task` to include detailed parameters for 90%/10% vial feeding, improving clarity and usability. - Introduced `create_batch_90_10_vial_feeding_task` for batch processing of 90%/10% vial feeding tasks with JSON formatted input. - Added `create_batch_diamine_solution_task` for batch preparation of diamine solution, also utilizing JSON formatted input. - Refined `create_diamine_solution_task` to include additional parameters for better task configuration. - Enhanced schema descriptions and default values for improved user guidance. * 修复to_plr_resources * add update remove * 支持选择器注册表自动生成 支持转运物料 * 修复资源添加 * 修复transfer_resource_to_another生成 * 更新transfer_resource_to_another参数,支持spot入参 * 新增test_resource动作 * fix host_node error * fix host_node test_resource error * fix host_node test_resource error * 过滤本地动作 * 移动内部action以兼容host node * 修复同步任务报错不显示的bug * feat: 允许返回非本节点物料,后面可以通过decoration进行区分,就不进行warning了 * update todo * modify bioyond/plr converter, bioyond resource registry, and tests * pass the tests * update todo * add conda-pack-build.yml * add auto install script for conda-pack-build.yml (cherry picked from commit172599adcf) * update conda-pack-build.yml * update conda-pack-build.yml * update conda-pack-build.yml * update conda-pack-build.yml * update conda-pack-build.yml * Add version in __init__.py Update conda-pack-build.yml Add create_zip_archive.py * Update conda-pack-build.yml * Update conda-pack-build.yml (with mamba) * Update conda-pack-build.yml * Fix FileNotFoundError * Try fix 'charmap' codec can't encode characters in position 16-23: character maps to <undefined> * Fix unilabos msgs search error * Fix environment_check.py * Update recipe.yaml * Update registry. Update uuid loop figure method. Update install docs. * Fix nested conda pack * Fix one-key installation path error * Bump version to 0.10.7 * Workshop bj (#99) * Add LaiYu Liquid device integration and tests Introduce LaiYu Liquid device implementation, including backend, controllers, drivers, configuration, and resource files. Add hardware connection, tip pickup, and simplified test scripts, as well as experiment and registry configuration for LaiYu Liquid. Documentation and .gitignore for the device are also included. * feat(LaiYu_Liquid): 重构设备模块结构并添加硬件文档 refactor: 重新组织LaiYu_Liquid模块目录结构 docs: 添加SOPA移液器和步进电机控制指令文档 fix: 修正设备配置中的最大体积默认值 test: 新增工作台配置测试用例 chore: 删除过时的测试脚本和配置文件 * add * 重构: 将 LaiYu_Liquid.py 重命名为 laiyu_liquid_main.py 并更新所有导入引用 - 使用 git mv 将 LaiYu_Liquid.py 重命名为 laiyu_liquid_main.py - 更新所有相关文件中的导入引用 - 保持代码功能不变,仅改善命名一致性 - 测试确认所有导入正常工作 * 修复: 在 core/__init__.py 中添加 LaiYuLiquidBackend 导出 - 添加 LaiYuLiquidBackend 到导入列表 - 添加 LaiYuLiquidBackend 到 __all__ 导出列表 - 确保所有主要类都可以正确导入 * 修复大小写文件夹名字 * 电池装配工站二次开发教程(带目录)上传至dev (#94) * 电池装配工站二次开发教程 * Update intro.md * 物料教程 * 更新物料教程,json格式注释 * Update prcxi driver & fix transfer_liquid mix_times (#90) * Update prcxi driver & fix transfer_liquid mix_times * fix: correct mix_times type * Update liquid_handler registry * test: prcxi.py * Update registry from pr * fix ony-key script not exist * clean files --------- Co-authored-by: Junhan Chang <changjh@dp.tech> Co-authored-by: ZiWei <131428629+ZiWei09@users.noreply.github.com> Co-authored-by: Guangxin Zhang <guangxin.zhang.bio@gmail.com> Co-authored-by: Xie Qiming <97236197+Andy6M@users.noreply.github.com> Co-authored-by: h840473807 <47357934+h840473807@users.noreply.github.com> Co-authored-by: LccLink <1951855008@qq.com> Co-authored-by: lixinyu1011 <61094742+lixinyu1011@users.noreply.github.com> Co-authored-by: shiyubo0410 <shiyubo@dp.tech>
401 lines
15 KiB
Python
401 lines
15 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
智达GCMS设备驱动
|
||
|
||
支持智达GCMS设备的TCP通信协议,包括状态查询、方法获取、样品分析等功能。
|
||
通信协议版本:1.0.1
|
||
"""
|
||
|
||
import base64
|
||
import json
|
||
import socket
|
||
import time
|
||
import os
|
||
from pathlib import Path
|
||
|
||
|
||
class ZhidaClient:
|
||
def __init__(self, host='192.168.3.184', port=5792, timeout=10.0):
|
||
# 如果部署在智达GCMS上位机本地,可使用localhost: host='127.0.0.1'
|
||
"""
|
||
初始化智达GCMS客户端
|
||
|
||
Args:
|
||
host (str): 设备IP地址,本地部署时可使用'127.0.0.1'
|
||
port (int): 通信端口,默认5792
|
||
timeout (float): 超时时间,单位秒
|
||
"""
|
||
self.host = host
|
||
self.port = port
|
||
self.timeout = timeout
|
||
self.sock = None
|
||
self._ros_node = None # ROS节点引用,由框架设置
|
||
|
||
def post_init(self, ros_node):
|
||
"""
|
||
ROS节点初始化后的回调方法,用于建立设备连接
|
||
|
||
Args:
|
||
ros_node: ROS节点实例
|
||
"""
|
||
self._ros_node = ros_node
|
||
try:
|
||
self.connect()
|
||
ros_node.lab_logger().info(f"智达GCMS设备连接成功: {self.host}:{self.port}")
|
||
except Exception as e:
|
||
ros_node.lab_logger().error(f"智达GCMS设备连接失败: {e}")
|
||
# 不抛出异常,允许节点继续运行,后续可以重试连接
|
||
|
||
def connect(self):
|
||
"""
|
||
建立TCP连接到智达GCMS设备
|
||
|
||
Raises:
|
||
ConnectionError: 连接失败时抛出
|
||
"""
|
||
try:
|
||
self.sock = socket.create_connection((self.host, self.port), timeout=self.timeout)
|
||
# 确保后续 recv/send 都会在 timeout 秒后抛 socket.timeout
|
||
self.sock.settimeout(self.timeout)
|
||
except Exception as e:
|
||
raise ConnectionError(f"Failed to connect to {self.host}:{self.port} - {str(e)}")
|
||
|
||
def close(self):
|
||
"""
|
||
关闭与智达GCMS设备的TCP连接
|
||
"""
|
||
if self.sock:
|
||
try:
|
||
self.sock.close()
|
||
except Exception:
|
||
pass # 忽略关闭时的错误
|
||
finally:
|
||
self.sock = None
|
||
|
||
def _send_command(self, cmd: dict) -> dict:
|
||
"""
|
||
发送命令到智达GCMS设备并接收响应
|
||
|
||
Args:
|
||
cmd (dict): 要发送的命令字典
|
||
|
||
Returns:
|
||
dict: 设备响应的JSON数据
|
||
|
||
Raises:
|
||
ConnectionError: 连接错误
|
||
TimeoutError: 超时错误
|
||
"""
|
||
if not self.sock:
|
||
raise ConnectionError("Not connected to device")
|
||
|
||
try:
|
||
# 发送JSON命令(UTF-8编码)
|
||
payload = json.dumps(cmd, ensure_ascii=False).encode('utf-8')
|
||
self.sock.sendall(payload)
|
||
|
||
# 循环接收数据直到能成功解析完整JSON
|
||
buffer = bytearray()
|
||
start = time.time()
|
||
while True:
|
||
try:
|
||
chunk = self.sock.recv(4096)
|
||
if not chunk:
|
||
# 对端关闭连接,尝试解析已接收的数据
|
||
if buffer:
|
||
try:
|
||
text = buffer.decode('utf-8', errors='strict')
|
||
return json.loads(text)
|
||
except (UnicodeDecodeError, json.JSONDecodeError):
|
||
pass
|
||
break
|
||
buffer.extend(chunk)
|
||
|
||
# 尝试解码和解析JSON
|
||
text = buffer.decode('utf-8', errors='strict')
|
||
try:
|
||
return json.loads(text)
|
||
except json.JSONDecodeError:
|
||
# JSON不完整,继续接收
|
||
pass
|
||
|
||
except socket.timeout:
|
||
# 超时时,尝试解析已接收的数据
|
||
if buffer:
|
||
try:
|
||
text = buffer.decode('utf-8', errors='strict')
|
||
return json.loads(text)
|
||
except (UnicodeDecodeError, json.JSONDecodeError):
|
||
pass
|
||
raise TimeoutError(f"recv() timed out after {self.timeout:.1f}s")
|
||
|
||
# 防止死循环,总时长超过2倍超时时间就报错
|
||
if time.time() - start > self.timeout * 2:
|
||
# 最后尝试解析已接收的数据
|
||
if buffer:
|
||
try:
|
||
text = buffer.decode('utf-8', errors='strict')
|
||
return json.loads(text)
|
||
except (UnicodeDecodeError, json.JSONDecodeError):
|
||
pass
|
||
raise TimeoutError(f"No complete JSON received after {time.time() - start:.1f}s")
|
||
|
||
# 连接关闭,如果有数据则尝试解析
|
||
if buffer:
|
||
try:
|
||
text = buffer.decode('utf-8', errors='strict')
|
||
return json.loads(text)
|
||
except (UnicodeDecodeError, json.JSONDecodeError):
|
||
pass
|
||
|
||
raise ConnectionError("Connection closed before JSON could be parsed")
|
||
|
||
except Exception as e:
|
||
if isinstance(e, (ConnectionError, TimeoutError)):
|
||
raise
|
||
else:
|
||
raise ConnectionError(f"Command send failed: {str(e)}")
|
||
|
||
def get_status(self) -> str:
|
||
"""
|
||
获取设备状态
|
||
|
||
Returns:
|
||
str: 设备状态 (Idle|Offline|Error|Busy|RunSample|Unknown)
|
||
"""
|
||
if not self.sock:
|
||
# 尝试重新连接
|
||
try:
|
||
self.connect()
|
||
if self._ros_node:
|
||
self._ros_node.lab_logger().info("智达GCMS设备重新连接成功")
|
||
except Exception as e:
|
||
if self._ros_node:
|
||
self._ros_node.lab_logger().warning(f"智达GCMS设备连接失败: {e}")
|
||
return "Offline"
|
||
|
||
try:
|
||
response = self._send_command({"command": "getstatus"})
|
||
return response.get("result", "Unknown")
|
||
except Exception as e:
|
||
if self._ros_node:
|
||
self._ros_node.lab_logger().warning(f"获取设备状态失败: {e}")
|
||
return "Error"
|
||
|
||
def get_methods(self) -> dict:
|
||
"""
|
||
获取当前Project的方法列表
|
||
|
||
Returns:
|
||
dict: 包含方法列表的响应
|
||
"""
|
||
if not self.sock:
|
||
try:
|
||
self.connect()
|
||
if self._ros_node:
|
||
self._ros_node.lab_logger().info("智达GCMS设备重新连接成功")
|
||
except Exception as e:
|
||
if self._ros_node:
|
||
self._ros_node.lab_logger().warning(f"智达GCMS设备连接失败: {e}")
|
||
return {"error": "Device not connected"}
|
||
|
||
try:
|
||
return self._send_command({"command": "getmethods"})
|
||
except Exception as e:
|
||
if self._ros_node:
|
||
self._ros_node.lab_logger().warning(f"获取方法列表失败: {e}")
|
||
return {"error": str(e)}
|
||
|
||
|
||
|
||
def get_version(self) -> dict:
|
||
"""
|
||
获取接口版本和InLabPAL固件版本
|
||
|
||
Returns:
|
||
dict: 响应格式 {"result": "OK|Error", "message": "Interface:x.x.x;FW:x.x.x.xxx"}
|
||
"""
|
||
return self._send_command({"command": "version"})
|
||
|
||
def put_tray(self) -> dict:
|
||
"""
|
||
放盘操作,准备InLabPAL进样器
|
||
|
||
注意:此功能仅在特殊场景下使用,例如:
|
||
- 机械臂比较短,需要让开一个位置
|
||
- 盘支架是可移动的,需要进样器配合做动作
|
||
|
||
对于宜宾深势这套配置,空间足够,不需要这个额外的控制组件。
|
||
|
||
Returns:
|
||
dict: 响应格式 {"result": "OK|Error", "message": "ready_info|error_info"}
|
||
"""
|
||
return self._send_command({"command": "puttray"})
|
||
|
||
def start_with_csv_file(self, string: str = None, csv_file_path: str = None) -> dict:
|
||
"""
|
||
使用CSV文件启动分析(支持ROS2动作调用)
|
||
|
||
Args:
|
||
string (str): CSV文件路径(ROS2参数名)
|
||
csv_file_path (str): CSV文件路径(兼容旧接口)
|
||
|
||
Returns:
|
||
dict: ROS2动作结果格式 {"return_info": str, "success": bool}
|
||
|
||
Raises:
|
||
FileNotFoundError: CSV文件不存在
|
||
Exception: 文件读取或通信错误
|
||
"""
|
||
try:
|
||
# 支持两种参数传递方式:ROS2的string参数和直接的csv_file_path参数
|
||
file_path = string if string is not None else csv_file_path
|
||
if file_path is None:
|
||
error_msg = "未提供CSV文件路径参数"
|
||
if self._ros_node:
|
||
self._ros_node.lab_logger().error(error_msg)
|
||
return {"return_info": error_msg, "success": False}
|
||
|
||
# 使用Path对象进行更健壮的文件处理
|
||
csv_path = Path(file_path)
|
||
if not csv_path.exists():
|
||
error_msg = f"CSV文件不存在: {file_path}"
|
||
if self._ros_node:
|
||
self._ros_node.lab_logger().error(error_msg)
|
||
return {"return_info": error_msg, "success": False}
|
||
|
||
# 读取CSV文件内容(UTF-8编码,替换未知字符)
|
||
csv_content = csv_path.read_text(encoding="utf-8", errors="replace")
|
||
|
||
# 转换为Base64编码
|
||
b64_content = base64.b64encode(csv_content.encode('utf-8')).decode('ascii')
|
||
|
||
if self._ros_node:
|
||
self._ros_node.lab_logger().info(f"正在发送CSV文件到智达GCMS: {file_path}")
|
||
self._ros_node.lab_logger().info(f"Base64编码长度: {len(b64_content)} 字符")
|
||
|
||
# 发送start命令
|
||
response = self._send_command({
|
||
"command": "start",
|
||
"message": b64_content
|
||
})
|
||
|
||
# 转换为ROS2动作结果格式
|
||
if response.get("result") == "OK":
|
||
success_msg = f"智达GCMS分析启动成功: {response.get('message', 'Unknown')}"
|
||
if self._ros_node:
|
||
self._ros_node.lab_logger().info(success_msg)
|
||
return {"return_info": success_msg, "success": True}
|
||
else:
|
||
error_msg = f"智达GCMS分析启动失败: {response.get('message', 'Unknown error')}"
|
||
if self._ros_node:
|
||
self._ros_node.lab_logger().error(error_msg)
|
||
return {"return_info": error_msg, "success": False}
|
||
|
||
except Exception as e:
|
||
error_msg = f"CSV文件处理失败: {str(e)}"
|
||
if self._ros_node:
|
||
self._ros_node.lab_logger().error(error_msg)
|
||
return {"return_info": error_msg, "success": False}
|
||
|
||
def start(self, string: str = None, text: str = None) -> dict:
|
||
"""
|
||
使用Base64编码数据启动分析(支持ROS2动作调用)
|
||
|
||
Args:
|
||
string (str): Base64编码的CSV数据(ROS2参数名)
|
||
text (str): Base64编码的CSV数据(兼容旧接口)
|
||
|
||
Returns:
|
||
dict: ROS2动作结果格式 {"return_info": str, "success": bool}
|
||
"""
|
||
try:
|
||
# 支持两种参数传递方式:ROS2的string参数和原有的text参数
|
||
b64_content = string if string is not None else text
|
||
if b64_content is None:
|
||
error_msg = "未提供Base64编码数据参数"
|
||
if self._ros_node:
|
||
self._ros_node.lab_logger().error(error_msg)
|
||
return {"return_info": error_msg, "success": False}
|
||
|
||
if self._ros_node:
|
||
self._ros_node.lab_logger().info(f"正在发送Base64数据到智达GCMS")
|
||
self._ros_node.lab_logger().info(f"Base64编码长度: {len(b64_content)} 字符")
|
||
|
||
# 发送start命令
|
||
response = self._send_command({
|
||
"command": "start",
|
||
"message": b64_content
|
||
})
|
||
|
||
# 转换为ROS2动作结果格式
|
||
if response.get("result") == "OK":
|
||
success_msg = f"智达GCMS分析启动成功: {response.get('message', 'Unknown')}"
|
||
if self._ros_node:
|
||
self._ros_node.lab_logger().info(success_msg)
|
||
return {"return_info": success_msg, "success": True}
|
||
else:
|
||
error_msg = f"智达GCMS分析启动失败: {response.get('message', 'Unknown error')}"
|
||
if self._ros_node:
|
||
self._ros_node.lab_logger().error(error_msg)
|
||
return {"return_info": error_msg, "success": False}
|
||
|
||
except Exception as e:
|
||
error_msg = f"Base64数据处理失败: {str(e)}"
|
||
if self._ros_node:
|
||
self._ros_node.lab_logger().error(error_msg)
|
||
return {"return_info": error_msg, "success": False}
|
||
|
||
def abort(self) -> dict:
|
||
"""
|
||
停止当前运行的分析
|
||
|
||
Returns:
|
||
dict: 响应格式 {"result": "OK|Error", "message": "error_info"}
|
||
"""
|
||
return self._send_command({"command": "abort"})
|
||
|
||
|
||
def test_zhida_client():
|
||
"""
|
||
测试智达GCMS客户端功能
|
||
"""
|
||
client = ZhidaClient()
|
||
|
||
try:
|
||
# 连接设备
|
||
print("Connecting to Zhida GCMS...")
|
||
client.connect()
|
||
print("Connected successfully!")
|
||
|
||
# 获取设备状态
|
||
print(f"Device status: {client.status}")
|
||
|
||
# 获取版本信息
|
||
version_info = client.get_version()
|
||
print(f"Version info: {version_info}")
|
||
|
||
# 获取方法列表
|
||
methods = client.get_methods()
|
||
print(f"Available methods: {methods}")
|
||
|
||
# 测试CSV文件发送(如果文件存在)
|
||
csv_file = Path(__file__).parent / "zhida_gcms-test_1.csv"
|
||
if csv_file.exists():
|
||
print(f"Testing CSV file: {csv_file}")
|
||
result = client.start_with_csv_file(str(csv_file))
|
||
print(f"Start result: {result}")
|
||
|
||
except Exception as e:
|
||
print(f"Error: {str(e)}")
|
||
|
||
finally:
|
||
# 关闭连接
|
||
client.close()
|
||
print("Connection closed.")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
test_zhida_client()
|