Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0f7366f
feat(bioyond): 添加计算实验设计功能,支持化合物配比和滴定比例参数
ZiWei09 Nov 20, 2025
6b0b28b
feat(bioyond): 添加测量小瓶功能,支持基本参数配置
ZiWei09 Nov 21, 2025
daf4187
feat(bioyond): 添加测量小瓶配置,支持新设备参数
ZiWei09 Nov 21, 2025
c16756d
feat(bioyond): 更新仓库布局和尺寸,支持竖向排列的测量小瓶和试剂存放堆栈
ZiWei09 Nov 21, 2025
efec1dd
Merge remote-tracking branch 'upstream/dev' into hrdev
ZiWei09 Nov 21, 2025
3d62e8b
feat(bioyond): 优化任务创建流程,确保无论成功与否都清理任务队列以避免重复累积
ZiWei09 Nov 23, 2025
32bd234
feat(bioyond): 添加设置反应器温度功能,支持温度范围和异常处理
ZiWei09 Nov 23, 2025
68eddbd
feat(bioyond): 调整反应器位置配置,统一坐标格式
ZiWei09 Nov 23, 2025
7250995
feat(bioyond): 添加调度器启动功能,支持任务队列执行并处理异常
ZiWei09 Nov 26, 2025
dbe129c
feat(bioyond): 优化调度器启动功能,添加异常处理并更新相关配置
ZiWei09 Nov 26, 2025
fb6ee79
feat(opcua): 增强节点ID解析兼容性和数据类型处理
ZiWei09 Nov 26, 2025
c0e7a69
feat(registry): 新增后处理站的设备配置文件
ZiWei09 Nov 26, 2025
6d8884a
Merge remote-tracking branch 'upstream/dev' into hrdev
ZiWei09 Nov 28, 2025
4a23b05
添加调度器启动功能,合并物料参数配置,优化物料参数处理逻辑
ZiWei09 Dec 1, 2025
8efbbbe
添加从 Bioyond 系统自动同步工作流序列的功能,并更新相关配置
ZiWei09 Dec 8, 2025
c68903e
Merge branch 'dev' into hrdev
ZiWei09 Dec 8, 2025
f03ff96
Merge branch 'dev' into hrdev
ZiWei09 Dec 8, 2025
2c69e66
fix:兼容 BioyondReactionStation 中 workflow_sequence 被重写为 property
ZiWei09 Dec 10, 2025
d7c970d
fix:同步工作流序列
ZiWei09 Dec 10, 2025
632f9b9
feat: remove commented workflow synchronization from `reaction_statio…
ZiWei09 Dec 10, 2025
de662a4
Merge branch 'dev' into hrdev
ZiWei09 Dec 16, 2025
9cac852
添加时间约束功能及相关配置
ZiWei09 Dec 16, 2025
440c996
fix:自动更新物料缓存功能,添加物料时更新缓存并在删除时移除缓存项
ZiWei09 Dec 18, 2025
74d0ea3
fix:在添加物料时处理字符串和字典返回值,确保正确更新缓存
ZiWei09 Dec 22, 2025
5ae89d8
fix:更新奔曜错误处理报送为物料变更报送,调整日志记录和响应消息
ZiWei09 Dec 23, 2025
1e5f6b0
feat:添加实验报告简化功能,去除冗余信息并保留关键信息
ZiWei09 Dec 24, 2025
beaa1d7
feat: 添加任务状态事件发布功能,监控并报告任务运行、超时、完成和错误状态
ZiWei09 Dec 25, 2025
d5e0d76
fix: 修复添加物料时数据格式错误
ZiWei09 Dec 25, 2025
d57e5ff
Refactor bioyond_dispensing_station and reaction_station_bioyond YAML…
ZiWei09 Dec 25, 2025
81b28ce
Merge branch 'dev' into pr/169
ZiWei09 Dec 25, 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
558 changes: 355 additions & 203 deletions unilabos/device_comms/opcua_client/client.py

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions unilabos/device_comms/opcua_client/node/uniopcua.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def __init__(self, client: Client, name: str, node_id: str, typ: NodeType, data_
self._type = typ
self._data_type = data_type
self._node: Optional[Node] = None

def _get_node(self) -> Node:
if self._node is None:
try:
Expand All @@ -66,7 +66,7 @@ def _get_node(self) -> Node:
# 直接以字符串形式处理
if isinstance(nid, str):
nid = nid.strip()

# 处理包含类名的格式,如 'StringNodeId(ns=4;s=...)' 或 'NumericNodeId(ns=2;i=...)'
# 提取括号内的内容
match_wrapped = re.match(r'(String|Numeric|Byte|Guid|TwoByteNode|FourByteNode)NodeId\((.*)\)', nid)
Expand Down Expand Up @@ -116,16 +116,16 @@ def _get_node(self) -> Node:
def read(self) -> Tuple[Any, bool]:
"""读取节点值,返回(值, 是否出错)"""
pass

@abstractmethod
def write(self, value: Any) -> bool:
"""写入节点值,返回是否出错"""
pass

@property
def type(self) -> NodeType:
return self._type

@property
def node_id(self) -> str:
return self._node_id
Expand Down Expand Up @@ -210,15 +210,15 @@ def __init__(self, client: Client, name: str, node_id: str, parent_node_id: str,
super().__init__(client, name, node_id, NodeType.METHOD, data_type)
self._parent_node_id = parent_node_id
self._parent_node = None

def _get_parent_node(self) -> Node:
if self._parent_node is None:
try:
# 处理父节点ID,使用与_get_node相同的解析逻辑
import re

nid = self._parent_node_id

# 如果已经是 NodeId 对象,直接使用
try:
from opcua.ua import NodeId as UaNodeId
Expand All @@ -227,16 +227,16 @@ def _get_parent_node(self) -> Node:
return self._parent_node
except Exception:
pass

# 字符串处理
if isinstance(nid, str):
nid = nid.strip()

# 处理包含类名的格式
match_wrapped = re.match(r'(String|Numeric|Byte|Guid|TwoByteNode|FourByteNode)NodeId\((.*)\)', nid)
if match_wrapped:
nid = match_wrapped.group(2).strip()

# 常见短格式
if re.match(r'^ns=\d+;[is]=', nid):
self._parent_node = self._client.get_node(nid)
Expand Down Expand Up @@ -271,7 +271,7 @@ def read(self) -> Tuple[Any, bool]:
def write(self, value: Any) -> bool:
"""方法节点不支持写入操作"""
return True

def call(self, *args) -> Tuple[Any, bool]:
"""调用方法,返回(返回值, 是否出错)"""
try:
Expand All @@ -285,20 +285,20 @@ def call(self, *args) -> Tuple[Any, bool]:
class Object(Base):
def __init__(self, client: Client, name: str, node_id: str):
super().__init__(client, name, node_id, NodeType.OBJECT, None)

def read(self) -> Tuple[Any, bool]:
"""对象节点不支持直接读取操作"""
return None, True

def write(self, value: Any) -> bool:
"""对象节点不支持直接写入操作"""
return True

def get_children(self) -> Tuple[List[Node], bool]:
"""获取子节点列表,返回(子节点列表, 是否出错)"""
try:
children = self._get_node().get_children()
return children, False
except Exception as e:
print(f"获取对象 {self._name} 的子节点失败: {e}")
return [], True
return [], True
29 changes: 27 additions & 2 deletions unilabos/devices/workstation/bioyond_studio/bioyond_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,24 @@ def add_material(self, params: dict) -> dict:
return {}

print(f"add material data: {response['data']}")
return response.get("data", {})

# 自动更新缓存
data = response.get("data", {})
if data:
if isinstance(data, str):
# 如果返回的是字符串,通常是ID
mat_id = data
name = params.get("name")
else:
# 如果返回的是字典,尝试获取name和id
name = data.get("name") or params.get("name")
mat_id = data.get("id")

if name and mat_id:
self.material_cache[name] = mat_id
print(f"已自动更新缓存: {name} -> {mat_id}")

return data

def query_matial_type_id(self, data) -> list:
"""查找物料typeid"""
Expand All @@ -203,7 +220,7 @@ def material_type_list(self) -> list:
params={
"apiKey": self.api_key,
"requestTime": self.get_current_time_iso8601(),
"data": {},
"data": 0,
})
if not response or response['code'] != 1:
return []
Expand Down Expand Up @@ -273,6 +290,14 @@ def delete_material(self, material_id: str) -> dict:

if not response or response['code'] != 1:
return {}

# 自动更新缓存 - 移除被删除的物料
for name, mid in list(self.material_cache.items()):
if mid == material_id:
del self.material_cache[name]
print(f"已从缓存移除物料: {name}")
break

return response.get("data", {})

def material_outbound(self, material_id: str, location_name: str, quantity: int) -> dict:
Expand Down
Loading
Loading